API Client

APIClient is a class for handling requests to the Civis API. An instantiated APIClient contains a set of resources (listed in API Resources) where each resource is an object with methods. By convention, an instantiated APIClient object is named client and API requests are made with the following syntax:

client = civis.APIClient()
response = client.resource.method(params)

Dynamically Created Resources and Methods

The methods on APIClient are created dynamically at runtime by parsing an collections.OrderedDict representation of the Civis API specification. The methods are generated based on the path and HTTP method used with each endpoint. For example, GET /workflows/1 can be accessed with client.workflows.get(1). GET endpoints that don’t end in a parameter use a list method instead. Below are examples of endpoints and how they map to API Client methods:

Endpoint

API Client Method

GET /workflows

client.workflows.list()

GET /workflows/1

client.workflows.get(1)

GET /workflows/1/executions

client.workflows.list_executions(1)

PATCH /workflows/1

client.workflows.patch(1, ...)

POST /workflows/1/executions

client.workflows.post_executions(1)

GET /workflows/1/executions/2

client.workflows.get_executions(1, 2)

If your code editor has auto-completion functionality (as many heavy IDEs do), typing client. or client.workflows. should trigger the display of the available resources or methods, respectively. If you’re running Python interactively (e.g., the regular Python interactive shell, IPython, or a Jupyter notebook), Python’s built-in help function can be used to see lists of available endpoints for a resource (e.g., help(client.workflows)) or to get documentation for a specific endpoint function (e.g., help(client.workflows.list)). The ? operator in IPython (e.g., ?client.workflows) and the shift-tab hotkey in a Jupyter notebook also cause documentation to be displayed.

By default, the Civis API specification is downloaded from the /endpoints endpoint the first time an APIClient object is instantiated. To reduce overhead due to re-downloading the same API spec multiple times when multiple client instances are created, this API spec is cached in memory for a set amount of time. If you’re running Python interactively (e.g., the regular Python interactive shell, IPython, or a Jupyter notebook), the cached spec expires in 15 minutes, and if you’re running a script, the spec expires in 24 hours. When a cached spec expires and a new client instance is created, a new spec is downloaded from the Civis API (so that updates to the Civis API, if any, are available to the new client). If you want to force a new spec to be downloaded, you can pass force_refresh_api_spec=True to the APIClient constructor. Note that for a given APIClient object, the auto-generated resources and methods attached to it are never refreshed, even if the Civis API is updated during the lifetime of this object.

In some circumstances, it may be useful to use a local cache of the API specification rather than downloading the spec. This can be done by passing the specification to the client through the parameter local_api_spec as either the collections.OrderedDict or a filename where the specification has been saved.

api_key = os.environ['CIVIS_API_KEY']
spec = civis.resources.get_api_spec(api_key)

# From OrderedDict
client = civis.APIClient(local_api_spec=spec)

# From file
with open('local_api_spec.json', 'w') as f:
    json.dump(spec, f)
client = civis.APIClient(local_api_spec='local_api_spec.json')

Retries

The API client will automatically retry for certain API error responses.

If the error is one of [413, 429, 503] and the API client is told how long it needs to wait before it’s safe to retry (this is always the case with 429s, which are rate limit errors), then the client will wait the specified amount of time before retrying the request.

If the error is one of [429, 502, 503, 504] and the request is not a patch* or post* method, then the API client will retry the request several times, with an exponential delay, to see if it will succeed. If the request is of type post* it will retry with the same parameters for error codes [429, 503].

While the conditions under which retries are attempted are set as described above, the behavior of the retries is customizable by passing in a tenacity.Retrying instance to the retries kwarg of civis.APIClient.

Object Reference

class civis.APIClient(api_key: str | None = None, return_type: str = 'snake', api_version: str = '1.0', local_api_spec: collections.OrderedDict | str | None = None, force_refresh_api_spec: bool = False, retries: tenacity.Retrying | None = None)[source]

The Civis API client.

Parameters:
api_keystr, optional

Your API key obtained from the Civis Platform. If not given, the client will use the CIVIS_API_KEY environment variable.

return_typestr, optional

The following types are implemented:

  • 'raw' Returns the raw requests.Response object.

  • 'snake' Returns a civis.Response object for the json-encoded content of a response. This maps the top-level json keys to snake_case.

api_versionstring, optional

The version of endpoints to call. May instantiate multiple client objects with different versions. Currently only “1.0” is supported.

local_api_speccollections.OrderedDict or string, optional

The methods on this class are dynamically built from the Civis API specification, which can be retrieved from the /endpoints endpoint. When local_api_spec is None, the default, this specification is downloaded the first time APIClient is instantiated. Alternatively, a local cache of the specification may be passed as either an OrderedDict or a filename which points to a json file.

force_refresh_api_specbool, optional

Whether to force re-downloading the API spec, even if the cached version for the given API key hasn’t expired.

retriestenacity.Retrying, optional

Provide a tenacity.Retrying instance for retries. If None or not provided, the following default will be used:

tenacity.Retrying(
    wait=tenacity.wait_random_exponential(multiplier=2, max=60),
    stop=(tenacity.stop_after_delay(600) | tenacity.stop_after_attempt(10)),
    retry_error_callback=lambda retry_state: retry_state.outcome.result(),
)

If you’re providing a tenacity.Retrying instance, please note that you should leave the retry attribute unspecified, because the conditions under which retries apply are pre-determined – see Retries for details.

Attributes:
admin

An instance of the Admin endpoint

aliases

An instance of the Aliases endpoint

announcements

An instance of the Announcements endpoint

clusters

An instance of the Clusters endpoint

credentials

An instance of the Credentials endpoint

databases

An instance of the Databases endpoint

endpoints

An instance of the Endpoints endpoint

enhancements

An instance of the Enhancements endpoint

exports

An instance of the Exports endpoint

files

An instance of the Files endpoint

git_repos

An instance of the Git_Repos endpoint

groups

An instance of the Groups endpoint

imports

An instance of the Imports endpoint

jobs

An instance of the Jobs endpoint

json_values

An instance of the Json_Values endpoint

match_targets

An instance of the Match_Targets endpoint

media

An instance of the Media endpoint

models

An instance of the Models endpoint

notebooks

An instance of the Notebooks endpoint

notifications

An instance of the Notifications endpoint

ontology

An instance of the Ontology endpoint

permission_sets

An instance of the Permission_Sets endpoint

predictions

An instance of the Predictions endpoint

projects

An instance of the Projects endpoint

queries

An instance of the Queries endpoint

remote_hosts

An instance of the Remote_Hosts endpoint

reports

An instance of the Reports endpoint

roles

An instance of the Roles endpoint

scripts

An instance of the Scripts endpoint

search

An instance of the Search endpoint

services

An instance of the Services endpoint

storage_hosts

An instance of the Storage_Hosts endpoint

table_tags

An instance of the Table_Tags endpoint

tables

An instance of the Tables endpoint

templates

An instance of the Templates endpoint

usage

An instance of the Usage endpoint

usage_limits

An instance of the Usage_Limits endpoint

users

An instance of the Users endpoint

workflows

An instance of the Workflows endpoint

Methods

get_aws_credential_id(cred_name[, owner])

Find an AWS credential ID.

get_database_credential_id(username, ...)

Return the credential ID for a given username in a given database.

get_database_id(database)

Return the database ID for a given database name.

get_storage_host_id(storage_host)

Return the storage host ID for a given storage host name.

get_table_id(table, database)

Return the table ID for a given database and table name.

property default_credential

The current user’s default credential.

property default_database_credential_id

The current user’s default database credential ID.

get_aws_credential_id(cred_name, owner=None)[source]

Find an AWS credential ID.

Parameters:
cred_namestr or int

If an integer ID is given, this passes through directly. If a str is given, return the ID corresponding to the AWS credential with that name.

ownerstr, optional

Return the credential with this owner. If not provided, search for credentials under your username to disambiguate multiple credentials with the same name. Note that this function cannot return credentials which are not associated with an owner.

Returns:
aws_credential_idint

The ID number of the AWS credentials.

Raises:
ValueError

If the AWS credential can’t be found.

Examples

>>> import civis
>>> client = civis.APIClient()
>>> client.get_aws_credential_id('jsmith')
1234
>>> client.get_aws_credential_id(1111)
1111
>>> client.get_aws_credential_id('shared-cred',
...                              owner='research-group')
99
get_database_credential_id(username, database_name)[source]

Return the credential ID for a given username in a given database.

Parameters:
usernamestr or int

If an integer ID is given, this passes through directly. If a str is given, return the ID corresponding to the database credential with that username.

database_namestr or int

Return the ID of the database credential with username username for this database name or ID.

Returns:
database_credential_idint

The ID of the database credentials.

Raises:
ValueError

If the credential can’t be found.

Examples

>>> import civis
>>> client = civis.APIClient()
>>> client.get_database_credential_id('jsmith', 'redshift-general')
1234
>>> client.get_database_credential_id(1111, 'redshift-general')
1111
get_database_id(database)[source]

Return the database ID for a given database name.

Parameters:
databasestr or int

If an integer ID is given, passes through. If a str is given the database ID corresponding to that database name is returned.

Returns:
database_idint

The ID of the database.

Raises:
ValueError

If the database can’t be found.

get_storage_host_id(storage_host)[source]

Return the storage host ID for a given storage host name.

Parameters:
storage_hoststr or int

If an integer ID is given, passes through. If a str is given the storage host ID corresponding to that storage host is returned.

Returns:
storage_host_idint

The ID of the storage host.

Raises:
ValueError

If the storage host can’t be found.

Examples

>>> import civis
>>> client = civis.APIClient()
>>> client.get_storage_host_id('test host')
1234
>>> client.get_storage_host_id(1111)
1111
get_table_id(table, database)[source]

Return the table ID for a given database and table name.

Parameters:
tablestr

The name of the table in format schema.tablename. Either schema or tablename, or both, can be double-quoted to correctly parse special characters (such as ‘.’).

databasestr or int

The name or ID of the database.

Returns:
table_idint

The ID of the table.

Raises:
ValueError

If a table match can’t be found.

Examples

>>> import civis
>>> client = civis.APIClient()
>>> client.get_table_id('foo.bar', 'redshift-general')
123
>>> client.get_table_id('"schema.has.periods".bar', 'redshift-general')
456
property username

The current user’s username.