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

# About Validio SDK

> The Validio SDK provides functionality to interact with the Validio API using Python.

The Validio Software Development Kit (SDK) is a Python package that implements [Validio Code](https://docs.validio.io/v10.2/developer/validio-code.md), Validio's Infrastructure-as-Code (IaC) solution. It also comes with a GraphQL client for the Validio API, which uses the same default authentication methods and headers as the [Validio CLI](https://docs.validio.io/v10.2/developer/validio-cli.md). The [SDK Reference](https://docs.validio.io/v10.2/sdk-reference.md) documents all of the SDK's public modules, classes, and functions.

The client lets you send your queries or mutations as regular strings, and pass a Python dictionary as `variable_values`. For more information, see [Use the SDK client](#use-the-sdk-client). For worked examples, see the [SDK recipes](https://docs.validio.io/v10.2/developer/validio-sdk/sdk-recipes.md).

> [!WARNING]
>
> The GraphQL client is in beta, and breaking changes may happen.

## Install the Validio SDK

The Validio SDK is published as a Python package on PyPI as `validio-sdk`. You can use a Python package installer, such as `pip`, to install the SDK in your desired environment:

```bash title="Bash" theme={null}
pip install validio-sdk
```

The [Validio CLI](https://docs.validio.io/v10.2/developer/validio-cli.md) depends on the SDK, so installing `validio-cli` installs both.

## Authentication

You need an [API key](https://docs.validio.io/v10.2/docs/access-and-settings/settings/managing-api-keys.md), made up of an access key and an access secret, to interact with the Validio API. The client finds your credentials automatically, by looking for environment variables and then for a `config.json`. For the full lookup order, see [How the CLI and SDK find credentials](https://docs.validio.io/v10.2/developer/getting-started/authentication.md#how-the-cli-and-sdk-find-credentials). You can create the `config.json` with the Validio CLI by running `validio config init`.

To specify the credentials yourself, pass a [`ValidioConfig`](https://docs.validio.io/v10.2/sdk-reference/validio_sdk#validioconfig) when you create the client. You can also pass `headers`, a dictionary of additional headers to send with every request:

```python title="Python" theme={null}
from validio_sdk.client import Client
from validio_sdk.config import ValidioConfig


client_with_automatic_config = Client()
client_with_custom_config = Client(
    ValidioConfig(
        endpoint="https://my.validio.app.com",
        access_key=my_access_key,
        access_secret=my_access_secret,
        default_namespace="default",
    ),
    headers={
        "X-Custom-Header": "value",
    },
)
```

## Use the SDK client

For more examples of how to use the client, see the [SDK recipes](https://docs.validio.io/v10.2/developer/validio-sdk/sdk-recipes.md).

### Send a query

This example creates a client with explicit credentials, sends a `sourcesList` query with a variable that filters on a namespace, and prints the name of each source:

```python title="Python" theme={null}
import asyncio
import os

from validio_sdk.client import Client
from validio_sdk.config import ValidioConfig


async def main():
    client = Client(
        config=ValidioConfig(
            endpoint="https://validio.my-company.com",
            access_key=os.environ["VALIDIO_ACCESS_KEY"],
            access_secret=os.environ["VALIDIO_SECRET_ACCESS_KEY"],
        ),
        headers={
            "X-Custom-Header": "value",
        },
    )

    query = """
    query SourcesList($filter: ResourceFilter) {
      sourcesList(filter: $filter) {
        id
        name
        segmentations { id }
      }
    }
    """
    variables = {"filter": {"namespaceId": "default"}}

    sources = await client.execute(query, variable_values=variables)
    for source in sources["sourcesList"]:
        print(source["name"])


if __name__ == "__main__":
    asyncio.run(main())
```

The client returns the response data as a dictionary, keyed by each top-level field in the query, here `sourcesList`.

### Synchronous or asynchronous

The client is written to be used asynchronously, so it needs an asynchronous runtime. This allows safe concurrent use, and lets you run multiple operations at the same time when needed. To use the client in a non-asynchronous context, wrap the request in `asyncio.run`:

```python title="Python" theme={null}
import asyncio

from validio_sdk.client import Client


client = Client()
query = "..."

result = asyncio.run(client.execute(query))
```

This is not to be confused with how the server executes operations. When multiple queries are sent in the same request, the server always executes them concurrently, whereas mutations are always executed in sequence. For more information, see the [GraphQL documentation](https://graphql.org/learn/queries/#multiple-fields-in-mutations).

### Use the same client in different threads

To use the client across multiple threads at the same time, use a session. The session is opened before the first request and isn't closed until all requests are done. Open one with an `async with` block. The session it returns is a [`validio_sdk.client.Session`](https://docs.validio.io/v10.2/sdk-reference/validio_sdk.client#session), which has the same `execute` method as the client:

```python title="Python" theme={null}
import asyncio

from validio_sdk.client import Client


async def session_example():
    client = Client()

    async with client as session:
        await asyncio.gather(
            task1(session),
            task2(session),
            task3(session),
        )
```
