One-line, agent-led install for Storm commercial metering (qualified engineering results — generative CAD & simulation).
Project description
storm-billing
Dependency-free Python SDK and one-line, agent-led installer for Storm's commercial metering (qualified engineering results — generative CAD & simulation).
pip install storm-billing
This installs a storm CLI, an onboarding kit designed to be driven by your coding
agent, and an optional typed SDK:
storm init # write the onboarding kit into your project
storm agent-guide # runbook + interview the agent asks you
storm adapter inspect SAMPLE # offline: propose a mapping for your own events
storm doctor # read-only config + reachability check
storm provision --plan # transparent plan; --apply after you approve
storm verify # authorization smoke test
This wheel is onboarding and provisioning tooling. It does not need to become a
runtime dependency of your product. In the customer-hosted topology a pilot
deploys, raw telemetry stays in your own Kafka/MSK log and a digest-pinned Storm
projector reads it; your product runtime makes one synchronous HTTPS call at
operation submission, which you can make with whatever HTTP client you already
have. If you want that call written out for you rather than typed, copy
examples/control-client/storm_control_client.py
— one file, standard library only.
Reach for the SDK (from storm_billing import StormClient) when you want the
accelerators: Shape A event builders, canonical evidence attestation, batch
receipts, deterministic fixtures.
Enterprise-safe by design: a plain PyPI install (no curl | sh), a pure-Python wheel with
no install-time code, and no network or mutation until you explicitly run a storm command.
See https://stormbilling.dev/docs/install for the full flow.
SDK reference
Integration boundary
The SDK emits raw workflow observations; it cannot declare a result qualified, billable, accepted, priced, or certified. Storm's versioned deterministic policy owns qualification.
The customer-facing meter is qualified_engineering_result. One contract
catalog covers DESIGN_GENERATION and SIMULATION_ANALYSIS. A top-level
customer operation earns at most once after terminal technical success,
verified evidence, customer-visible availability inside the product, and a
complexity class derived from locked inputs.
Resource telemetry such as tokens, model/tool calls, solver/GPU/CPU seconds, storage, retries, and cache hits is retained for cost and margin analysis. It does not directly set the customer price or create a statement line.
The four-event workflow
The Storm-managed edge client that used to be documented here was removed on 2026-07-30 (API-first trim): the earlier Storm-hosted data plane remains a server-side compatibility/benchmark surface, but it is not a customer SDK deliverable and onboarding never configures it. In the pilot topology the events below are published to your own Kafka/MSK log, where the digest-pinned Storm projector reads them; the only Storm call your runtime makes is the synchronous authorization.
import os
from storm_metering import (
StormClient,
engineering_operation_started_event,
engineering_resource_recorded_event,
engineering_result_available_event,
engineering_result_completed_event,
)
customer_id = "nova-propulsion"
customer_operation_id = "operation-wing-design-001"
work_item_id = "wing-design-001"
input_fingerprint = "a" * 64
result_content_hash = "b" * 64
complexity = {
"domain": "aerospace",
"fidelity": "HIGH_FIDELITY",
"constraint_count": "180",
"geometry_feature_count": "4200",
"assembly_component_count": "240",
"optimization_candidate_count": "1200",
"required_evidence_level": "VERIFIED",
}
common = {
"customer_id": customer_id,
"customer_operation_id": customer_operation_id,
"work_item_id": work_item_id,
}
events = [
engineering_operation_started_event(
**common,
event_id="operation-wing-design-001-started",
time="2026-07-19T18:00:00.000Z",
commercial_intent="CUSTOMER_REQUESTED",
result_type="DESIGN_GENERATION",
input_fingerprint=input_fingerprint,
declared_complexity_inputs=complexity,
qualification_deadline_at="2026-07-20T18:00:00.000Z",
),
engineering_resource_recorded_event(
**common,
event_id="operation-wing-design-001-gpu",
time="2026-07-19T18:05:00.000Z",
attempt_id="attempt-001",
meter="gpu_seconds",
quantity="720.000000",
disposition="ORIGINAL",
),
engineering_result_completed_event(
**common,
event_id="operation-wing-design-001-completed",
time="2026-07-19T18:12:00.000Z",
attempt_id="attempt-001",
result_id="result-wing-design-001",
result_content_hash=result_content_hash,
input_fingerprint=input_fingerprint,
result_type="DESIGN_GENERATION",
terminal_state="SUCCEEDED",
design_status="COMPLETE",
requirements_satisfied=True,
final_complexity_inputs=complexity,
operation_started_at="2026-07-19T18:00:00.000Z",
operation_completed_at="2026-07-19T18:12:00.000Z",
evidence_refs=["verified-evidence-record-001"],
tool_version="design-tool-2026.1",
),
engineering_result_available_event(
**common,
event_id="operation-wing-design-001-available",
time="2026-07-19T18:13:00.000Z",
result_id="result-wing-design-001",
result_content_hash=result_content_hash,
availability="CUSTOMER_VISIBLE",
result_reference="prometheus://workbench/results/result-wing-design-001",
),
]
# Admission is a control-plane decision, not telemetry ingestion. Storm derives
# the price and reserves exact currency; the producer never supplies an amount.
control = StormClient(
base_url=os.environ["STORM_CONTROL_PLANE_URL"],
ingest_api_key=os.environ["STORM_TELEMETRY_API_KEY"],
control_plane_api_key=os.environ["STORM_COMMERCIAL_API_KEY"],
)
admission = control.authorize_engineering_operation(events[0])
if not admission["allowed"]:
raise RuntimeError(
f"Engineering operation denied: {admission['reason']}"
)
# Publish `events` to your own Kafka/MSK topic (your existing producer, your
# serialization). Storm's projector consumes them from there — the SDK does
# not send workflow telemetry to Storm.
For SIMULATION_ANALYSIS, provide convergence_status, residual, and
max_constraint_violation instead of design fields. A nonconvergent simulation
cannot earn the commercial result.
Use StormClient separately for scoped control-plane operations: central
operation authorization, reservation lookup, evidence registration and
verification, qualification explanations, commercial-fact reads, and statement
reads with CSV/reconciliation download. Admission denial (402) is returned as
a typed decision; malformed, unauthorized, and unexpected responses still raise
StormApiError. Statement authoring and settlement (preview, commit, finalize,
export, destinations) belong to finance tooling and were removed from this
client on 2026-07-30, as were the legacy finalized-simulation and
internal-cost builders — the four workflow builders above are the producer
contract.
Engineering artifacts stay in customer-owned systems. Send only immutable hashes, US-resident references, and evidence metadata.
The first deployment profile targets AWS us-west-2, but the SDK makes no
assumption about your cloud. It depends only on Storm's HTTP contracts and does
not embed an AWS dependency.
See docs/api-contract.md, docs/architecture/high-throughput-data-plane.md,
https://stormbilling.dev/docs/data-plane, and
openapi/storm-agent-api.openapi.json.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file storm_billing-0.3.0.tar.gz.
File metadata
- Download URL: storm_billing-0.3.0.tar.gz
- Upload date:
- Size: 54.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
418a35a0033e6487db16a57e6840b1b9550b420ff8bfc04c6886dd3585f3b4a9
|
|
| MD5 |
1191943d21d5f03c1e43931230f4f1d2
|
|
| BLAKE2b-256 |
74b3736fee4f8ba4036f436ce874b0cf3b6b40c818d3eec23703f925847b65c4
|
File details
Details for the file storm_billing-0.3.0-py3-none-any.whl.
File metadata
- Download URL: storm_billing-0.3.0-py3-none-any.whl
- Upload date:
- Size: 61.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da44683795609796084063afc164f2e3ec7f90056de6e1abcbe97fdfd422c460
|
|
| MD5 |
c00ee402d90ac16de67129a37d2b39f4
|
|
| BLAKE2b-256 |
35d34b685ab28178142299f0200d1b7e7f58c0ef439d3dcd73ce28f24942b346
|