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 themessage
andstatus_code
propertiesmessage: str
: if the request failed, provides more information on the reason for the failurestatus_code: HTTPStatus
: the status code of the requestreturn_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 andparameters_to_include
parameter. If used in an Add function, this contains the created entity and be populated as ifparameters_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:
- HTTP/POST https://hhdm-api.hh-dev.com/Championships/{championship_id}/Attachments
- Compress the file to add in LZ4 yourself.
- HTTP/PUT to the signed URL returned from Step 1 with the compressed file in the body of the request
- HTTP/PUT https://hhdm-api.hh-dev.com/Championships/{championship_id}/Attachments/{attached_file_id} updating the parameter
ServerAttachedFileState
to2
(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)