This release is a pre-release and may not be stable for production use.
OSHConnect-Python
Library for communicating with Opensensorhub that provides options for saving configurations, getting visualization recommendations for data, retrieving data in real time, archival streams, and batch modes, and more.
API Documentation available here
Links:
Installation
OSHConnect is published to PyPI, but
so far only as alpha pre-releases (latest 0.5.1a22) — there is no stable
release yet. pip and uv skip pre-releases by default, so you must opt in:
pip install "oshconnect==0.5.1a22" # exact pin auto-allows the alpha
pip install --pre oshconnect # or: latest alpha (note below)
uv add "oshconnect==0.5.1a22" # exact pin auto-allows the alpha
uv add "oshconnect>=0.5.1a0" --prerelease=allow # or: allow future alphas
Prefer the exact pin with pip: its --pre flag is global, so it also
allows pre-releases of every dependency (e.g. an alpha pydantic), not just
oshconnect.
To track unreleased work, install straight from Git instead (no pre-release flag needed):
pip install "git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git"
uv add "git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git"
Releases are published from v* tags via .github/workflows/publish.yml.
Installation extras
The base install is transport-free (HTTP discovery/CRUD + models). Streaming
and binary encodings are opt-in extras: mqtt, nats, streaming (mqtt +
nats), protobuf, flatbuffers, tinydb, and all.
Extras combine — comma-separate them in one bracket (no spaces); they're additive. This works from PyPI, from the Git URL, and in a uv project.
# From PyPI (pre-release opt-in required, as above):
pip install --pre "oshconnect[mqtt,protobuf]"
uv add "oshconnect[mqtt,nats]==0.5.1a22" # exact pin auto-allows the alpha
uv add "oshconnect[streaming]>=0.5.1a0" --prerelease=allow
# From Git (unreleased work) — use the "name[extras] @ URL" form:
pip install "oshconnect[mqtt,protobuf] @ git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git"
uv add "git+https://github.com/Botts-Innovative-Research/OSHConnect-Python.git" --extra mqtt --extra nats
See the tutorial's Optional features table for the full matrix.
Running Tests
uv sync # install dev deps (incl. pytest, pytest-cov)
uv run pytest # full suite (skips network-marked tests if you add `-m "not network"`)
uv run pytest tests/test_swe_components.py -v # one file, verbose
uv run pytest -k name_token # one keyword
Tests that need a live OSH server (e.g. localhost:8282 running
FakeWeatherDriver) are tagged @pytest.mark.network. CI skips them; locally
you can include or exclude them:
uv run pytest -m "not network" # what CI runs
uv run pytest -m network # only the live-server tests
Test Coverage
Coverage is opt-in via pytest-cov. The
default pytest run is fast; add --cov when you want a report.
uv run pytest --cov # terminal summary + missing lines
uv run pytest --cov --cov-report=html # HTML report at htmlcov/index.html
uv run pytest --cov --cov-report=xml # coverage.xml (CI / Codecov-ready)
Configuration lives in pyproject.toml under [tool.coverage.*] — branch
coverage is on, source is scoped to src/oshconnect, and obvious dead lines
(if TYPE_CHECKING:, raise NotImplementedError, etc.) are excluded.
CI (.github/workflows/tests.yaml) runs the suite with --cov on every push
across Python 3.11 / 3.12 / 3.13 / 3.14 and uploads coverage.xml as a workflow
artifact (downloadable from the run page). A further non-blocking lane runs
against the 3.15 pre-release as an early-warning signal; it is allowed to fail
and does not gate merges.
Development happens on Python 3.14 (pinned in .python-version); 3.11 is the
supported floor.
Logging
OSHConnect logs to the oshconnect logger namespace — every module uses
logging.getLogger(__name__), so records arrive as oshconnect.node,
oshconnect.resources.system, oshconnect.csapi4py.mqtt, and so on.
The library never configures logging on your behalf: the package logger
carries a NullHandler, so nothing is emitted until you opt in. One call
controls the whole library without touching the root logger or any other
package:
import logging
logging.basicConfig(level=logging.INFO) # your app's choice
logging.getLogger("oshconnect").setLevel(logging.DEBUG) # verbose OSHConnect
logging.getLogger("oshconnect.csapi4py.mqtt").setLevel(logging.WARNING) # ...but quiet MQTT
Note that discovery additionally raises SchemaFetchWarning through the
warnings module when an individual datastream or control-stream schema
fetch fails. That's deliberate and separate from logging — discovery
doesn't raise on per-resource schema failures, so the warning is how you
catch them programmatically (warnings.catch_warnings).
Documentation Coverage
interrogate reports what fraction of
public modules / classes / functions / methods carry a docstring (presence
only, it doesn't check style). It's purely informational right now; there's
no CI gate. Configuration lives in pyproject.toml under [tool.interrogate]
(__init__, dunder, private, and property/setter members are skipped).
uv run interrogate src/oshconnect # one-line summary
uv run interrogate -v src/oshconnect # per-file table
uv run interrogate -vv src/oshconnect # per-symbol (shows which symbols are missing)
Once we agree on a baseline, raise [tool.interrogate].fail-under from 0 so
new code without docstrings starts failing locally and in CI.
OGC Format Serialization
Format-explicit conversion methods on the wrapper classes (System,
Datastream, ControlStream) and the underlying pydantic resource models.
Use these to round-trip CS API server JSON in SML+JSON, OM+JSON, and
SWE+JSON without having to remember the model_dump(by_alias=True, …)
incantation, and to construct OSHConnect wrappers from raw server payloads.
from oshconnect import Node, System, Datastream
node = Node(protocol="http", address="localhost", port=8282)
# Build a System from an SML+JSON server response
sys_dict = {"type": "PhysicalSystem", "uniqueId": "urn:test:1", "label": "Sensor"}
sys = System.from_csapi_dict(sys_dict, node) # auto-detects SML vs GeoJSON
sys.to_smljson_dict() # -> dict ready to POST
# Build a Datastream from a CS API listing entry
ds = Datastream.from_csapi_dict(ds_json, node)
ds.to_csapi_dict() # the resource body
ds.schema_to_swejson_dict() # the SWE+JSON schema doc
ds.observation_to_omjson_dict({"temperature": 22.5}) # one OM+JSON observation
# Single observations / commands
from oshconnect.resource_datamodels import ObservationResource
obs = ObservationResource.from_omjson_dict(om_json_payload)
obs.to_swejson_dict() # flat SWE+JSON record
The two older static factories System.from_system_resource and
Datastream.from_resource are deprecated in favor of from_csapi_dict and
emit DeprecationWarning on use. They'll be removed in a future major
version.
Generating the Docs
The documentation is built with Sphinx using
the Furo theme,
autodoc
for auto-generated API reference from docstrings,
MyST so that Markdown source files
work alongside reST, and sphinxcontrib-mermaid
for the architecture diagrams. Sources live under docs/source/.
Install dev dependencies (including Sphinx, Furo, and the plugins):
uv sync --all-extras
Build the HTML docs:
uv run sphinx-build -b html docs/source docs/build/sphinx
Open docs/build/sphinx/index.html in a browser to view locally.
For a live-reloading preview while editing, use sphinx-autobuild:
uv run --with sphinx-autobuild sphinx-autobuild docs/source docs/build/sphinx
To match what CI publishes (warnings become errors — useful after touching docstrings or signatures):
uv run sphinx-build -W --keep-going -b html docs/source docs/build/sphinx
CI builds the site on every push and deploys main to GitHub Pages via
.github/workflows/docs_pages.yaml.
Metadata
Release files for oshconnect 0.5.5a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| oshconnect-0.5.5a1.tar.gz | 179.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oshconnect-0.5.5a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 312.6 kB
Release files / oshconnect-0.5.5a1.tar.gz
| Download URL | oshconnect-0.5.5a1.tar.gz |
|---|---|
| Size | 179.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
232458975ac9a2fc060e35a95022f48e59e3d87256937099a04dd0119553bf00
|
|
BLAKE2b-256 checksum How to use checksums |
833371141f8b938965c2ff50ff7811e82dd7d065ec29b1bbb25b06b413936165
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / oshconnect-0.5.5a1-py3-none-any.whl
| Download URL | oshconnect-0.5.5a1-py3-none-any.whl |
|---|---|
| Size | 132.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
54bdf2e47208a6387c67c40e11faa9f5c539836738e40036631aea1fa0321c37
|
|
BLAKE2b-256 checksum How to use checksums |
477fec1949ec996c4b12e31360ce57ba868709057a85ec4e0fa5b7aefb65d8ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|