Skip to main content

aceiot-models

Pydantic models and API client for the ACE IoT Aerodrome Platform

Installation

pip install aceiot-models

For upload progress support:

pip install aceiot-models[upload-progress]

Features

  • Pydantic Models: Type-safe data models for all ACE IoT entities
  • Dual API Clients: Both synchronous and asynchronous clients for the ACE IoT API
  • Async Support: Full async/await support with httpx for high-performance applications
  • Pagination Support: Efficient handling of large datasets (both sync and async)
  • Batch Processing: Process large operations in manageable chunks with concurrency control
  • Type Hints: Full type annotations for better IDE support
  • Error Handling: Robust error handling with detailed error information

Usage

Using the Synchronous API Client

from aceiot_models.api import APIClient, APIError

# Initialize the client
client = APIClient(
    base_url="https://flightdeck.aceiot.cloud/api",
    api_key="your-api-key"
)

# Or use environment variables:
# export ACEIOT_API_URL=https://flightdeck.aceiot.cloud/api
# export ACEIOT_API_KEY=your-api-key
client = APIClient()

# Get clients
clients = client.get_clients(page=1, per_page=20)

# Create a point
from aceiot_models import PointCreate

point = PointCreate(
    name="sensor/temperature/office",
    site_id=1,
    client_id=1,
    point_type="analog",
    collect_enabled=True
)
result = client.create_points([point.model_dump()])

Using the Asynchronous API Client

import asyncio
from aceiot_models.api import AsyncAPIClient, APIError

async def main():
    # Initialize the async client with context manager
    async with AsyncAPIClient(
        base_url="https://flightdeck.aceiot.cloud/api",
        api_key="your-api-key"
    ) as client:
        # Get clients asynchronously
        clients = await client.get_clients(page=1, per_page=20)

        # Make concurrent requests
        clients_task = client.get_clients()
        sites_task = client.get_sites()
        gateways_task = client.get_gateways()

        # Wait for all requests
        clients, sites, gateways = await asyncio.gather(
            clients_task, sites_task, gateways_task
        )

        print(f"Found {clients['total_items']} clients")
        print(f"Found {sites['total_items']} sites")
        print(f"Found {gateways['total_items']} gateways")

# Run the async function
asyncio.run(main())

Filtering Site Points

Both get_site_points() and get_site_configured_points() accept optional created_after, created_before, updated_after, and updated_before filters as ISO 8601 strings. All bounds are inclusive. Timestamps with timezone offsets are normalized to UTC by the API; timestamps without an offset are treated as UTC. The API rejects invalid timestamps and ranges where after is later than before.

points = client.get_site_points(
    "my-site",
    created_after="2026-01-01T00:00:00Z",
    created_before="2026-02-01T00:00:00Z",
)

# Filters also work with the pagination helpers.
from aceiot_models.api import PaginatedResults

configured_points = PaginatedResults(
    client.get_site_configured_points,
    site_name="my-site",
    updated_after="2026-01-01T00:00:00Z",
).all_items()

The asynchronous client accepts the same filters; await the endpoint methods or use AsyncPaginatedResults to fetch multiple pages.

Using Pagination

Synchronous Pagination:

from aceiot_models.api import PaginatedResults

# Paginate through all sites
paginator = PaginatedResults(client.get_sites, per_page=100)
for page_sites in paginator:
    for site in page_sites:
        print(f"Site: {site['name']}")

# Or get all items at once
all_sites = paginator.all_items()

Asynchronous Pagination:

from aceiot_models.api import AsyncPaginatedResults

# Async pagination through all sites
async def paginate_sites():
    paginator = AsyncPaginatedResults(client.get_sites, per_page=100)
    async for page_sites in paginator:
        for site in page_sites:
            print(f"Site: {site['name']}")

    # Or get all items at once
    all_sites = await paginator.all_items()

Batch Processing

Synchronous Batch Processing:

from aceiot_models.api import batch_process

# Process points in batches
points = [...]  # List of many points

def create_batch(batch):
    return client.create_points(batch)

results = batch_process(
    items=points,
    process_func=create_batch,
    batch_size=100,
    progress_callback=lambda current, total: print(f"{current}/{total}")
)

Asynchronous Batch Processing with Concurrency Control:

from aceiot_models.api import batch_process_async

# Process points in batches with concurrent requests
async def create_batch_async(batch):
    return await client.create_points(batch)

results = await batch_process_async(
    items=points,
    process_func=create_batch_async,
    batch_size=100,
    max_concurrent=5,  # Control concurrent requests
    progress_callback=lambda current, total: print(f"{current}/{total}")
)

Using the Models

from aceiot_models import Point, Sample, PointCreate

# Create a new point
point = PointCreate(
    name="sensor/temperature/office",
    site_id=1,
    client_id=1,
    point_type="analog",
    collect_enabled=True
)

Using the API Client

from aceiot_models.api import APIClient, APIError

# Initialize the client
client = APIClient(
    base_url="https://flightdeck.aceiot.cloud/api",
    api_key="your-api-key"
)

# Fetch sites
try:
    sites = client.get_sites(page=1, per_page=100)
    print(f"Found {sites['total_items']} sites")
except APIError as e:
    print(f"Error: {e}")

Pagination

from aceiot_models.api import PaginatedResults

# Iterate through all points page by page
paginator = PaginatedResults(client.get_points, per_page=500)
for page_points in paginator:
    print(f"Processing {len(page_points)} points...")
    # Process each page

# Or get all items at once
all_points = paginator.all_items()

Batch Processing

from aceiot_models.api import batch_process

# Process items in batches
def process_batch(items):
    return client.create_points(items)

results = batch_process(
    items=large_list_of_points,
    process_func=process_batch,
    batch_size=100,
    progress_callback=lambda current, total: print(f"{current}/{total}")
)

Configuration

The API client can be configured through environment variables:

  • ACEIOT_API_URL: Base URL for the API
  • ACEIOT_API_KEY: Your API key
  • ACEIOT_API_TIMEOUT: Request timeout in seconds (default: 30)

Examples

See the examples directory for complete usage examples:

Testing

Unit Tests

Run the unit tests:

pytest tests/ -v

Integration Tests

Integration tests verify the API client works with a real API endpoint. See tests/api/README_INTEGRATION.md for setup instructions.

# Set environment variables
export ACEIOT_API_URL="https://flightdeck.aceiot.cloud/api"
export ACEIOT_API_KEY="your-api-key"
export ACEIOT_INTEGRATION_TESTS="true"

# Run integration tests
pytest tests/api/test_integration.py -v

Development

This project uses uv for dependency management. To set up a development environment:

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone the repository
git clone https://github.com/yourusername/aceiot-models.git
cd aceiot-models

# Install dependencies
uv sync --all-extras

# Run tests
uv run pytest

# Run linting
uv run ruff check .
uv run ruff format .

# Run type checking
uv run pyrefly check aceiot_models/

License

MIT License

Metadata

Release files for aceiot-models 0.3.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aceiot-models 0.3.8
File Size Uploaded
aceiot_models-0.3.8.tar.gz 143.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aceiot-models 0.3.8
File Interpreter ABI Platform
aceiot_models-0.3.8-py3-none-any.whl Python 3 none any Details

Total release size: 221.0 kB

Release files / aceiot_models-0.3.8.tar.gz

Download URL aceiot_models-0.3.8.tar.gz
Size 143.4 kB
Tags Source
SHA-256 checksum
How to use checksums
93318262c3ae868a973c21669c9a5a83d7f26217a6fc6b7659101556f8e26d9e
BLAKE2b-256 checksum
How to use checksums
21e8a0549a744349ba221b2e3ea73fec83fe06b169e6ac4bcab24a64c4816712
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / aceiot_models-0.3.8-py3-none-any.whl

Download URL aceiot_models-0.3.8-py3-none-any.whl
Size 77.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2e1edc7406b156146da87be4e2e70253752fb5a6972ad463b5a22d260a380142
BLAKE2b-256 checksum
How to use checksums
b1bdd36744a9d1ad602d376cc43df49e74f695b4d632da8bf8c556f524a38b14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.8 This release

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.2.7

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page