I have a code that fetch usd prices of some currencies contract writted in file using geckoterminal api, geckoterminal allow 30 addresses in one api call, but i found that geckotetminal dont confirm liquidity when giving prices, i want yo use defillama free coins prices api because defillama promise they check for true price and if they cant they will add new a 'confidence' value for how much they confirm the price...
Defillama api related doc:
GET
/prices/current/{coins}
Get current prices of tokens by contract address
The goal of this API is to price as many tokens as possible, including exotic ones that never get traded, which makes them impossible to price by looking at markets.

The base of our data are prices pulled from coingecko, which is then extended through multiple means:

We price all bridged tokens by using the price of the token in it's original chain, so we fetch all bridged versions of USDC on arbitrum, fantom, avax... and price all them using the price for the token on Ethereum, which we know. Right now we support 10 different bridging protocols.

We have multiple adapters to price specialized sets of tokens by running custom code:

We price yearn's yToken LPs by checking how much underlying token can be withdrawn for each LP

Aave, compound and euler LP tokens are also priced based on their relationship against underlying tokens

Uniswap, curve, balancer and stargate LPs are priced using the underlying tokens in each pair

GMX's GLP token is priced based on the value of tokens given on withdrawal (which includes calculations based on trader's PnL)

Synthetix tokens are priced using forex prices of the coin they are pegged to

For tokens that we haven't been able to price in any other way, we find the pool with most liquidity for each on uniswap, curve and serum and then use the prices provided on those exchanges.

Unlike all the other tokens, we can't confirm that these prices are correct, so we only ingest the ones that have sufficient liquidity and, even in that case, we attach a confidence value to them that is related to the depth of liquidity and which represents our confidence in the quality of each price. API consumers can choose to filter out prices with low confidence values.

Our API server is fully open source and we are constantly adding more pricing adapters, extending the amount of tokens we support.

Tokens are queried using {chain}:{address}, where chain is an identifier such as ethereum, bsc, polygon, avax... You can also get tokens by coingecko id by setting coingecko as the chain, eg: coingecko:ethereum, coingecko:bitcoin. Examples:

ethereum:0xdF574c24545E5FfEcb9a659c229253D4111d87e1
bsc:0x762539b45a1dcce3d36d080f74d1aed37844b878
coingecko:ethereum
arbitrum:0x4277f8f2c384827b5273592ff7cebd9f2c1ac258
Parameters
Name Description
coins * string (path)
set of comma-separated tokens defined as {chain}:{address}

Example: ethereum:0xdF574c24545E5FfEcb9a659c229253D4111d87e1,coingecko:ethereum,bsc:0x762539b45a1dcce3d36d080f74d1aed37844b878,ethereum:0xdB25f211AB05b1c97D595516F45794528a807ad8

Response example:
200
successful operation

Media type

application/json
Controls Accept header.
Example Value
Schema
{
  "coins": {
    "ethereum:0xdF574c24545E5FfEcb9a659c229253D4111d87e1": {
      "decimals": 8,
      "price": 0.022053735051098835,
      "symbol": "cDAI",
      "timestamp": 0.99
    }
  }
}
Update this code to use defillama instead of geckoterminal with rate limit 60 calls / minute with 30 addresses in same chain(network) per call:
import pandas as pd
import requests
from datetime import datetime
import time

# Load the CSV file containing contracts
file_path = '/content/nd-quotes-20240930-045322.csv'
df = pd.read_csv(file_path)

# Create a base URL for the Geckoterminal API
base_url = "https://api.geckoterminal.com/api/v2"

# Initialize a list to collect results
results = []

# Function to fetch token prices
def fetch_token_prices(network, addresses):
    endpoint = f"/simple/networks/{network}/token_price/{addresses}"
    url = f"{base_url}{endpoint}"

    response = requests.get(url)

    if response.status_code == 200:
        return response.json()
    else:
        print(f"Error fetching data for {network}: {response.status_code}")
        return None

# Splitting the contracts into groups by network
contract_groups = df.groupby('network')

for network, group in contract_groups:
    contracts = group['contract'].tolist()

    # Call the API in chunks of 30 contracts
    for i in range(0, len(contracts), 30):
        chunk = contracts[i:i+30]
        addresses = ','.join(chunk)

        # Fetch prices
        data = fetch_token_prices(network, addresses)

        if data and 'data' in data:
            token_prices = data['data']['attributes']['token_prices']
            for contract in chunk:
                price = token_prices.get(contract.lower())  # Use lower() for case-insensitivity
                # Validate price data
                if price and isinstance(price, (int, float)):
                    price = str(price)  # Convert int/float to string for consistency
                if price:  # Skip empty or None prices
                    currency = df.loc[(df['network'] == network) & (df['contract'] == contract), 'currency']
                    results.append({
                        'network': network,
                        'currency': currency.iloc[0],
                        'contract': contract,
                        'price': price
                    })

        # Respect the rate limit
        time.sleep(2)  # 2 seconds delay to ensure staying under 30 calls/stored results

# Create a DataFrame from the results
results_df = pd.DataFrame(results)

# Filter out empty or invalid prices
results_df = results_df[results_df['price'].notnull()]

# Get the current date and time
now = datetime.now().strftime("%Y%m%d-%H%M%S")

# Save the results to a new CSV file if there are valid prices
if not results_df.empty:
    output_file = f'quotes-{now}.csv'
    results_df.to_csv(output_file, index=False)
    print(f'Quotes data has been saved to {output_file}')
else:
    print('No valid quotes to save. Empty or