Connect
Python Package

hdforce

A Python package for accessing the Hawkin API. Authentication management, pandas DataFrames, and simple one-liner data access.

Version
2.0.0
Platform
Python ≥ 3.10
License
MIT

Installation

Install hdforce from PyPI using pip.

# Install hdforce from PyPI pip install hdforce

Authentication

hdforce authenticates with a Refresh Token you generate in the Hawkin web app, then store via environment variables, a .env file, the OS keychain, or pass directly at runtime.

1

Generate Your Refresh Token

In the Hawkin web app, open Settings → Integrations (cloud.hawkindynamics.com/integrations) and generate a Refresh Token. This is admin-only and long-lived. Then store it as the HD_REFRESH_TOKEN environment variable, in a .env file, in your OS keychain, or pass it directly.

2

Authenticate

Run AuthManager(region="Americas") to exchange your refresh token for an access token. The method is chosen via the authMethod parameter.

3

Start Querying

All Get*() functions use the active authentication automatically. Call GetTests() to start pulling data.

Quick Start

A complete, runnable script to get your first data.

from hdforce import AuthManager, GetAthletes, GetTeams, GetGroups, GetTypes, GetTests # 1. Authenticate AuthManager(region="Americas") # 2. Get organizational data roster = GetAthletes() teams = GetTeams() groups = GetGroups() types = GetTypes() # 3. Get test data tests = GetTests(from_=1690859091, to_=1711392994) print(f"Count: {tests.attrs['Count']}") print(tests.head())

Regional Endpoints

Set the region parameter in AuthManager() to match your organization's data residency.

Region Value Base URL
Americas "Americas" cloud.hawkindynamics.com
Europe "Europe" eu.cloud.hawkindynamics.com
Asia-Pacific "Asia/Pacific" apac.cloud.hawkindynamics.com
Use the exact region string. Valid values are "Americas", "Europe", and "Asia/Pacific". An unrecognized value (e.g. "APAC" or "US") is not matched and routes to an internal development endpoint rather than your production region.
Tutorials & Guides

User Guide

In-depth tutorials covering environment setup, data retrieval, example workflows, and integrating hdforce into web applications.

Environment Setup

Before using hdforce, you can configure logging and authentication to suit your development workflow.

Event Logging

hdforce supports event logging for detailed function process output and debugging. Use LoggerConfig.Configuration() to customize the logging behavior at the start of your script or session.

from hdforce import LoggerConfig # Configure a log file for thorough debugging LoggerConfig.Configuration(file=True, level="debug")

Configuration options:

Option Description
file Stream logs to stdout (default) or create a log file
level Minimum log level to output (default: "warning")
file_path Custom file path (default: "root/hdforce.log")
file_mode Append to log file or overwrite each session

Authentication with AuthManager

Use the AuthManager() function to authenticate with the Hawkin API. It supports four authentication methods to fit different environments.

Get your Refresh Token first

Every method needs a Refresh Token. Generate one in the Hawkin web app under Settings → Integrations (cloud.hawkindynamics.com/integrations) — only an organization administrator can create API tokens. The Refresh Token is long-lived; AuthManager() exchanges it for a short-lived Access Token automatically on each session.

Which method should you use?

Method Use when Token stored
"env" Local development; token already in your system environment System environment variable
"file" Project-scoped config you want visible and editable .env file
"manual" Token supplied at runtime and must never be persisted Not stored
"keyring" Secure, reusable storage across sessions and projects OS keychain

Method 1: Environment Variables (default)

Store your refresh token as a system environment variable named HD_REFRESH_TOKEN. This is the simplest approach for local development.

from hdforce import AuthManager # Uses HD_REFRESH_TOKEN from system environment AuthManager(authMethod="env", region="Americas")

Method 2: Environment File

Store variables in a .env file for more visible and dynamic interaction with auth variables.

# .env file template HD_REFRESH_TOKEN=your_api_token # Replace with your Refresh Token REGION=your_region # Replace with your URL region ACCESS_TOKEN= # Access token will be stored here TOKEN_EXPIRATION= # Token expiration will be stored here CLOUD_URL= # Your region's URL here
from hdforce import AuthManager # Authenticate using .env file AuthManager(authMethod="file", env_file_name=".env", region="Americas")

Method 3: Manual Token

Pass the refresh token directly. Useful for password-protected applications where the token is provided at runtime and should not be stored.

from hdforce import AuthManager # Pass token directly (not stored) AuthManager(authMethod="manual", region="Americas", refreshToken="your_refresh_token")

Method 4: OS Keychain

Store the refresh token securely in the operating system credential store (macOS Keychain, Windows Credential Manager, Linux Secret Service) via the keyring package — mirroring the hawkinR client. Store it once, then reconnect in later sessions without re-supplying the token.

from hdforce import AuthManager # First time: store the token in the OS keychain AuthManager(authMethod="keyring", region="Americas", refreshToken="your_refresh_token") # Later sessions: read it back from the keychain (no token needed) AuthManager(authMethod="keyring", region="Americas")

Multiple orgs or profiles. Pass a distinct refreshToken_name to store separate tokens side by side, then select one by name when you reconnect:

# Store a second profile under its own name AuthManager(authMethod="keyring", refreshToken_name="HD_TEAM_B", refreshToken="team_b_refresh_token", region="Europe") # Reconnect to that profile later by name AuthManager(authMethod="keyring", refreshToken_name="HD_TEAM_B", region="Europe")
Note: tokens are stored under keychain service "hdforce", keyed by refreshToken_name (default HD_REFRESH_TOKEN) — so each name is a separate stored profile. Requires the keyring package (installed with hdforce); if no OS keychain backend is available it raises an error — see the keyring docs for backend setup.

Creating Environment Variables

For local development, storing your refresh token as a system environment variable keeps it secure and reusable across projects.

Windows

  1. Right-click the Start button and select System.
  2. Click Advanced system settings on the left sidebar.
  3. Click the Environment Variables... button.
  4. Under User variables, click New...
  5. Enter HD_REFRESH_TOKEN as the name and your token as the value. Click OK.

macOS

  1. Open Terminal (Applications → Utilities → Terminal).
  2. Edit your profile: open -e ~/.zshrc (or ~/.bash_profile for Bash).
  3. Add the line: export HD_REFRESH_TOKEN='your_api_key_here'
  4. Apply changes: source ~/.zshrc

Verify Your Environment Variable

import os print("Refresh Token:", os.getenv("HD_REFRESH_TOKEN"))

Getting Data

Once authenticated, hdforce provides functions to retrieve Hawkin-specific, organizational, and test data.

Hawkin-Specific Data

These functions return data about test types and metrics available in the Hawkin system. Useful for understanding what data is available and building efficient queries.

Function Purpose
GetTypes() Get test type names and IDs for all test types in the system
GetMetrics() Get all metrics per test type: canonical ID, name, metric ID, label, units, description

Organization Data

Every organization has unique entities with their own IDs. Retrieve these to use as filters when pulling test data.

Function Purpose
GetAthletes() Get all athletes. Set includeInactive=True to include inactive athletes
GetTeams() Get team names and IDs for all teams in the organization
GetGroups() Get group names and IDs for all groups in the organization
GetTags() Get tag names, IDs, and descriptions for tags in the organization

Test Data

The GetTests() function is the primary way to retrieve performance test data. Use the filtering parameters to efficiently query only the data you need.

Key Parameters

Parameter Description
from_ Start time as Unix timestamp. Best for bulk historical exports
to_ End time as Unix timestamp. Defaults to now if omitted
sync When True, returns updated and newly created tests based on sync time. Best for incremental database sync
includeInactive Default False. Set True to include inactive tests
athleteId Filter by a specific athlete ID
typeId Filter by test type ID
teamId Filter by team ID(s), max 10
groupId Filter by group ID(s), max 10
Important: Requests cannot combine athleteId, typeId, teamId, or groupId together. Any of these can be used with from_, to_, sync, and includeInactive.
Deprecation Notice: As of July 2024, GetTestsAth, GetTestsType, GetTestsTeam, and GetTestsGroup have been deprecated in favor of GetTests() with filter parameters. Use GetTests() for all new code.

Example Usage

Full workflow examples demonstrating common hdforce patterns.

Log Configuration

Run at the beginning of your script or session to set desired logging settings.

from hdforce import LoggerConfig # Configure a log file for thorough debugging LoggerConfig.Configuration(file=True, level="debug")

Authentication

Environment Variable Method

First use in a new environment, storing the refresh token and region.

from hdforce import AuthManager AuthManager( region="Americas", authMethod="env", refreshToken_name="HD_REFRESH_TOKEN", refreshToken="YourRefreshTokenHere" )

File Method

Using a .env file for variable storage. Create the file first, then authenticate.

from hdforce import AuthManager AuthManager( region="Europe", authMethod="file", refreshToken_name="HD_REFRESH_TOKEN", refreshToken="YourRefreshTokenHere", env_file_name=".env" )

Create Useful Variables

import hdforce as hd # Get test types and IDs types = hd.GetTypes() # Get all athletes (including inactive) players = hd.GetAthletes(includeInactive=True) # Get teams, groups, tags for filtering teams = hd.GetTeams() groups = hd.GetGroups() tags = hd.GetTags()

GetTests with Various Filters

from hdforce import GetTests # Set time points time1 = 1690859091 time2 = 1711392994 # Get all tests in system (not recommended for large orgs) allTests = GetTests() # Get tests from a specific time fromTests = GetTests(from_=time2) # Get tests up to a specific time toTests = GetTests(to_=time1) # Get tests between time points rangeTests = GetTests(from_=time1, to_=time2) # Sync tests since last sync (only new or updated) lastSync = allTests.attrs["Last Sync"] newTests = GetTests(from_=lastSync, sync=True)

Filter by Athlete

from hdforce import GetTests, GetAthletes players = GetAthletes() # Find athlete ID by name me = players.id[players["name"] == "Lauren Green"] myId = me.iloc[0] # Get all tests for that athlete myTests = GetTests(athleteId=myId)

GetForceTime

from hdforce import GetTests, GetForceTime # Get tests for an athlete myTests = GetTests(athleteId="athlete_id_here") # Get test trial ID of first test someTest = myTests.iloc[0] # Get force-time data ftData = GetForceTime(testId=someTest)

Integrating with Web Applications

hdforce works seamlessly with popular Python web frameworks. Below are complete integration examples for Streamlit, FastAPI, and Dash.

Streamlit

Build interactive dashboards quickly with Streamlit. Use st.secrets or environment variables for secure token storage.

import streamlit as st from hdforce import AuthManager, GetTests, GetAthletes # Authenticate using Streamlit secrets or env vars @st.cache_resource def init_hawkin(): AuthManager( authMethod="manual", region="Americas", refreshToken=st.secrets["HD_REFRESH_TOKEN"] ) return True init_hawkin() st.title("Hawkin Dashboard") athletes = GetAthletes() selected = st.selectbox("Athlete", athletes["name"]) athlete_id = athletes.loc[athletes["name"] == selected, "id"].iloc[0] tests = GetTests(athleteId=athlete_id, from_=1704067200) st.dataframe(tests)
Tip: On Streamlit Cloud, add your HD_REFRESH_TOKEN in the app settings under Secrets using TOML format: HD_REFRESH_TOKEN = "your_token_here". For local development, create a .streamlit/secrets.toml file.

FastAPI

Serve Hawkin data as REST endpoints. Authenticate on startup and let FastAPI handle requests.

from fastapi import FastAPI from hdforce import AuthManager, GetTests, GetAthletes app = FastAPI() # Connect on startup @app.on_event("startup") def startup(): AuthManager(authMethod="env", region="Americas") @app.get("/athletes") def athletes(): return GetAthletes().to_dict(orient="records") @app.get("/tests") def tests(days: int = 7): from datetime import datetime, timedelta from_ = int((datetime.now() - timedelta(days=days)).timestamp()) return GetTests(from_=from_).to_dict(orient="records")
Tip: Set the HD_REFRESH_TOKEN environment variable on your server or pass it via a .env file. For Docker deployments, use docker run -e HD_REFRESH_TOKEN=your_token.

Dash

Build data-driven dashboards with Plotly Dash. Authenticate once at module level and use callbacks for interactivity.

from dash import Dash, html, dcc, dash_table, callback, Input, Output from hdforce import AuthManager, GetTests AuthManager(authMethod="env", region="Americas") app = Dash(__name__) app.layout = html.Div([ html.H1("Hawkin Dashboard"), dcc.Input(id="days-input", type="number", value=7, placeholder="Days back"), html.Button("Refresh", id="refresh-btn"), dash_table.DataTable(id="tests-table") ]) @callback(Output("tests-table", "data"), Input("refresh-btn", "n_clicks"), Input("days-input", "value")) def update_table(n, days): from datetime import datetime, timedelta from_ = int((datetime.now() - timedelta(days=days or 7)).timestamp()) df = GetTests(from_=from_) return df.head(50).to_dict("records") if __name__ == "__main__": app.run(debug=True)
Tip: For Dash deployments, set HD_REFRESH_TOKEN as an environment variable on your hosting platform. For local development, use a .env file with the authMethod="file" option in AuthManager.
API Reference

Function Reference

Complete documentation for all public hdforce functions — signatures, parameters, return values, and examples.

Authentication
AuthManager(region, authMethod, refreshToken_name, refreshToken, env_file_name)

Manages authentication with the Hawkin API. Exchanges a refresh token for an access token and stores the session credentials for use by all other hdforce functions.

Parameters
Name Type Default Description
region str "Americas" API region: "Americas", "Europe", or "Asia/Pacific"
authMethod str "env" Authentication method: "env" (system environment), "file" (.env file), "manual" (direct token, not stored), or "keyring" (OS keychain via the keyring package)
refreshToken_name str "HD_REFRESH_TOKEN" Name of the environment variable holding the refresh token
refreshToken str None The refresh token value. Required when authMethod="manual". When provided with "env" method, sets the environment variable
env_file_name str None Path to the .env file. Required when authMethod="file"
Returns

Sets up the internal authentication state. All subsequent Get*() calls use the stored credentials automatically.

Example
from hdforce import AuthManager # Environment variable method (default) AuthManager(authMethod="env", region="Americas") # File method AuthManager(authMethod="file", env_file_name=".env", region="Americas") # Manual method AuthManager(authMethod="manual", region="Americas", refreshToken="your_token")
Configuration
LoggerConfig.Configuration(file, level, file_path, file_mode)

Configures the hdforce event logging system. Controls log output destination, verbosity level, file path, and file write mode.

Parameters
Name Type Default Description
file bool False If True, logs are written to a file instead of stdout
level str "warning" Minimum log level: "debug", "info", "warning", "error", "critical"
file_path str "hdforce.log" Path for the log file
file_mode str "a" "a" to append, "w" to overwrite each session
Example
from hdforce import LoggerConfig # Debug logging to stdout LoggerConfig.Configuration(level="debug") # Log to file with overwrite LoggerConfig.Configuration(file=True, file_path="app/hdforce.log", file_mode="w")
Data Retrieval
GetTests(from_, to_, sync, athleteId, typeId, teamId, groupId, includeInactive, includeEid)

Retrieves test data from the Hawkin API. The primary function for querying performance data. Replaces all previous GetTests* variations. Supports filtering by athlete, team, group, test type, and date range.

Parameters
Name Type Default Description
from_ int None Start time as Unix timestamp
to_ int None End time as Unix timestamp. Defaults to now
sync bool False If True, returns updated and newly created tests based on sync time
athleteId str None Filter by specific athlete ID
typeId str None Filter by test type ID
teamId str / list None Filter by team ID(s). Max 10
groupId str / list None Filter by group ID(s). Max 10
includeInactive bool False Include inactive (disabled) trials. Default False sends includeInactive=false so only active tests return
includeEid bool False Include the hardware equipment ID (eid) on each returned test record
Returns

A pandas DataFrame containing test trials and their metrics. Each row is a single test trial; large queries are auto-paginated (1,000 per page). The DataFrame includes attrs with metadata: Count, Last Sync, and Last Test Time.

Examples
from hdforce import GetTests # All tests df = GetTests() # Specific date range df = GetTests(from_=1690859091, to_=1711392994) # Filter by athlete df = GetTests(athleteId="abc123") # Sync mode for incremental updates df = GetTests(from_=lastSync, sync=True) # Access metadata print(df.attrs["Count"]) print(df.attrs["Last Sync"])
GetForceTime(testId)

Retrieves the raw force-time data for a specific test trial. Returns high-frequency data sampled at 1000 Hz including left, right, and combined force, velocity, displacement, and power.

Parameters
Name Type Default Description
testId str The unique identifier for the test trial
Returns

A pandas DataFrame with columns for time, left force, right force, combined force, velocity, displacement, and power at each millisecond interval.

Example
from hdforce import GetTests, GetForceTime # Get a test ID tests = GetTests(athleteId="athlete_id") test_id = tests.iloc[0]["id"] # Fetch force-time data ft = GetForceTime(testId=test_id) print(ft.head())
GetForceTimeBulk(test_ids, export, export_dir, format, file_naming, deidentify)

Retrieve raw force-time data for many tests at once. A wrapper over GetTests() and GetForceTime() that can optionally export each trial to a file.

Parameters
Name Type Default Description
test_ids list / DataFrame None A list of test IDs, or a DataFrame with an id column (e.g. GetTests() output). If None, calls GetTests(**kwargs) to find targets
export bool False If True, write each result to a file in export_dir
export_dir str None Directory for exported files. Required when export=True
format str "csv" "csv", "tsv", "json", or "parquet"
file_naming list[str] ["test_id"] Filename parts joined by "_": "test_id", "athlete_name", "athlete_id", "testType_name", "date"
deidentify bool False If True, replaces the athlete name with "De-identified"
Returns

If export=False, a list of DataFrames (one per test). If export=True, a list of file paths written (plus a metadata_manifest file in export_dir). Extra keyword args pass through to GetTests() when test_ids is None (e.g. from_, typeId).

Example
from hdforce import GetTests, GetForceTimeBulk # Pull a set of tests, then bulk-fetch their force-time data cmj = GetTests(typeId="CMJ", from_=1704067200) # Return a list of DataFrames... ft_list = GetForceTimeBulk(test_ids=cmj) # ...or export each trial to CSV GetForceTimeBulk(test_ids=cmj, export=True, export_dir="ft_out", format="csv")
GetCOP(testId)

Retrieve Center-of-Pressure (COP) time-series data for a test trial. COP data is exclusive to the Free Run test type — any other type returns a 404.

Parameters
Name Type Default Description
testId str The unique identifier for the test trial (must be a Free Run test)
Returns

A pandas DataFrame with columns time, copX, copY, leftCopX, leftCopY, rightCopX, rightCopY — millimeters relative to plate center; NaN for samples where no weight is on a given plate.

Example
from hdforce import GetTests, GetCOP fr = GetTests(typeId="Free Run", from_=1704067200) cop = GetCOP(testId=fr.iloc[0]["id"]) print(cop.head())
GetTypes()

Get the test type names and IDs for all test types in the Hawkin system.

Returns

A pandas DataFrame containing the test types with their canonical IDs and names.

Example
from hdforce import GetTypes types = GetTypes() print(types)
GetMetrics()

Get all metrics for each test type. Returns the canonical test type ID, test type name, metric ID, metric label, unit of measure, and description.

Returns

A pandas DataFrame with columns: canonicalTestTypeID, testTypeName, id, label, units, description.

Example
from hdforce import GetMetrics metrics = GetMetrics() print(metrics)
GetAthletes(includeInactive)

Get all athletes for an account. Inactive athletes are only included when includeInactive is set to True.

Parameters
Name Type Default Description
includeInactive bool False Include inactive athletes in the results
Returns

A pandas DataFrame with columns: id, name, active, teams, groups, and any external properties.

Example
from hdforce import GetAthletes # Active athletes only athletes = GetAthletes() # Include inactive all_athletes = GetAthletes(includeInactive=True)
Organization
GetTeams()

Get team names and IDs for all teams in the organization.

Returns

A pandas DataFrame with columns: id, name.

Example
from hdforce import GetTeams teams = GetTeams() print(teams)
GetGroups()

Get group names and IDs for all groups in the organization.

Returns

A pandas DataFrame with columns: id, name.

Example
from hdforce import GetGroups groups = GetGroups() print(groups)
GetTags()

Get tag names, IDs, and descriptions for all tags created by users in your organization.

Returns

A pandas DataFrame with columns: id, name, description.

Example
from hdforce import GetTags tags = GetTags() print(tags)
Athlete Management
CreateAthletes(athletes)

Create new athletes for an account. Accepts a list of NewAthlete objects. Bulk create up to 500 athletes at a time.

Parameters
Name Type Default Description
athletes list[NewAthlete] A list of NewAthlete objects. Each requires a name (str). Optional: active (bool), teams (list), groups (list), image (str), and any external properties
Returns

Prints confirmation with the count of created athletes. If any fail, returns details about the failures.

Example
from hdforce import CreateAthletes, NewAthlete # Create NewAthlete objects athlete1 = NewAthlete(name="John Doe") athlete2 = NewAthlete(name="Jane Smith", active=True) # Create athletes CreateAthletes(athletes=[athlete1, athlete2])
UpdateAthletes(athletes)

Update existing athletes. Accepts a list of Athlete objects. Bulk update up to 500 athletes at a time.

Parameters
Name Type Default Description
athletes list[Athlete] A list of Athlete objects. Each requires an id (str). Optional: name, active, teams, groups, image, and external properties
Warning: When updating external properties, any custom properties not included in the request will be removed from the athlete. Always include all external properties you want to keep.
Example
from hdforce import UpdateAthletes, Athlete # Create Athlete object with updated data updated = Athlete(id="athlete_uuid", name="John Doe Updated") # Update the athlete UpdateAthletes(athletes=[updated])
Deprecated
Deprecation Notice: The following functions have been deprecated as of July 2024. Use GetTests() with the appropriate filter parameters instead. These functions will be fully removed in a future release.
GetTestsAth(athleteId, from_, to_, sync, includeInactive) Deprecated

Get tests for a specific athlete. Deprecated — use GetTests(athleteId=...) instead.

Parameters
Name Type Default Description
athleteId str The athlete's unique ID
from_ int None Start time as Unix timestamp
to_ int None End time as Unix timestamp
sync bool False Use sync time instead of test time
includeInactive bool False Include inactive tests
Migration: Replace GetTestsAth(athleteId="abc") with GetTests(athleteId="abc"). The same applies to GetTestsType, GetTestsTeam, and GetTestsGroup — use GetTests() with the corresponding parameter.
Version History

Changelog

Release notes and version history for hdforce.

2026
v2.0.0
Added Updated

v2 — parity with hawkinR 2.0, COP + bulk force-time

  • New GetCOP() — Center-of-Pressure series for Free Run tests
  • New GetForceTimeBulk() — retrieve or export force-time data for many trials at once
  • GetTests() now uses cursor-based pagination (1,000 per page) and adds includeEid; access tokens refresh automatically
  • Brought to parity with the hawkinR 2.0 client
  • Requires Python 3.10+
2024
v1.1.0
Added Breaking

Athlete management and unified GetTests

  • Added CreateAthletes() and UpdateAthletes() functions for athlete management
  • Expanded GetTests() to accept all filter parameters: athleteId, typeId, teamId, groupId
  • Breaking: Deprecated GetTestsAth, GetTestsType, GetTestsTeam, GetTestsGroup in favor of unified GetTests()
2023
v1.0.01
Added

Initial production release

  • Full logging system with configurable output and levels
  • Complete authentication management with environment, file, and manual methods
  • Core data retrieval functions: GetTests, GetAthletes, GetTeams, GetGroups, GetTags
  • GetForceTime for raw force-time waveform data
  • GetTypes and GetMetrics for system metadata
v1.0.0rc0
Fixed

Release candidate — logging and bug fixes

  • Improved logging output formatting and consistency
  • Fixed authentication token refresh edge cases
  • Bug fixes for data frame column type handling
v0.0.0.1-beta
Added

Initial build

  • First beta release of hdforce
  • Basic API authentication and data retrieval
  • Pandas DataFrame output for all endpoints