What is openapi-python-client

What is openapi-python-client#

The emgapi_v2_client sub-package is a Python client library for accessing version 2 of the MGnify API created using package openapi-python-client .


Expand for more info on how the client library was generated using openapi-python-client

mgnipy.emgapi_v2_client is a python library that was created from the openapi.json spec using openapi-python-client . An example of the command that was used:

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 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 sub-package in mgnipy.




Foreword#

The emgapi_v2_client is a sub-package within MGni.py. It serves as the initial HTTP client to remove the complexity of direct HTTP requests to version 2 of the MGnify API while maintaining type safety through attrs-based models.

Development#

This client library was automatically generated from the MGnify API v2 OpenAPI specification using openapi-python-client . This choice was made in the hopes that it would be easier for MGni.py to be updated with changes to the MGnify API endpoints and models.

Maintenance#

To update the client library ideally (hopefully) you can just run ./autogen_clients.sh



The rest of this readme was also initiated by openapi-python-client and provides instructions on how to use the generated client directly.

Usage#

First, create a client:

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:

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:

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:

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.

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.

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

    2. sync_detailed: Blocking request that always returns a Request, optionally with parsed set if the request was successful.

    3. asyncio: Like sync but async instead of blocking

    4. asyncio_detailed: Like sync_detailed but async instead of blocking

  2. All path/query params, and bodies become method arguments.

  3. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)

  4. 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):

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):

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"))