Skip to main content

Firmngin Python SDK

Firmngin Logo

Python License: MIT

Python SDK for Firmngin device clients, Raspberry Pi. Supports async and sync styles with mTLS, E2EE, entity state, payments, and optional image upload.

Docs: Introduction — Python SDK menu on firmngin.dev/docs

Install

pip install firmngin

Image upload (optional):

pip install firmngin[http]

From Git:

pip install git+https://github.com/firmngin/firmngin-sdk-python.git

Client vs AsyncClient

There are two client classes: Client (sync, blocking) and AsyncClient (async, non-blocking). Both support the same events and payloads. Use AsyncClient in an async context with await client.connect() and await client.run(). Use Client in a sync context with client.connect() and client.run().

Both use ClientConfig.from_file("keys.json") and support the same events.

Quickstart

from firmngin import Client, ClientConfig, Entity, EntityCommand

relay = Entity("relay")
temperature = Entity("temperature")

with Client(ClientConfig.from_file("keys.json")) as client:

    @client.on_entity(relay)
    def handle_relay(command: EntityCommand) -> None:
        print("relay:", command.value)

    client.connect()
    client.push_entity(temperature, 27.5)
    client.run()

Debug mode

Debug is off by default — no banner or console output.

client.set_debug(True)
client.connect()

With debug enabled, connect() prints the Firmngin banner, connection details, and connect/disconnect messages.

Events

Register handlers with client.on(Event.X, handler):

Event Payload Description
Event.PAYMENT Payment Payment updates
Event.PAYMENT_PENDING Payment Payment pending
Event.PAYMENT_SUCCESS Payment Payment succeeded
Event.POSTPAID_READY Payment Postpaid order ready
Event.INIT Init Device init payload
Event.DISPENSE Dispense Vending SKU list to dispense
Event.MERCHANT_STATUS str Merchant status string
Event.VERIFICATION Verification Verification result
Event.PIN Verification PIN display
Event.DEVICE_STATUS DeviceStatus Device lifecycle
Event.ENTITY_COMMAND EntityCommand Any entity command
Event.ACTIVE_SESSION ActiveSession Active paid session
Event.METADATA_PENDING str Pending-payment metadata JSON
Event.METADATA_ACTIVE_SERVICE str Active-service metadata JSON
Event.METADATA_EXPIRED str Expired-payment metadata JSON
Event.METADATA_SUCCESS str Successful-payment metadata JSON
Event.METADATA_POSTPAID_READY str Postpaid-ready metadata JSON
Event.ERROR Exception Runtime error

Metadata events pass the decrypted payload as a JSON string — parse it in your handler.

Event.POSTPAID_READY uses the same Payment fields as pending and successful payments: item title, price, order ID, and quantity (always 1 for postpaid). When the catalog item has postpaid-ready metadata, it is delivered separately through Event.METADATA_POSTPAID_READY.

Every Payment also exposes mutually exclusive payment-type booleans: is_post_paid / is_pre_paid. These flags are separate from is_pending and is_success.

Init business mode

Use is_service_mode / is_vending_mode to detect business mode:

@client.on(Event.INIT)
def on_init(init: Init) -> None:
    if init.is_vending_mode:
        print("vending mode")

Vending dispense

When business mode is vending, a paid order delivers catalog SKUs to dispense. Handle with Event.DISPENSE / Dispense:

from firmngin import Dispense, Event

@client.on(Event.DISPENSE)
def on_dispense(dispense: Dispense) -> None:
    if not dispense.is_valid:
        return
    for sku in dispense.skus:
        print("dispense:", sku)

When the service enters on_active_service, optional catalog metadata is delivered separately through Event.METADATA_ACTIVE_SERVICE. Like the other metadata events, the payload remains a decrypted raw JSON string.

import json

@client.on(Event.METADATA_PENDING)
def on_metadata(raw_json: str) -> None:
    data = json.loads(raw_json)

Per-entity commands:

@client.on_entity(Entity("relay"))
def on_relay(command: EntityCommand) -> None:
    print(command.value)

API overview

Import Role
AsyncClient Async device client
Client Sync blocking client
ClientConfig Runtime settings
KeysConfig keys.json loader
Event Event names for client.on(...)
Entity, Payment, Init, Dispense, … Typed payloads

Device keys

Download keys.json from the Firmngin dashboard. The SDK accepts dashboard fields including server_fingerprint_bytes (20-byte Arduino-style fingerprint) and picks the right TLS validation mode automatically.

The generated service_ca_cert is the trust anchor for HTTPS device services at ota.firmngin.dev, including image upload. MQTT continues to use ca_cert independently.

Never commit real keys. See keys.json.example.

For a local development broker, add these fields to keys.json:

{
  "firmngin_broker_addr": "192.168.100.31",
  "firmngin_broker_port": 1883,
  "firmngin_no_tls": true,
  "firmngin_api_base_url": "http://192.168.100.31:8080/api/v1",
  "firmngin_ota_base_url": "http://192.168.100.31:8080/api/v1/ota"
}

The broker fields only change the MQTT connection. firmngin_no_tls sends MQTT traffic without TLS and must only be used in a trusted development network. firmngin_api_base_url configures HTTP device-service requests. The OTA URL is reserved for OTA support and is not consumed by an OTA executor yet.

Image upload

pip install firmngin[http]
await client.upload_image(Entity("camera"), "snapshot.jpg")

Examples

See examples/.

License

MIT — see LICENSE.

Metadata

Release files for firmngin 0.0.2

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

Source distribution (sdist)

Source distribution for firmngin 0.0.2
File Size Uploaded
firmngin-0.0.2.tar.gz 34.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for firmngin 0.0.2
File Interpreter ABI Platform
firmngin-0.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 70.2 kB

Release files / firmngin-0.0.2.tar.gz

Download URL firmngin-0.0.2.tar.gz
Size 34.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2f7198e83e80c0857ea69cd224606252e59fb1c386dbf7557e306b287b94a248
BLAKE2b-256 checksum
How to use checksums
41341637a0f732448be618a1228f69ddbf2283ac070b804c75170be03c0796f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.10

Release files / firmngin-0.0.2-py3-none-any.whl

Download URL firmngin-0.0.2-py3-none-any.whl
Size 36.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0d342c59f31ff14425dd3ff411f9550594ad5374fb9b8c8779fc7be0e06cf8c6
BLAKE2b-256 checksum
How to use checksums
fbb141cb7208fc9d1f4643bba10825b86af9e15b771d4457160d9b9a795f6cad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.10

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files

0.0.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