Delfini Core library¶
The pydelfini.delfini_core
module is a set of low-level
endpoints and data models that have been automatically generated from
Delfini’s OpenAPI spec. For every Delfini API endpoint, there is a
single API method in pydelfini.delfini_core.api
, and for every
request and response body, there is a corresponding data model defined
in pydelfini.delfini_core.models
.
Since this module is automatically generated, any missing or
insubstantial documentation should be addressed by adding the
appropriate fields to the main delfini-api.yaml
file. See the
Autogeneration section for more information.
Usage¶
First, create a client:
from pydelfini.delfini_core import Client
client = Client(base_url="https://delfini.bioteam.net/api/v1")
If the endpoints you’re going to hit require authentication, login
using the pydelfini.delfini_core.login.Login()
helper:
from pydelfini.delfini_core import Client
from pydelfini.delfini_core import Login
client = Login(
Client(base_url="https://delfini.bioteam.net/api/v1")
).with_password('myuser', 'mypassword')
Now call your endpoint and use your models:
from pydelfini.delfini_core.models import CollectionsGetCollectionsCollectionList as CollectionList
from pydelfini.delfini_core.api.collections import collections_get_collections
from pydelfini.delfini_core.types import Response
# the context manager is recommended in order to clean up any HTTP connection pool,
# see https://www.python-httpx.org/advanced/
with client as client:
coll_list: CollectionList = collections_get_collections.sync(client=client)
# or if you need more info (e.g. status_code)
response: Response[CollectionList] = collections_get_collections.sync_detailed(client=client)
Or do the same thing with an async version:
from pydelfini.delfini_core.models import CollectionsGetCollectionsCollectionList as CollectionList
from pydelfini.delfini_core.api.collections import collections_get_collections
from pydelfini.delfini_core.types import Response
async with client as client:
my_data: CollectionList = await collections_get_collections.asyncio(client=client)
response: Response[CollectionList] = await collections_get_collections.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://delfini.local/api/v1",
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://delfini.local/api/v1",
token="SuperSecretToken",
verify_ssl=False
)
Things to know¶
Every path/method combo becomes a Python module with four functions:
sync
: Blocking request that returns parsed data, if successful, or raises an exception otherwise.sync_detailed
: Blocking request that always returns aRequest
, optionally withparsed
set if the request was successful.asyncio
: Likesync
but async instead of blockingasyncio_detailed
: Likesync_detailed
but async instead of blocking
All path/query params, and bodies become method arguments.
If your endpoint had any tags on it, the first tag will be used as a module name for the function (“collections” in the above examples)
Any endpoint which did not have a tag will be in
pydelfini.delfini_core.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 pydelfini.delfini_core 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://delfini.bioteam.net/api/v1",
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 pydelfini.delfini_core import Client
client = Client(
base_url="https://delfini.bioteam.net/api/v1",
)
# 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://delfini.bioteam.net/api/v1", proxies="http://localhost:8030"
)
)
Autogeneration¶
The core client code can be regenerated by running autogenerate.sh
in the clients/pydelfini
directory. This is automatically run by
the pre-commit hook system any time that delfini-api.yaml
is
edited, so the client code should always remain in sync with the API
specification.
The autogenerate.sh
script contains several templates and
workarounds for various bugs and strange behavior in
openapi-python-client.
Documentation¶
All documentation can be found under the
pydelfini.delfini_core
API documentation section.
Contains methods for accessing the API |
|
Contains shared errors types that can be raised from API functions |
|
Contains functions to log in to a Delfini instance |
|
Contains all the data models used in inputs/outputs |
|
Contains a helper to assist with handling paginated responses |
|
Contains some shared types for properties |
Updating Documentation¶
Since the documentation is autogenerated from the code, and the code
is autogenerated from the original delfini-api.yaml
API spec, any
updates to the delfini_core
documentation should be
made in delfini-api.yaml
. The mapping between fields in the source
OpenAPI document and the outputs in the generated code are:
title:
is essentially a rename for a given schema or endpoint. For example, if a schema is defined with the keydictionary_search_options:
it will typically be autogenerated with the model title DictionarySearchOptions, but by providingtitle: Search Options for Dictionaries
the model title will now be SearchOptionsForDictionaries. This should be used sparingly as it makes it harder to map back from the generated code to the original API definition.summary:
is a short, one-line summary of a schema or endpoint.description:
is a longer, multi-line description of the function of a schema or endpoint.