Official Python SDK for the DataCanvas IoT Platform — A modern, type-safe, resource-based client library
Project description
DataCanvas SDK for Python
Official Python SDK for the DataCanvas IoT Platform. A modern, type-safe, and resource-based client library for seamless integration with the DataCanvas API.
Features
- Resource-Based Architecture — Intuitive API organised by domain concepts
- Type-Safe — Full type annotations and
py.typedmarker for static analysis - Modern — Supports Python 3.9+, dataclasses, and enums
- Robust Error Handling — Comprehensive error hierarchy for precise error management
- Minimal Dependencies — Uses
requestsfor HTTP; no unnecessary extras
Installation
pip install datacanvas
Quick Start
import os
from datacanvas import DataCanvas, SortOrder
# Initialise SDK
client = DataCanvas(
access_key_client=os.environ["DATACANVAS_ACCESS_KEY_ID"],
access_key_secret=os.environ["DATACANVAS_SECRET_KEY"],
project_id=int(os.environ["DATACANVAS_PROJECT_ID"]),
base_url=os.environ["DATACANVAS_BASE_URL"],
)
# List all devices
devices = client.devices.list()
print(f"Found {len(devices.devices)} devices")
# Retrieve data from a datatable
data = client.data.list(
table_name="temperature_sensors",
devices=[1, 2, 3],
page=0,
limit=50,
order=SortOrder.DESC,
)
print(f"Retrieved {data.count} data points")
Context Manager
The SDK supports context managers for automatic resource cleanup:
with DataCanvas(
access_key_client="your-key",
access_key_secret="your-secret",
project_id=123,
base_url="https://api.<something>.<something>",
) as client:
devices = client.devices.list()
API Reference
Configuration
DataCanvas(**kwargs)
Creates a new SDK instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
access_key_client |
str |
✅ | Client access key ID from DataCanvas dashboard |
access_key_secret |
str |
✅ | Secret access key for authentication |
project_id |
int |
✅ | Project ID to scope API requests |
base_url |
str |
✅ | Base URL for the DataCanvas API |
client = DataCanvas(
access_key_client="your-access-key-id",
access_key_secret="your-secret-key",
project_id=123,
base_url="https://api.<something>.<something>",
)
Device Management
client.devices.list() -> DeviceResponse
Retrieves all devices associated with the configured project.
response = client.devices.list()
for device in response.devices:
print(f"Device: {device.device_name} (ID: {device.device_id})")
Response types:
@dataclass
class DeviceResponse:
success: bool
devices: list[Device]
@dataclass
class Device:
device_id: int
device_name: str
Data Retrieval
client.data.list(**kwargs) -> DataResponse
Retrieves data from a specified datatable with optional filtering and pagination.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
table_name |
str |
✅ | — | Name of the datatable to query |
devices |
list[int] |
❌ | [] |
List of device IDs to filter |
page |
int |
❌ | 0 |
Page number (0-indexed) |
limit |
int |
❌ | 20 |
Items per page (max: 1000) |
order |
SortOrder |
❌ | DESC |
Sort order (ASC or DESC) |
from datacanvas import SortOrder
# Retrieve all data
all_data = client.data.list(table_name="temperature_sensors")
# Retrieve with filtering and pagination
filtered = client.data.list(
table_name="temperature_sensors",
devices=[1, 2, 3],
page=0,
limit=50,
order=SortOrder.DESC,
)
print(f"Total records: {filtered.count}")
for device_id, points in filtered.data.items():
print(f"Device {device_id}: {len(points)} data points")
for point in points:
print(f" - ID: {point.id}, Device: {point.device}, Extra: {point.extra}")
Response types:
@dataclass
class DataResponse:
count: int
data: dict[str, list[DataPoint]]
@dataclass
class DataPoint:
id: int
device: int
extra: dict[str, Any] # Dynamic fields from datatable schema
Error Handling
The SDK provides comprehensive error handling with specific error types for different scenarios. All errors inherit from DataCanvasError.
Error Types
| Error Class | Description | HTTP Status |
|---|---|---|
AuthenticationError |
Invalid credentials | 401 |
AuthorizationError |
Insufficient permissions | 403 |
ValidationError |
Invalid request parameters | 400, 422 |
NotFoundError |
Resource not found | 404 |
RateLimitError |
Rate limit exceeded | 429 |
ServerError |
Server-side error | 500+ |
NetworkError |
Network connectivity issue | — |
Handling Errors
from datacanvas import (
DataCanvas,
AuthenticationError,
ValidationError,
RateLimitError,
NetworkError,
DataCanvasError,
)
try:
data = client.data.list(table_name="sensors", limit=100)
except AuthenticationError:
print("Authentication failed. Check your credentials.")
except ValidationError as e:
print(f"Invalid request: {e}")
except RateLimitError:
print("Rate limit exceeded. Please wait.")
except NetworkError as e:
print(f"Network error: {e}")
except DataCanvasError as e:
print(f"SDK error: {e}")
Architecture
The SDK follows a resource-based OOP architecture with clear separation of concerns:
DataCanvas SDK
├── DataCanvas (Main Client)
│ ├── devices (DevicesResource)
│ └── data (DataResource)
├── HttpClient (HTTP Communication)
├── Exceptions (Error Hierarchy)
├── Constants (Enums & Defaults)
└── Types (Dataclass Definitions)
Python Type Checking
The SDK ships with a py.typed marker and full type annotations. Use with mypy or pyright:
from datacanvas import DataCanvas, SDKConfig, DeviceResponse, DataResponse, DataPoint, GetDataParams
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone repository
git clone https://github.com/Datacanvas-IoT/Datacanvas-PIP
cd Datacanvas-PIP
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run type checks
mypy src/datacanvas
# Run linter
ruff check src/
License
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.
Resources
Support
For questions, issues, or feature requests:
- 📧 Email: datacanvasmgmt[at]gmail[dot]com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Made with ❤️ by the DataCanvas Team
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 datacanvas-1.0.0.tar.gz.
File metadata
- Download URL: datacanvas-1.0.0.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25cf89f1fcd1cb1ed602288957dab0a4445da50a3640189129d24dc1af424af3
|
|
| MD5 |
8223dc251814b38f5d36569401cac1b8
|
|
| BLAKE2b-256 |
9c7cd4cec541c15762b763c3d4d3d47fb7b45b39e545ab9705c49bb6eeeae7ef
|
File details
Details for the file datacanvas-1.0.0-py3-none-any.whl.
File metadata
- Download URL: datacanvas-1.0.0-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcb3ee42a16bc4315de19aadb2f9fe816b82a99c0210f4634ef6ccc338c40a6c
|
|
| MD5 |
3e47fc7d5e73e116f2b9e398d964ec97
|
|
| BLAKE2b-256 |
f295a6e6fc53cf11ba71b851308e9808aef323f867d45766db571ea62992610e
|