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

# Send data from Python app to Axiom

> This page explains how to send data from a Python app to Axiom.

To send data from a Python app to Axiom, use the Axiom Python SDK.

<Note>
  The Axiom Python SDK is an open-source project and welcomes your contributions. For more information, see the [GitHub repository](https://github.com/axiomhq/axiom-py).
</Note>

## Prerequisites

* [Create an Axiom account](https://app.axiom.co/register).
* [Create a dataset in Axiom](/reference/datasets#create-dataset) where you send your data.
* [Create an API token in Axiom](/reference/tokens) with permissions to ingest data to the dataset you have created.

## Install SDK

<CodeGroup>
  ```shell Linux / MacOS theme={null}
  python3 -m pip install axiom-py
  ```

  ```shell Windows theme={null}
  py -m pip install axiom-py
  ```

  ```shell pip theme={null}
  pip3 install axiom-py
  ```
</CodeGroup>

If you use the [Axiom CLI](/reference/cli), run `eval $(axiom config export -f)` to configure your environment variables. Otherwise, [create an API token](/reference/tokens) and export it as `AXIOM_TOKEN`.

You can also configure the client using options passed to the client constructor:

```py theme={null}
import axiom_py

client = axiom_py.Client("API_TOKEN")
```

## Use client

```py theme={null}
import axiom_py
import rfc3339
from datetime import datetime,timedelta

client = axiom_py.Client()

client.ingest_events(
    dataset="DATASET_NAME",
    events=[
        {"foo": "bar"},
        {"bar": "baz"},
    ])
client.query(r"['DATASET_NAME'] | where foo == 'bar' | limit 100")
```

For more examples, see the [examples in GitHub](https://github.com/axiomhq/axiom-py/tree/main/examples/client_example.py).

## Configure region

By default, the client sends data to `api.axiom.co`. To target a specific edge region, pass the `edge` argument with the edge domain that matches the region your dataset lives in:

<CodeGroup>
  ```py EU Central 1 theme={null}
  import axiom_py

  client = axiom_py.Client(
      token="xaat-your-api-token",
      edge="eu-central-1.aws.edge.axiom.co",
  )
  ```

  ```py US East 1 theme={null}
  import axiom_py

  client = axiom_py.Client(
      token="xaat-your-api-token",
      edge="us-east-1.aws.edge.axiom.co",
  )
  ```
</CodeGroup>

The following edge domains are available:

| Edge deployment    | Base domain for ingest and query |
| ------------------ | -------------------------------- |
| US East 1 (AWS)    | `us-east-1.aws.edge.axiom.co`    |
| EU Central 1 (AWS) | `eu-central-1.aws.edge.axiom.co` |

For more information about edge deployments, see [Edge deployments](/reference/edge-deployments).

To point at a custom edge endpoint such as a proxy or load balancer, use `edge_url="https://your-edge-host"` instead. `edge_url` takes precedence over `edge` if both are set.

<Note>
  Edge endpoints require an API token (`xaat-`), not a personal token (`xapt-`). Passing a personal token with edge configuration raises an error.
</Note>

<Warning>
  Edge configuration must be passed explicitly when you create the client. Unlike `token` and `org_id`, the `edge` and `edge_url` arguments are not read from environment variables.
</Warning>

## Example with `AxiomHandler`

The example below uses `AxiomHandler` to send logs from the `logging` module to Axiom:

```python theme={null}
import axiom_py
from axiom_py.logging import AxiomHandler
import logging

def setup_logger():
    client = axiom_py.Client()
    handler = AxiomHandler(client, "DATASET_NAME")
    logging.getLogger().addHandler(handler)
```

For a full example, see [GitHub](https://github.com/axiomhq/axiom-py/tree/main/examples/logger_example.py).

## Example with `structlog`

The example below uses [structlog](https://github.com/hynek/structlog) to send logs to Axiom:

```python theme={null}
from axiom_py import Client
from axiom_py.structlog import AxiomProcessor

def setup_logger():
    client = Client()

    structlog.configure(
        processors=[
            # ...
            structlog.processors.add_log_level,
            structlog.processors.TimeStamper(fmt="iso", key="_time"),
            AxiomProcessor(client, "DATASET_NAME"),
            # ...
        ]
    )
```

For a full example, see [GitHub](https://github.com/axiomhq/axiom-py/tree/main/examples/structlog_example.py).
