A Python client for Wyld Network's Satellite IoT API with support for custom payload schemas
Project description
Wyld API Client
A Python client for interacting with Wyld Network's Satellite IoT API with support for custom payload schemas.
Features
- 🔐 HMAC-SHA256 authentication
- 📡 Fetch device data from satellite IoT network
- 🎯 Custom payload schema validation - Define schemas for different device codecs
- ✅ Type-safe data access with Pydantic models
- 🔄 Flexible response parsing for varying device types
Installation
# Using uv
uv add pydantic requests
# Or using pip
pip install pydantic requests
Quick Start
Basic Usage (Raw Data)
from wyld_api_client import WyldAPIClient
import time
client = WyldAPIClient(
org_id="your_org_id",
api_token="your_api_token"
)
# Get raw data without validation
end_ts = int(time.time() * 1000)
start_ts = end_ts - (24 * 60 * 60 * 1000) # 24 hours ago
data = client.get_device_data("device_id", start_ts, end_ts)
print(data)
Advanced Usage with Schemas
The API returns different payload structures based on the device's codec. You can define schemas to validate and type-check the response data:
from wyld_api_client import WyldAPIClient
from schemas import BasePayload
from pydantic import Field
from typing import Optional
# Define a schema for your device's codec
class TemperatureSensorPayload(BasePayload):
temperature: float = Field(..., description="Temperature in Celsius")
humidity: Optional[float] = None
battery: Optional[int] = None
# Use the schema to get validated, typed data
client = WyldAPIClient(org_id="your_org", api_token="your_token")
temperature_data = client.get_device_data(
dev_id="temp_sensor_001",
start_ts=start_ts,
end_ts=end_ts,
payload_schema=TemperatureSensorPayload, # Pass your schema
validate=True
)
# Now you get typed objects with auto-completion!
for reading in temperature_data:
print(f"Temperature: {reading.temperature}°C")
if reading.humidity:
print(f"Humidity: {reading.humidity}%")
Custom Schemas for Different Device Types
Since the satellite IoT network uses different codecs per device type, you can create schemas for each:
Example: GPS Tracker
from schemas import BasePayload
class GPSTrackerPayload(BasePayload):
latitude: float
longitude: float
altitude: Optional[float] = None
speed: Optional[float] = None
satellites: Optional[int] = None
# Use it
gps_data = client.get_device_data(
dev_id="gps_tracker_123",
start_ts=start_ts,
end_ts=end_ts,
payload_schema=GPSTrackerPayload
)
for location in gps_data:
print(f"Position: {location.latitude}, {location.longitude}")
Example: Water Level Sensor
class WaterLevelSensorPayload(BasePayload):
water_level_cm: float
pressure_kpa: float
battery_voltage: Optional[float] = None
water_data = client.get_device_data(
dev_id="water_sensor_456",
start_ts=start_ts,
end_ts=end_ts,
payload_schema=WaterLevelSensorPayload
)
for reading in water_data:
print(f"Water Level: {reading.water_level_cm} cm")
Dynamic Schema Selection
Handle multiple device types with a schema registry:
# Create a mapping of device types to schemas
DEVICE_SCHEMAS = {
"temperature": TemperatureSensorPayload,
"gps": GPSTrackerPayload,
"water_level": WaterLevelSensorPayload,
}
def get_device_data_with_schema(device_id, device_type, start_ts, end_ts):
schema = DEVICE_SCHEMAS.get(device_type)
return client.get_device_data(
dev_id=device_id,
start_ts=start_ts,
end_ts=end_ts,
payload_schema=schema,
validate=True if schema else False
)
Error Handling
The client includes validation error handling:
from pydantic import ValidationError
try:
data = client.get_device_data(
dev_id="device_123",
start_ts=start_ts,
end_ts=end_ts,
payload_schema=TemperatureSensorPayload,
validate=True
)
except ValidationError as e:
print(f"Validation failed: {e}")
# Fall back to raw data
raw_data = client.get_device_data(
dev_id="device_123",
start_ts=start_ts,
end_ts=end_ts,
payload_schema=None
)
API Reference
WyldAPIClient.get_device_data()
Fetch device data with optional schema validation.
Parameters:
dev_id(str): The device IDstart_ts(int): Start timestamp in milliseconds since epochend_ts(int): End timestamp in milliseconds since epochpayload_schema(Optional[Type[BasePayload]]): Pydantic model class for validationvalidate(bool): Enable/disable validation (default: True)
Returns:
- If
payload_schemais None: Raw dict response - If
payload_schemaprovided: List of validated payload objects
Schema Definition Guidelines
- Inherit from
BasePayload: All custom schemas should inherit fromBasePayload - Use Pydantic Field validators: Leverage Pydantic's validation features
- Make fields Optional: Use
Optional[]for fields that may not always be present - Add descriptions: Use
Field(..., description="...")for better documentation
from schemas import BasePayload
from pydantic import Field, field_validator
from typing import Optional
class CustomPayload(BasePayload):
# Required field
sensor_value: float = Field(..., description="Primary sensor reading")
# Optional field with default
status: Optional[str] = Field(None, description="Device status")
# Field with validation
battery_level: int = Field(..., ge=0, le=100, description="Battery 0-100%")
@field_validator('battery_level')
def validate_battery(cls, v):
if v < 10:
print(f"Warning: Low battery ({v}%)")
return v
Benefits of Using Schemas
- Type Safety: IDE auto-completion and type checking
- Validation: Automatic data validation against your schema
- Documentation: Self-documenting code with field descriptions
- Searchability: Easier to search and filter data with typed objects
- Flexibility: Support for varying codecs across device types
- Error Detection: Catch data issues early in development
Examples
See usage_examples.py for comprehensive examples of all features.
License
[Your License Here]
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 wyld_api-0.1.1.tar.gz.
File metadata
- Download URL: wyld_api-0.1.1.tar.gz
- Upload date:
- Size: 8.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae2ebd3aef74ff49be74b865a1dc450774c68a3823f28169174d71aaaa8bd387
|
|
| MD5 |
daa72e189fc9eadfa604b2e5cd103035
|
|
| BLAKE2b-256 |
6970a4e35428ef18053517462605291066376fda40ed8fb915c76b7660f1fd86
|
File details
Details for the file wyld_api-0.1.1-py3-none-any.whl.
File metadata
- Download URL: wyld_api-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f219b64f71cd3c98767a1d9c620e656e2841cda2a3a1de2c20f66e07e41781d
|
|
| MD5 |
407a4b358aba823fe033f9cb2d0fef0e
|
|
| BLAKE2b-256 |
99950b075c06c7da5476fb690f58c41e83a14d9e7193ebc5e1da9816e0ccee20
|