# Athena Client Library
This is a Python library for interacting with the Athena API (Resolver Unknown
CSAM Detection).
## Authentication
The Athena client supports two authentication methods:
### Static Token Authentication
```python
from resolver_athena_client.client.channel import create_channel
# Use a pre-existing authentication token
channel = create_channel(host="your-host", auth_token="your-token")
```
### OAuth Credential Helper (Recommended)
The credential helper automatically handles OAuth token acquisition and refresh:
```python
import asyncio
from resolver_athena_client.client.channel import CredentialHelper, create_channel_with_credentials
async def main():
# Create credential helper with OAuth settings
credential_helper = CredentialHelper(
client_id="your-oauth-client-id",
client_secret="your-oauth-client-secret",
auth_url="https://crispthinking.auth0.com/oauth/token", # Optional, this is default
audience="crisp-athena-live" # Optional, this is default
)
# Create channel with automatic OAuth handling
channel = await create_channel_with_credentials(
host="your-host",
credential_helper=credential_helper
)
asyncio.run(main())
```
#### Environment Variables
For the OAuth example to work, set these environment variables:
```bash
export OAUTH_CLIENT_ID="your-client-id"
export OAUTH_CLIENT_SECRET="your-client-secret"
export ATHENA_HOST="your-athena-host"
```
#### OAuth Features
- **Automatic token refresh**: Tokens are automatically refreshed when they expire
- **Thread-safe**: Multiple concurrent requests will safely share cached tokens
- **Error handling**: Comprehensive error handling for OAuth failures
- **Configurable**: Custom OAuth endpoints and audiences supported
See `examples/oauth_example.py` for a complete working example.
## Examples
- `examples/example.py` - Basic classification example with static token
- `examples/oauth_example.py` - OAuth authentication with credential helper
- `examples/create_image.py` - Image generation utilities
## TODO
### Async pipelines
Make pipeline style invocation of the async interators such that we can
async read file -> async transform -> async classify -> async results
### More async pipeline transformers
Add additional pipeline transformers for:
- Image format conversion
- Metadata extraction
- Error recovery and retry
## Development
This package uses [uv](https://docs.astral.sh/uv/) to manage its packages.
To install dependencies, run:
```bash
uv sync --dev
```
To build the package, run:
```bash
uv build
```
To run the standard tests, run:
```bash
pytest -m 'not functional'
```
Developers wishing to run the functional tests should see the
[Functional Tests](#functional-tests) section below.
To lint and format the code, run:
```bash
ruff check
ruff format
```
There are pre-commit hooks that will lint, format, and type check the code.
Install them with:
```bash
pre-commit install
```
To re-compile the protobuf files, run from the repository's root directory:
```bash
bash scripts/compile_proto.sh
```
### Functional Tests
Functional tests require an Athena environment to run against.
#### Pre-Requisites
You will need:
- An Athena host URL.
- An OAuth client ID and secret with access to the Athena environment.
- An affiliate with Athena enabled.
- `imagemagick` installed on your system and on your path at `magick`.
#### Preparing your environment
You can set up the environment variables in a `.env` file in the root of the
repository, or in your shell environment:
You must set the following variables:
```
ATHENA_HOST=your-athena-host (e.g. myathenahost.com)
ATHENA_TEST_AFFILIATE=your-affiliate-id
OAUTH_CLIENT_ID=your-oauth-client-id
OAUTH_CLIENT_SECRET=your-oauth-client-secret
ATHENA_TEST_PLATFORM_TOKEN=a standard platform token - this should be rejected
as only athena specific tokens are accepted.
ATHENA_TEST_EXPIRED_TOKEN=a valid but expired token - this should be rejected.
```
You can optionally set the following variables:
```
OAUTH_AUTH_URL=your-oauth-auth-url (default: https://crispthinking.auth0.com/oauth/token)
OAUTH_AUDIENCE=your-oauth-audience (default: crisp-athena-live)
TEST_IMAGE_COUNT=number-of-images-to-test-with (default: 5000) - this is the
number of images the _streaming_ test will use.
TEST_MIN_INTERVAL=minimum-interval-in-ms (default: None, send as fast as
possible) - this is the minimum interval between
images for the _streaming_ test.
ATHENA_NON_EXISTENT_AFFILIATE=non-existent-affiliate-id (default:
thisaffiliatedoesnotexist123) - this is used to test error handling.
ATHENA_NON_PERMITTED_AFFILIATE=non-permitted-affiliate-id (default:
thisaffiliatedoesnothaveathenaenabled) - this is used to test error handling.
```
Then run the functional tests with:
```bash
pytest -m functional
```
Raw data
{
"_id": null,
"home_page": null,
"name": "resolver-athena-client",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "csam, content-detection, image-classification, api-client, grpc",
"author": "Crisp Thinking Group Ltd",
"author_email": "Crisp Thinking Group Ltd <opensource@kroll.com>",
"download_url": "https://files.pythonhosted.org/packages/fc/a2/51eeeb64fe38f71eb29b2b1348bfc66f896a289d1b78cb59c76d2aac5078/resolver_athena_client-0.2.2.tar.gz",
"platform": null,
"description": "# Athena Client Library\n\nThis is a Python library for interacting with the Athena API (Resolver Unknown\nCSAM Detection).\n\n## Authentication\n\nThe Athena client supports two authentication methods:\n\n### Static Token Authentication\n```python\nfrom resolver_athena_client.client.channel import create_channel\n\n# Use a pre-existing authentication token\nchannel = create_channel(host=\"your-host\", auth_token=\"your-token\")\n```\n\n### OAuth Credential Helper (Recommended)\nThe credential helper automatically handles OAuth token acquisition and refresh:\n\n```python\nimport asyncio\nfrom resolver_athena_client.client.channel import CredentialHelper, create_channel_with_credentials\n\nasync def main():\n # Create credential helper with OAuth settings\n credential_helper = CredentialHelper(\n client_id=\"your-oauth-client-id\",\n client_secret=\"your-oauth-client-secret\",\n auth_url=\"https://crispthinking.auth0.com/oauth/token\", # Optional, this is default\n audience=\"crisp-athena-live\" # Optional, this is default\n )\n\n # Create channel with automatic OAuth handling\n channel = await create_channel_with_credentials(\n host=\"your-host\",\n credential_helper=credential_helper\n )\n\nasyncio.run(main())\n```\n\n#### Environment Variables\nFor the OAuth example to work, set these environment variables:\n```bash\nexport OAUTH_CLIENT_ID=\"your-client-id\"\nexport OAUTH_CLIENT_SECRET=\"your-client-secret\"\nexport ATHENA_HOST=\"your-athena-host\"\n```\n\n#### OAuth Features\n- **Automatic token refresh**: Tokens are automatically refreshed when they expire\n- **Thread-safe**: Multiple concurrent requests will safely share cached tokens\n- **Error handling**: Comprehensive error handling for OAuth failures\n- **Configurable**: Custom OAuth endpoints and audiences supported\n\nSee `examples/oauth_example.py` for a complete working example.\n\n## Examples\n\n- `examples/example.py` - Basic classification example with static token\n- `examples/oauth_example.py` - OAuth authentication with credential helper\n- `examples/create_image.py` - Image generation utilities\n\n## TODO\n\n### Async pipelines\nMake pipeline style invocation of the async interators such that we can\n\nasync read file -> async transform -> async classify -> async results\n\n### More async pipeline transformers\nAdd additional pipeline transformers for:\n- Image format conversion\n- Metadata extraction\n- Error recovery and retry\n\n\n\n## Development\nThis package uses [uv](https://docs.astral.sh/uv/) to manage its packages.\n\nTo install dependencies, run:\n\n```bash\nuv sync --dev\n```\n\nTo build the package, run:\n\n```bash\nuv build\n```\n\nTo run the standard tests, run:\n\n```bash\npytest -m 'not functional'\n```\n\nDevelopers wishing to run the functional tests should see the\n[Functional Tests](#functional-tests) section below.\n\n\nTo lint and format the code, run:\n\n```bash\nruff check\nruff format\n```\n\nThere are pre-commit hooks that will lint, format, and type check the code.\nInstall them with:\n\n```bash\npre-commit install\n```\n\nTo re-compile the protobuf files, run from the repository's root directory:\n\n```bash\nbash scripts/compile_proto.sh\n```\n\n### Functional Tests\nFunctional tests require an Athena environment to run against.\n\n#### Pre-Requisites\nYou will need:\n- An Athena host URL.\n- An OAuth client ID and secret with access to the Athena environment.\n- An affiliate with Athena enabled.\n- `imagemagick` installed on your system and on your path at `magick`.\n\n\n#### Preparing your environment\nYou can set up the environment variables in a `.env` file in the root of the\nrepository, or in your shell environment:\n\nYou must set the following variables:\n```\nATHENA_HOST=your-athena-host (e.g. myathenahost.com)\nATHENA_TEST_AFFILIATE=your-affiliate-id\nOAUTH_CLIENT_ID=your-oauth-client-id\nOAUTH_CLIENT_SECRET=your-oauth-client-secret\nATHENA_TEST_PLATFORM_TOKEN=a standard platform token - this should be rejected\nas only athena specific tokens are accepted.\nATHENA_TEST_EXPIRED_TOKEN=a valid but expired token - this should be rejected.\n```\n\nYou can optionally set the following variables:\n```\nOAUTH_AUTH_URL=your-oauth-auth-url (default: https://crispthinking.auth0.com/oauth/token)\nOAUTH_AUDIENCE=your-oauth-audience (default: crisp-athena-live)\nTEST_IMAGE_COUNT=number-of-images-to-test-with (default: 5000) - this is the\nnumber of images the _streaming_ test will use.\nTEST_MIN_INTERVAL=minimum-interval-in-ms (default: None, send as fast as\npossible) - this is the minimum interval between\nimages for the _streaming_ test.\nATHENA_NON_EXISTENT_AFFILIATE=non-existent-affiliate-id (default:\nthisaffiliatedoesnotexist123) - this is used to test error handling.\nATHENA_NON_PERMITTED_AFFILIATE=non-permitted-affiliate-id (default:\nthisaffiliatedoesnothaveathenaenabled) - this is used to test error handling.\n```\n\nThen run the functional tests with:\n\n```bash\npytest -m functional\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python client library for Athena API - CSAM detection and content classification",
"version": "0.2.2",
"project_urls": null,
"split_keywords": [
"csam",
" content-detection",
" image-classification",
" api-client",
" grpc"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "50ce29baf261cadba9208b1496de6392e82ac2f8d8b9d9f5eeeca3ed2847ad64",
"md5": "8b8709bf5accdc0c314f05dcf8472806",
"sha256": "a8b9a3b7267b722211d6ce1c59ce8d8f392f59b81c7987978169bd0e8c2d7a12"
},
"downloads": -1,
"filename": "resolver_athena_client-0.2.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8b8709bf5accdc0c314f05dcf8472806",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 38822,
"upload_time": "2025-10-09T10:10:28",
"upload_time_iso_8601": "2025-10-09T10:10:28.200938Z",
"url": "https://files.pythonhosted.org/packages/50/ce/29baf261cadba9208b1496de6392e82ac2f8d8b9d9f5eeeca3ed2847ad64/resolver_athena_client-0.2.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "fca251eeeb64fe38f71eb29b2b1348bfc66f896a289d1b78cb59c76d2aac5078",
"md5": "307deb0e061c3b5860ca66a231488118",
"sha256": "566e7dda063ba99d9de60d2da18089c2ddf30bf88293086125991ad031ea9dbc"
},
"downloads": -1,
"filename": "resolver_athena_client-0.2.2.tar.gz",
"has_sig": false,
"md5_digest": "307deb0e061c3b5860ca66a231488118",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 26194,
"upload_time": "2025-10-09T10:10:29",
"upload_time_iso_8601": "2025-10-09T10:10:29.529559Z",
"url": "https://files.pythonhosted.org/packages/fc/a2/51eeeb64fe38f71eb29b2b1348bfc66f896a289d1b78cb59c76d2aac5078/resolver_athena_client-0.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-09 10:10:29",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "resolver-athena-client"
}