Skip to main content

Python client for the Unimeter usage metering engine

Project description

python-unimeter

Python client for the Unimeter usage metering engine. Async-first design built on asyncio — connects to your cluster, routes requests to the right node, and handles failover automatically.

Zero external dependencies. Standard library only.


Quick start

import asyncio
from unimeter import AsyncClient, Event, MetricSchema, AggType, PeriodType, current_month

async def main():
    async with AsyncClient(["localhost:7001"]) as client:
        # Define a metric
        await client.metrics.create(MetricSchema(
            code="api_calls",
            agg_type=AggType.COUNT,
            period_type=PeriodType.CALENDAR,
            billing_cycle_day=1,
        ))

        # Record usage
        await client.ingest([
            Event(account_id=42, metric_code="api_calls", value=1),
            Event(account_id=42, metric_code="api_calls", value=1),
        ])

        # Query
        result = await client.query(42, "api_calls", current_month())
        print(f"API calls: {result.value.count}")

asyncio.run(main())

Installation

pip install unimeter-python

Requires Python 3.11 or later.


API reference

Connect

from unimeter import AsyncClient

# As a context manager (recommended)
async with AsyncClient(["node0:7001", "node1:7001"]) as client:
    ...

# Or manually
client = AsyncClient(["node0:7001"])
await client.connect()
# ...
await client.close()

Ingest events

from unimeter import Event, DeliveryMode

result = await client.ingest([
    Event(account_id=42, metric_code="api_calls", value=1),
    Event(account_id=99, metric_code="api_calls", value=1),
])
print(result.n_stored, result.n_duplicates)

Events for different accounts are routed to the correct nodes in parallel. Duplicates are detected and discarded automatically.

Delivery mode Behavior
DeliveryMode.ASYNC (default) Returns immediately; data flushed in background
DeliveryMode.SYNC Waits for durable write before returning

Query usage

from unimeter import current_month, last_month, current_billing_period

result = await client.query(42, "api_calls", current_month())
print(result.value.count)

Period helpers:

current_month()              # first of this month to first of next
last_month()                 # previous calendar month
current_billing_period(15)   # current period starting on the 15th
last_billing_period(15)      # previous period starting on the 15th

Filtering by dimension:

# Single dimension
result = await client.query(42, "compute_seconds", current_month(),
    filters={"provider": "aws"})

# AND query across multiple dimensions
result = await client.query(42, "compute_seconds", current_month(),
    filters={"provider": "aws", "region": "us-east"})

Real-time query

agg = await client.query_realtime(42, "api_calls")
print(agg.count)

Raw events and alert history

events = await client.list_events(42, since, until)
alerts = await client.list_alerts(42, since_offset=0)

Metric management

from unimeter import MetricSchema, AggType, PeriodType, DimensionFilter, AlertThreshold

await client.metrics.create(MetricSchema(
    code="compute_seconds",
    agg_type=AggType.SUM,
    period_type=PeriodType.CALENDAR,
    billing_cycle_day=1,
    filters=[
        DimensionFilter(key="provider", values=["aws", "gcp", "azure"]),
    ],
    thresholds=[
        AlertThreshold(code="soft_cap", value=100_000),
    ],
))

await client.metrics.update(schema)
await client.metrics.delete("compute_seconds")
schemas = await client.metrics.list()

Aggregation types: COUNT, SUM, MAX, LATEST, COUNT_UNIQUE

Period types: FIXED (default), CALENDAR


COUNT UNIQUE and OperationType

from unimeter import OperationType

await client.ingest([
    Event(account_id=42, metric_code="active_seats",
          value=user_id, operation_type=OperationType.ADD),
])

Use ADD / REMOVE with a COUNT UNIQUE metric to track active members (seats, users, devices).


Value scaling

All values are scaled integers with 6 decimal places of precision.

from unimeter import scale, unscale

scale(1.5)         # 1_500_000
unscale(1_500_000) # 1.5

Examples

Working examples are in unimeter/examples:

Example Demonstrates
python/saas-api.py Per-request counter, monthly query
python/infra-metering.py SUM with provider/region filters
python/seat-based.py COUNT UNIQUE active seats, entitlement gate
python/high-throughput.py Buffered async ingest
python/free-tier-alerts.py Alert thresholds and enforcement
python/stripe-integration.py Stripe webhook simulation → invoice

Documentation

License

O'SaaSy

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unimeter_python-0.2.0.tar.gz (18.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unimeter_python-0.2.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file unimeter_python-0.2.0.tar.gz.

File metadata

  • Download URL: unimeter_python-0.2.0.tar.gz
  • Upload date:
  • Size: 18.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for unimeter_python-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7bb1de6987bdf5cc6138cde0d1ac76526a1c0204012d788824e9fed93ebae3e3
MD5 b5db1f2b97bc03f419c41aa15f0342a4
BLAKE2b-256 c09c3889e1196b5d939dc26af9512f657efdc3f359638bf873e6ca4b46ed5e96

See more details on using hashes here.

File details

Details for the file unimeter_python-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for unimeter_python-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 184c620c08000e4f4796036cf486ffcdc28cd330904ccbff7c57f64138eae202
MD5 e067178c2d8ba04a8045b8cd2fe30de0
BLAKE2b-256 a8016d1f8ea1960594e68284da94b0b5dd063ed49770d37c758861c9d0e0849f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page