The amount of underlying tokens a liquidity provider owns in a Uniswap v2 pool is proportional to the provider's share of the LP tokens.
For example, let's say the pool has 1000 USDC in its reserves, and the totalSupply
of the LP token is equal to 100. Then someone owning 1 LP token would have the rights to 10.0 USDC in the pool.
Example Python code, for the USDC/WETH pool:
from web3 import Web3
web3 = Web3(Web3.HTTPProvider(PROVIDER_URL))
pair = '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc'
contract = web3.eth.contract(address=pair, abi=v2_pool_abi)
reserves = contract.functions.getReserves().call()
reserve_usdc = reserves[0]
total_supply = contract.functions.totalSupply().call()
lp_address = '0x76E2E2D4d655b83545D4c50D9521F5bc63bC5329'
lp_balance = contract.functions.balanceOf(lp_address).call()
lp_usdc = reserve_usdc * lp_balance / total_supply
usdc_decimals = 6
lp_usdc_adjusted = lp_usdc / 10 ** usdc_decimals
print(f"liquidity provider {lp_address} has {lp_usdc_adjusted} USDC in USDC/WETH pool")