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
Release files for datacanvas 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datacanvas-1.0.0.tar.gz | 20.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| datacanvas-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.0 kB
Release files / datacanvas-1.0.0.tar.gz
| Download URL | datacanvas-1.0.0.tar.gz |
|---|---|
| Size | 20.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
25cf89f1fcd1cb1ed602288957dab0a4445da50a3640189129d24dc1af424af3
|
|
BLAKE2b-256 checksum How to use checksums |
9c7cd4cec541c15762b763c3d4d3d47fb7b45b39e545ab9705c49bb6eeeae7ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / datacanvas-1.0.0-py3-none-any.whl
| Download URL | datacanvas-1.0.0-py3-none-any.whl |
|---|---|
| Size | 19.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bcb3ee42a16bc4315de19aadb2f9fe816b82a99c0210f4634ef6ccc338c40a6c
|
|
BLAKE2b-256 checksum How to use checksums |
f295a6e6fc53cf11ba71b851308e9808aef323f867d45766db571ea62992610e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|