Skip to main content

Python ctypes binding for the TSEdge embedded time-series storage library.

Project description

TSEdge Python Binding

tsedge is a Python ctypes binding for the TSEdge embedded C time-series storage library. Python code calls the public C API from include/tsedge.h; the native TSEdge core still owns WAL, segment files, compressed blocks, block indexes and recovery.

Starting with 0.1.1, locally built wheels can bundle the native TSEdge shared library inside the package. If the bundled library is present, TSEDGE_LIBRARY is not required. TSEDGE_LIBRARY and explicit lib_path arguments still take priority, so applications can override the bundled library.

Prebuilt bundled wheels are currently prepared for macOS arm64. Linux, Windows and macOS x86_64 wheels are planned for a later release.

No runtime Python dependencies are required.

Installation

For local development from the repository:

cd python
python3 -m pip install .

For a built bundled wheel:

python3 -m pip install python/dist/*.whl

When installing from TestPyPI after publishing:

python3 -m pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  tsedge

Building the Native Library

Build the C library first:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

The Python loader searches in this order:

  1. lib_path passed to TSEdge.open(..., lib_path=...);
  2. TSEDGE_LIBRARY;
  3. bundled tsedge/native/libtsedge.dylib, libtsedge.so or tsedge.dll;
  4. common CMake build directories;
  5. the system dynamic-library search path.

Manual override on Linux:

export TSEDGE_LIBRARY=$PWD/build/libtsedge.so

Manual override on macOS:

export TSEDGE_LIBRARY=$PWD/build/libtsedge.dylib

You can also pass a path explicitly:

db = TSEdge.open("sensor_db", lib_path="/path/to/libtsedge.dylib")

Bundled Native Library Wheel

Local macOS bundled wheel build:

rm -rf build
MACOSX_DEPLOYMENT_TARGET=11.0 cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0
cmake --build build
ctest --test-dir build --output-on-failure

cd python
MACOSX_DEPLOYMENT_TARGET=11.0 python3 scripts/prepare_native.py
MACOSX_DEPLOYMENT_TARGET=11.0 python3 -m build --wheel
python3 -m twine check dist/*

scripts/prepare_native.py copies the compiled native library into:

python/src/tsedge/native/libtsedge.dylib

You can override the source library path:

TSEDGE_NATIVE_LIBRARY=/path/to/libtsedge.dylib python3 scripts/prepare_native.py

Check that the wheel is platform-specific and contains the native library:

ls dist/
python3 -m zipfile -l dist/*.whl | grep tsedge/native

Expected local Apple Silicon wheel tag:

tsedge-0.1.1-py3-none-macosx_11_0_arm64.whl

The bundled wheel should not be tagged py3-none-any and should not use a CPython ABI tag such as cp314-cp314.

Runtime check without TSEDGE_LIBRARY:

python3 -m venv /tmp/tsedge-bundled-test
source /tmp/tsedge-bundled-test/bin/activate
python3 -m pip install python/dist/*.whl
unset TSEDGE_LIBRARY
cd /tmp
python3 -c "from tsedge import TSEdge; db = TSEdge.open('/tmp/tsedge_bundled_db'); db.close(); print('OK')"
deactivate

Linux, Windows and macOS x86_64 bundled wheels are intentionally left for a later cibuildwheel step.

Basic Usage

from tsedge import Aggregate, Durability, TSEdge

with TSEdge.open("sensor_db") as db:
    db.create_series("air.temperature")
    db.set_durability(Durability.BALANCED)

    db.append_batch("air.temperature", [
        (1, 23.1),
        (2, 23.4),
        (3, 23.2),
    ])

    avg = db.aggregate("air.temperature", 1, 3, Aggregate.AVG)
    print(avg)

Batch Writes

points = [(i, 20.0 + (i % 100) * 0.01) for i in range(100_000)]
db.append_batch("air.temperature", points)
db.flush_all()

The binding accepts (timestamp, value) tuples or Point dataclass instances. It builds a temporary ctypes array and calls tsedge_append_batch.

Range Reads

read_range wraps the C callback API and returns copied Point objects:

points = db.read_range("air.temperature", 0, 10_000)

The C point pointer is valid only during the callback, so values are copied immediately.

Aggregates

avg = db.aggregate("air.temperature", 0, 10_000, "avg")
min_value = db.aggregate("air.temperature", 0, 10_000, "min")
max_value = db.aggregate("air.temperature", 0, 10_000, "max")
count = db.aggregate("air.temperature", 0, 10_000, "count")

Aggregate names are case-insensitive. You can also use the Aggregate enum.

Window Aggregation

windows = db.aggregate_windowed(
    "air.temperature",
    start_time=0,
    end_time=1_000_000,
    window_size=1000,
)

The binding calls tsedge_aggregate_windowed, copies the returned C array into Python WindowAggregate objects and releases the C memory with tsedge_free_window_aggregates.

Series Metadata

stats = db.get_series_stats("air.temperature")
print(stats.block_count, stats.compression_ratio)

for series in db.list_series():
    print(series.name, series.total_points)

list_series copies the C array into Python objects and frees it with tsedge_free_series_list.

Verify

report = db.verify()
print(report.error_count)

report = TSEdge.verify_path("sensor_db")

Database corruption reported by tsedge_verify is returned in VerifyReport. Set raise_on_error=True if you want a TSEdgeError instead.

CSV Export

db.export_csv("air.temperature", 0, 10_000, "temperature.csv")

Disk Quota, If Available

If the loaded C library provides the quota API, the binding exposes it:

db.set_disk_quota(100 * 1024 * 1024)
print(db.get_disk_quota())
db.enforce_disk_quota()

If an older native library does not export quota symbols, these methods raise TSEdgeError with a clear message.

Sensor Simulation Example

python/examples/sensor_simulation.py is a realistic edge-device workflow. It generates deterministic sensor-like telemetry in Python and writes it to TSEdge in batches. The data is stored by the C core through WAL, segment files and compressed blocks; Python acts only as the application layer.

The example creates:

  • air.temperature
  • air.humidity
  • motor.vibration
  • motor.current

Run it from the repository with the source tree:

PYTHONPATH=python/src TSEDGE_LIBRARY=$PWD/build/libtsedge.dylib \
python3 python/examples/sensor_simulation.py --points 10000 --batch-size 1000

After installing a bundled wheel, neither PYTHONPATH nor TSEDGE_LIBRARY is needed:

python3 python/examples/sensor_simulation.py --points 10000 --batch-size 1000

Options:

--db
--csv
--points
--batch-size

The script prints per-series statistics, min/max/avg/count aggregates, a 60-second window aggregation summary, a small range read, a CSV export path and a verification report.

Run Examples From Source

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

export TSEDGE_LIBRARY=$PWD/build/libtsedge.dylib
PYTHONPATH=python/src python3 python/examples/basic_usage.py
PYTHONPATH=python/src python3 python/examples/batch_write.py
PYTHONPATH=python/src python3 python/examples/read_and_aggregate.py
PYTHONPATH=python/src python3 python/examples/window_aggregate.py
PYTHONPATH=python/src python3 python/examples/sensor_simulation.py --points 10000 --batch-size 1000
PYTHONPATH=python/src python3 python/smoke_test.py

Use libtsedge.so in TSEDGE_LIBRARY on Linux.

Build and Check the Package

cd python
python3 -m pip install --upgrade build twine
MACOSX_DEPLOYMENT_TARGET=11.0 python3 scripts/prepare_native.py
MACOSX_DEPLOYMENT_TARGET=11.0 python3 -m build --wheel
python3 -m twine check dist/*

This creates a platform wheel in python/dist/.

Test a Wheel Locally

python3 -m venv /tmp/tsedge-pkg-test
source /tmp/tsedge-pkg-test/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install python/dist/*.whl
unset TSEDGE_LIBRARY
python3 -c "from tsedge import TSEdge; print(TSEdge)"
python3 python/examples/basic_usage.py
python3 python/examples/sensor_simulation.py --points 1000 --batch-size 100
deactivate

TestPyPI

Do not upload to the main PyPI until the TestPyPI flow has been checked.

Upload to TestPyPI only when credentials are configured:

cd python
python3 -m twine upload --repository testpypi dist/*

Install back from TestPyPI in a clean environment:

python3 -m venv /tmp/tsedge-testpypi
source /tmp/tsedge-testpypi/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  tsedge
python3 -c "from tsedge import TSEdge; print(TSEdge)"
deactivate

Limitations

  • Local bundled wheel verification currently targets macOS.
  • Linux and Windows wheels will be a separate cibuildwheel step.
  • read_range returns a Python list, not a lazy iterator.
  • NumPy arrays are not supported in the first version.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

tsedge-0.1.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (42.5 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

tsedge-0.1.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (44.0 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

tsedge-0.1.1-py3-none-macosx_11_0_x86_64.whl (35.9 kB view details)

Uploaded Python 3macOS 11.0+ x86-64

tsedge-0.1.1-py3-none-macosx_11_0_arm64.whl (34.2 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file tsedge-0.1.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tsedge-0.1.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 241334642456dc5f4bf43f8b176328affe547a75411162a08b6c260bb74abbe7
MD5 1d44ee6e9acc40edc931983ddb95ead4
BLAKE2b-256 4394b1e60191e72214d2ebe0996f039ad7b2af9224c708ae102e4831e911c76b

See more details on using hashes here.

File details

Details for the file tsedge-0.1.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for tsedge-0.1.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 19a31adda592a36ce096c317fe2f6918891b85f0c0865afff7de2ec09fdf11ea
MD5 20e91dbb2fab160d1a999c76cccc7c4a
BLAKE2b-256 d501f7eff029ab59bc883bd13a1d74749ad2295a712474c5f49be6e36f320645

See more details on using hashes here.

File details

Details for the file tsedge-0.1.1-py3-none-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for tsedge-0.1.1-py3-none-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 9d5f63fe94f3e4db3567a293873ed436cf20af6544c436b82844c60eca4a59d3
MD5 b4529c6ef53bd90ab58443307c6b9e9d
BLAKE2b-256 1de5f78888c4f6b3a5e73476d29bd38b3a138fc445efd9fbfd88769a4316644f

See more details on using hashes here.

File details

Details for the file tsedge-0.1.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tsedge-0.1.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ed6add3cfa3b76a6803ea9bf13b1e3332c2a6649928ab52f3273a1bd5e1699f1
MD5 bae0a00655776b59f20c5c7676745098
BLAKE2b-256 c7f881c4ca899b8409d5ea0a03f7c69fe2749c4e55bf73ce1a3aa2b356c0ff32

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