Skip to main content

Python wrapper

The python wrapper is designed to simplify the process of interacting with the API in a python environment.

To view instructions and tips on how to get set up developing in python, see the Introduction to Python.

The wrapper is available on PyPi and can be installed:

>pip install hhdm-apiclient-wrapper

It can be imported in a python script like:

import hhdm_apiclient_wrapper as hh

Any examples will assume the wrapper has been imported like above.

Examples of usage are available on Github.

Each function in the wrapper maps to an endpoint on the API.

Instantiation and authentication

To make requests from the API, the wrapper must be authenticated. The API key can be passed to the wrapper when it is initialized. Initializing and authenticating the ApiClient can be done like so:

auth_settings = hh.AuthenticationSettings(api_key='API-KEY-HERE', authentication_mode=hh.AuthenticationMode.API_KEY)
client = hh.ApiClient(authentication_manager=hh.AuthenticationManager(auth_settings))

Concept

The general concept of the wrapper follows the same concept as the API, providing functions to get single items, lists of items, and create, update and delete items. One of the advantages of the wrapper is that it handles the multi-step process of uploading attached files.

All functions in the API wrapper have an account ID argument which is used in the AccountId header

ApiGetOptions

The class ApiGetOptions is used to specify what properties should be requested from the relevant entities.

It contains the following property:

  • parameters_to_include: List[str]: the list of properties, accepts * as a wildcard property, and nested properties can be accessed through dot notation. For example, Events.Cars.Car.*

ApiGetResult(Generic[T])

The class ApiGetResult(Generic[T]) is returned from all Add and Get functions. T is currently generally either a List[Dict] or Dict depending on the function.

The ApiGetResult(Generic[T]) class has the following properties:

  • success: bool: false if the request failed - in which case more information can be found in the message and status_code properties
  • message: str: if the request failed, provides more information on the reason for the failure
  • status_code: HTTPStatus: the status code of the request
  • return_value: T: if the request succeeded, the requested or created entity will be available in this property. If used in a Get function, this will be an entity or list of entities matching the criteria and parameters_to_include parameter. If used in an Add function, this contains the created entity and be populated as if parameters_to_include has a value of *.

Add functions

To add a new item using the wrapper use the add_{entity_name} functions. Some IDs will be required as arguments to express where the new item should be created. For example when creating a setup, the event_id and car_id will be required. A CreateModel instance is also required which has the properties explained in the creating items section of the API documentation.

For example:

add_setup_result = await client.add_setup(account_id, event_id, car_id, hh.CreateModel(true, false, None, []))

The add functions return a ApiGetResult[Dict].

Get functions

To get an item using the wrapper there are multiple options, as with the API. A single item can be retrieved by ID, or a list of items can be retrieved by passing in the appropriate parent IDs. For example when getting a list of setups, the event_id and car_id will be required. An ApiGetOptions instance is also required which contains the parameters_to_include information.

The get functions return a ApiGetResult[T]. The T will be either an item or a List of items depending on the function called.

For example:

get_setup_result = await client.get_setup_by_id(account_id, setup_id, hh.ApiGetOptions(["*"]))

This will return a ApiGetResult[Dict] containing all the properties on the setup with the ID specified by setup_id.

get_setups_result = await client.get_all_setups_for_event_car(account_id, event_id, car_id, hh.ApiGetOptions(["*"]))

This will return a ApiGetResult[List[Dict]].

Update functions

To update an item using the wrapper use the update_{entity_name} functions. The ID of the item to be updated will need to be provided as an argument. An UpdateModel instance is also required which contains the parameters_to_include information.

The update functions return a bool that indicates if the request was successful.

For example:

update_setup_result = await client.update_setup(account_id, setup_id, hh.UpdateModel(None, [
hh.ParameterUpdateModel("Param1", "NewValue")
]))

Delete functions

To delete an item using the wrapper use the delete_{entity_name} functions. The ID of the item to be deleted will need to be provided as an argument.

The delete functions return a bool that indicates if the request was successful.

For example:

delete_setup_result = await client.delete_setup(account_id, setup_id)

Attached Files

Adding attached files to an entity via the API is a process that takes several steps, each step requires building the headers and adding the ApiModels to the request body yourself:

  1. HTTP/POST https://hhdm-api.hh-dev.com/Championships/{championship_id}/Attachments
  2. Compress the file to add in LZ4 yourself.
  3. HTTP/PUT to the signed URL returned from Step 1 with the compressed file in the body of the request
  4. HTTP/PUT https://hhdm-api.hh-dev.com/Championships/{championship_id}/Attachments/{attached_file_id} updating the parameter ServerAttachedFileState to 2 (AvailableOnServer)

The API wrapper simplifies this process and the carefully created HTTP requests seen above can be replaced:

add_file_result = await client.add_attachment_to_championship(
account_id,
championship_id,
hh.ApiPrepareUploadModel(file_name, custom_property_attached_file_name, True, False, True),
file_path
))

It also supplies a function to retry adding the attachment if it fails the first time:

await client.retry_championship_attachment(add_file_result)