# emgapi-v2-client submodule

A client library for accessing version 2 of the MGnify API

<details>
<summary style=color:lightgreen>
Expand for more info on how the client library was generated using
<code style=color:lightgreen>openapi-python-client</code>
</summary>
<h1></h1>

`mgnipy.emgapi_v2_client` is a python library that was created from the [openapi.json spec](ttps://www.ebi.ac.uk/metagenomics/api/v2/openapi.json) using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client). An example of the command that was used:

```bash
openapi-python-client generate \
    --url https://www.ebi.ac.uk/metagenomics/api/v2/openapi.json \
    --output-path "mgnipy/emgapi-v2-client" \
    --config "config_v2.yaml" \
    --overwrite
```

Specifically [**_./autogen_clients.sh_**](https://github.com/EBI-Metagenomics/mgnipy/blob/main/autogen_clients.sh) was used to generate the python client library `emgapi_v2_client` using the command `openapi-python-client generate`

The genereated python client was moved into the mgnipy package and is treated as a submodule in mgnipy.

<h1></h1>
</details>
<br>
<br>

## Introduction

The `emgapi_v2_client` is a Python library that provides programmatic access to version 2 of the MGnify API. It serves as the core HTTP client within the MGni.py package, enabling seamless interaction with MGnify's comprehensive dataset of metagenomic analyses, samples, runs, assemblies, genomes, and more. It abstracts away the complexity of direct HTTP requests while maintaining type safety through `attrs`-based models.

### Purpose

This client library was automatically generated from the [MGnify API v2 OpenAPI specification](https://www.ebi.ac.uk/metagenomics/api/v2/openapi.json) using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client), ensuring that it stays synchronized with the latest API endpoints and models.

### Key Features

- **Type-safe API interactions**: All requests and responses are validated using `attrs` models
- **Flexible authentication**: Support for both public endpoints and authenticated requests via API tokens
- **Synchronous and asynchronous support**: Call endpoints using either blocking `sync` operations or async/await patterns
- **Detailed response information**: Access raw response data, status codes, and parsed models

The rest of this readme was also initiated by [openapi-python-client](https://github.com/openapi-generators/openapi-python-client) when using `generate` and provides instructions on how to use the generated client directly.

## Usage

First, create a client:

```python
from mgnipy.emgapi_v2_client import Client

client = Client(base_url="https://www.ebi.ac.uk")
```

If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead:

```python
from mgnipy.emgapi_v2_client import AuthenticatedClient

client = AuthenticatedClient(base_url="https://www.ebi.ac.uk", token="SuperSecretToken")
```

Now call your endpoint and use your models:

```python
from mgnipy.emgapi_v2_client.models import MyDataModel
from mgnipy.emgapi_v2_client.api.my_tag import get_my_data_model
from mgnipy.emgapi_v2_client.types import Response

with client as client:
    my_data: MyDataModel = get_my_data_model.sync(client=client)
    # or if you need more info (e.g. status_code)
    response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client)
```

Or do the same thing with an async version:

```python
from mgnipy.emgapi_v2_client.models import MyDataModel
from mgnipy.emgapi_v2_client.api.my_tag import get_my_data_model
from mgnipy.emgapi_v2_client.types import Response

async with client as client:
    my_data: MyDataModel = await get_my_data_model.asyncio(client=client)
    response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client)
```

By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle.

```python
client = AuthenticatedClient(
    base_url="https://internal_api.example.com",
    token="SuperSecretToken",
    verify_ssl="/path/to/certificate_bundle.pem",
)
```

You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
    base_url="https://internal_api.example.com",
    token="SuperSecretToken",
    verify_ssl=False
)
```

Things to know:

1. Every path/method combo becomes a Python module with four functions:
   1. `sync`: Blocking request that returns parsed data (if successful) or `None`
   1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.
   1. `asyncio`: Like `sync` but async instead of blocking
   1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking

1. All path/query params, and bodies become method arguments.
1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)
1. Any endpoint which did not have a tag will be in `mgnipy.emgapi_v2_client.api.default`

## Advanced customizations

There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):

```python
from mgnipy.emgapi_v2_client import Client

def log_request(request):
    print(f"Request event hook: {request.method} {request.url} - Waiting for response")

def log_response(response):
    request = response.request
    print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")

client = Client(
    base_url="https://api.example.com",
    httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
)

# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client()
```

You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url):

```python
import httpx
from mgnipy.emgapi_v2_client import Client

client = Client(
    base_url="https://api.example.com",
)
# Note that base_url needs to be re-set, as would any shared cookies, headers, etc.
client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030"))
```
