> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dune.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Execution & Results

In this quickstart, we will walk through how to fetch Dune data in Python.

<Note>
  ⌨️ For a quickstart on TypeScript, please [download Dune TypeScript SDK](https://github.com/bh2smith/ts-dune-client?tab=readme-ov-file) and [follow this demo project](https://github.com/bh2smith/demo-ts-dune-client).
</Note>

### Prerequisites

* Python environment set up (check out [uv](https://github.com/astral-sh/uv) if you want somewhere to start.)
* Have a Dune API key from the team/user who's queries you want to manage (to obtain one [follow the steps here](../overview/authentication#generate-an-api-key))

### Step 1: Prepare your Dune query

Have a Dune query you'd like to pull data from. Here, we'll use [this query](https://dune.com/queries/3373921/5660178) to get the DAI token balance for vitalik.eth.

### Step 2: Install Dune Python SDK

Ensure the [Dune Python SDK](https://pypi.org/project/dune-client/) is installed in your environment. You can install it using pip:

```
pip install dune-client
```

### Step 3: Get data from Dune query

#### Set up a Dune Python client

The API key might either be supplied in the constructor or read through environment variables.
The follow env variables might be supplied: `DUNE_API_KEY`, `DUNE_API_BASE_URL`, `DUNE_API_REQUEST_TIMEOUT`.

```python theme={null}
from dune_client.client import DuneClient

dune = DuneClient(
    api_key='<paste your api key here>',
    base_url="https://api.dune.com",
    request_timeout=300
)
```

#### Get query result

You can choose to either get the latest query result without triggering an execution or to trigger an execution and get the result to ensure freshest data.

<Tabs>
  <Tab title="Get latest result without execution">
    ```python theme={null}
      query_result = dune.get_latest_result(3373921) # get latest result in json format
      # query_result = dune.get_latest_result_dataframe(3373921) # get latest result in Pandas dataframe format
    ```
  </Tab>

  <Tab title="Query a query">
    ```python theme={null}
    query = QueryBase(
        query_id=3373921,

        # uncomment and change the parameter values if needed
        # params=[
        #     QueryParameter.text_type(name="contract", value="0x6B175474E89094C44Da98b954EedeAC495271d0F"), # default is DAI
        #     QueryParameter.text_type(name="owner", value="owner"), # default using vitalik.eth's wallet 
        # ],
    )

    query_result = dune.run_query_dataframe(
      query=query
      # , ping_frequency = 10 # uncomment to change the seconds between checking execution status, default is 1 second
      # , performance="large" # uncomment to run query on large engine, default is medium
      # , batch_size = 5_000 # uncomment to change the maximum number of rows to retrieve per batch of results, default is 32_000
    ) 

    # Note: to get the result in csv format, call run_query_csv(); for json format, call run_query().
    ```
  </Tab>
</Tabs>

<Note>
  * To paginate query results, please visit the [pagination page](../executions/pagination) to get more info.
  * If you are using the [Python SDK](https://github.com/duneanalytics/dune-client/tree/main):
    * For [higher level functions](https://github.com/duneanalytics/dune-client/blob/main/dune_client/api/extensions.py) like `run_query()`, pagination is handled for you automatically behind the scene, so you will get the entire dataset as the returned result. You can pass in parameter `batch_size` to define the maximum number of rows per batch or pagination call.
    * For [lower level functions](https://github.com/duneanalytics/dune-client/blob/main/dune_client/api/execution.py) like `get_execution_results()`, you can pass in pagination parameters `limit` and `offset` directly, as instructed [here](../executions/pagination#pagination-parameters).
</Note>

### Putting it all together

```python theme={null}
from dune_client.client import DuneClient
from dune_client.query import QueryBase

# setup Dune Python client
dune = DuneClient()

# get the latest executed result without triggering a new execution
query_result = dune.get_latest_result(3373921) # get latest result in json format


# query the query (execute and get latest result)
query = QueryBase(
    query_id=3373921,

    # uncomment and change the parameter values if needed
    # params=[
    #     QueryParameter.text_type(name="contract", value="0x6B175474E89094C44Da98b954EedeAC495271d0F"), # default is DAI
    #     QueryParameter.text_type(name="owner", value="owner"), # default using vitalik.eth's wallet 
    # ],
)

query_result = dune.run_query_dataframe(
  query=query
  # , ping_frequency = 10 # uncomment to change the seconds between checking execution status, default is 1 second
  # , performance="large" # uncomment to run query on large engine, default is medium
  # , batch_size = 5_000 # uncomment to change the maximum number of rows to retrieve per batch of results, default is 32_000
) 
```
