|
| 1 | +# SyconApi |
| 2 | + |
| 3 | +Lightweight Python client for the Sycon cloud API — concise, synchronous wrapper to authenticate and fetch device lists and raw device data. |
| 4 | + |
| 5 | +## Install |
| 6 | + |
| 7 | +```bash |
| 8 | +# HTTPS |
| 9 | +pip install "git+https://github.com/Hello-sycon/sycon-api.git@SyconApi-v$VERSION#subdirectory=libs/SyconApi" |
| 10 | + |
| 11 | +#SSH |
| 12 | +pip install "git+ssh://git@github.com/Hello-sycon/sycon-api.git@SyconApi-v$VERSION#subdirectory=libs/SyconApi" |
| 13 | +``` |
| 14 | + |
| 15 | +>[!NOTE] |
| 16 | +>To select the $VERSION variable, you can see the release associate to tag section in github repository |
| 17 | +
|
| 18 | +## Quick example |
| 19 | + |
| 20 | +```py |
| 21 | +from sycon_api import SyconApi |
| 22 | + |
| 23 | +client = SyconApi(username="me@example.com", password="secret", debug=False) |
| 24 | + |
| 25 | +# authenticate (normally called automatically by methods that need a token) |
| 26 | +client.authenticate() |
| 27 | + |
| 28 | +# list devices |
| 29 | +devices = client.get_devices_list() |
| 30 | +print(devices) |
| 31 | + |
| 32 | +# get data for a single device |
| 33 | +data = client.get_data_from_device( |
| 34 | + device_id="device-123", |
| 35 | + field=SyconApi.SyconApiDataFields.TEMPERATURE_CELSIUS, |
| 36 | + start_date="2025-10-03T12:30:00.000Z", |
| 37 | + end_date="2025-10-03T13:30:00.000Z", |
| 38 | + head_limit=100, |
| 39 | +) |
| 40 | +print(data) |
| 41 | + |
| 42 | +# get data for multiple devices (use tuple — function is cached) |
| 43 | +devices_data = client.get_data_from_devices( |
| 44 | + devices_id=("device-123", "device-456"), |
| 45 | + field=SyconApi.SyconApiDataFields.CO2_PPM, |
| 46 | + start_date="2025-10-03T12:30:00.000Z", |
| 47 | + end_date="2025-10-03T13:30:00.000Z", |
| 48 | + head_limit=10, |
| 49 | +) |
| 50 | +print(devices_data) |
| 51 | + |
| 52 | +# get data for all devices (uses get_devices_list internally) |
| 53 | +all_data = client.get_data_from_all_devices( |
| 54 | + field=SyconApi.SyconApiDataFields.HUMIDITY_PERCENT, |
| 55 | + start_date="2025-10-03T12:30:00.000Z", |
| 56 | + end_date="2025-10-03T13:30:00.000Z", |
| 57 | + head_limit=10, |
| 58 | +) |
| 59 | +print(all_data) |
| 60 | +``` |
| 61 | + |
| 62 | +## Public API (concise) |
| 63 | + |
| 64 | +All methods below belong to `SyconApi` (no leading underscore). |
| 65 | + |
| 66 | +### Constructor / properties |
| 67 | + |
| 68 | +* `SyconApi(username: str, password: str, debug: bool = False, debug_level: int = SyconApiLogLevel.DEBUG.value) -> SyconApi` |
| 69 | + Create client. Pass `debug=True` to enable logger. |
| 70 | +* `username` — property, configured username. |
| 71 | +* `token` — property, current token (may be `None` until authenticated). |
| 72 | + |
| 73 | +### Enums |
| 74 | + |
| 75 | +* `SyconApi.SyconApiDataFields` — data field constants (e.g. `TEMPERATURE_CELSIUS`, `CO2_PPM`, `HUMIDITY_PERCENT`, ...). |
| 76 | +* `SyconApi.SyconApiV1Route` — endpoints (LOGIN, RENEW, CHECK, DEVICES, DATA). |
| 77 | +* `SyconApi.SyconApiLogLevel` — log levels. |
| 78 | + |
| 79 | +### Exceptions you may catch |
| 80 | + |
| 81 | +* `SyconApiInvalidParametersException` — invalid argument(s). |
| 82 | +* `SyconApiMissingParametersException` — required parameter missing. |
| 83 | +* `SyconApiBadResponseException` — 4xx HTTP response or invalid JSON where JSON is expected. |
| 84 | +* `SyconApiServerErrorResponseException` — 5xx HTTP response. |
| 85 | + |
| 86 | +### Main methods |
| 87 | + |
| 88 | +* `authenticate() -> None` |
| 89 | + Authenticate with username/password. On success the client `token` is set from response headers. |
| 90 | + |
| 91 | +* `renew_token() -> None` |
| 92 | + Renew token using current token. Raises `SyconApiBadResponseException` if no `Authorization` header in response. |
| 93 | + |
| 94 | +* `check_token() -> bool` |
| 95 | + Check if current token is still valid. Returns `True` on HTTP 200. |
| 96 | + |
| 97 | +* `get_devices_list() -> Optional[Dict[str, Any]]` |
| 98 | + Return devices list (parsed JSON) on HTTP 200. Raises `SyconApiBadResponseException` if response JSON is invalid. |
| 99 | + |
| 100 | +* `get_data_from_device(device_id: str, field: SyconApiDataFields, start_date: str, end_date: str, head_limit: Optional[int] = None, tail_limit: Optional[int] = None, external_sensor_id: Optional[str] = None) -> Optional[Dict[str, Any]]` |
| 101 | + Fetch raw data for a single device. Returns a `dict` if response JSON parsed, otherwise `None`. Validates date format (ISO-8601 instant) and requires exactly one of `head_limit` / `tail_limit`. |
| 102 | + |
| 103 | +* `get_data_from_devices(devices_id: Tuple[str], field: SyconApiDataFields, start_date: str, end_date: str, head_limit: Optional[int] = None, tail_limit: Optional[int] = None, external_sensor_id: Optional[str] = None) -> Optional[Dict[str, Any]]` |
| 104 | + Fetch raw data for multiple devices. **Important:** `devices_id` must be an **immutable tuple** (function is cached via `lru_cache`). Returns a dict mapping `device_id` → response body (dict or raw text). |
| 105 | + |
| 106 | +* `get_data_from_all_devices(field: SyconApiDataFields, start_date: str, end_date: str, head_limit: Optional[int] = None, tail_limit: Optional[int] = None, external_sensor_id: Optional[str] = None) -> Optional[Dict[str, Any]]` |
| 107 | + Fetch data for all devices returned by `get_devices_list()`. Skips device entries that do not have an `"id"` key. |
| 108 | + |
| 109 | +## Notes & best practices |
| 110 | + |
| 111 | +* **Dates:** use strict ISO-8601 instant format: `YYYY-MM-DDTHH:MM:SS[.ms]Z` (example: `2025-10-03T12:30:00.000Z`). Invalid format raises `SyconApiInvalidParametersException`. |
| 112 | +* **Head/Tail limits:** exactly one of `head_limit` or `tail_limit` must be provided (not both). Limits are capped to `k_size_batch_limit` (default 10000). |
| 113 | +* **Caching:** `get_data_from_devices` and `get_data_from_device` are cached (`lru_cache`). For cached calls, ensure all arguments are hashable (use `tuple` for device lists). You can clear the cache with e.g. `SyconApi.get_data_from_devices.cache_clear()`. |
| 114 | +* **Errors:** 4xx responses raise `SyconApiBadResponseException`; 5xx raise `SyconApiServerErrorResponseException`. Network-level errors (requests exceptions) will propagate. |
| 115 | +* **Logging:** enable `debug=True` in the constructor to activate the internal logger. |
0 commit comments