marpledata 3.3.0__tar.gz → 3.4.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- marpledata-3.4.0.dev1/.env.local +3 -0
- marpledata-3.4.0.dev1/.env.nightly +2 -0
- marpledata-3.4.0.dev1/.env.staging +4 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/CHANGELOG.md +10 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/PKG-INFO +35 -1
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/README.md +34 -0
- marpledata-3.4.0.dev1/augment-dataset.py +681 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/db.rst +4 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.db.DB.rst +2 -1
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.db.DataStream.rst +1 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.db.Dataset.rst +5 -0
- marpledata-3.4.0.dev1/docs/api/marple.db.LAKE_ARROW_SCHEMA.rst +6 -0
- marpledata-3.4.0.dev1/docs/api/marple.db.SCHEMA.rst +6 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.db.Signal.rst +1 -0
- marpledata-3.4.0.dev1/docs/api/marple.db.SignalUpload.rst +32 -0
- marpledata-3.4.0.dev1/docs/api/marple.db.SignalsAlreadyExistError.rst +6 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/getting-started.rst +4 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/tutorials.rst +22 -0
- marpledata-3.4.0.dev1/ingest-ibiza.py +538 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/pyproject.toml +1 -1
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/__init__.py +1 -1
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/db/__init__.py +26 -2
- marpledata-3.4.0.dev1/src/marple/db/constants.py +52 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/db/dataset.py +184 -42
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/db/datastream.py +3 -9
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/db/signal.py +62 -4
- marpledata-3.4.0.dev1/src/marple/db/signal_upload.py +317 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/utils.py +7 -2
- marpledata-3.4.0.dev1/tests/test_signal_upload.py +332 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/uv.lock +1 -1
- marpledata-3.3.0/src/marple/db/constants.py +0 -19
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.flake8 +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.gitignore +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.python-version +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.uv-cache/.gitignore +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.uv-cache/.lock +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.uv-cache/CACHEDIR.TAG +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.uv-cache/interpreter-v4/c2c2931c8a99aae1/588e1e7c128e2872.msgpack +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/.uv-cache/sdists-v9/.gitignore +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/AGENTS.md +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/CONTRIBUTING.md +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/LICENSE +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/DEPLOYMENT.md +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/_static/custom.css +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/_static/favicon.png +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/_static/logo.png +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/insight.rst +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.Insight.rst +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api/marple.db.DatasetList.rst +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/api.rst +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/conf.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/docs/index.rst +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/example.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/examples_race.csv +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/pytest.xml +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/db/sql.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/insight.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/src/marple/py.typed +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/conftest.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/support.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/test_db.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/test_insight.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/test_reliability.py +0 -0
- {marpledata-3.3.0 → marpledata-3.4.0.dev1}/tests/test_sql.py +0 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
MDB_TOKEN=mdb_BfGpBUolaa4OlZpl-npTdq497-fVlXrCIRSUEVgox7Y
|
|
2
|
+
MDB_URL=https://db.staging.marpledata.com/api/v1
|
|
3
|
+
INSIGHT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL2FwcC5nZXRtYXJwbGUuaW8vYXBpLyIsImlzcyI6Imh0dHBzOi8vZGV2LXY4OHh3a213LmV1LmF1dGgwLmNvbS8iLCJpYXQiOjE3NzQ4NzI2MDMuNDk5NDc5OCwiZXhwIjoxNzc3NDY0NTkwLjgyNywic3ViIjoiZmMyZGQ1NmUtM2NiMC00YjEzLWIwYjMtMDFmYjZmNjk1MzNmIiwiaHR0cHM6Ly9tYXJwbGVkYXRhLmNvbS9lbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaHR0cHM6Ly9tYXJwbGVkYXRhLmNvbS9hcGlfdG9rZW4iOiJiNDAzYWNlZi0xOWI0LTQ1MTMtYmJmMy0wN2Q2MzQ1MTY1ZTQifQ.-LxExjnpxFD_xGZE6xdX20GHalXMWRBSN02Bjt9lx00
|
|
4
|
+
INSIGHT_URL=https://insight.staging.marpledata.com/api/v1
|
|
@@ -5,6 +5,16 @@ All notable changes to the Python SDK package `marpledata` will be documented in
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.4.0] - 2026-07-16
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `Dataset.add_signal` and `Dataset.add_signals` to upload signal data onto an existing dataset (presign → write → PUT → complete). Accepts DataFrame, Arrow table, or on-disk parquet matching `LAKE_ARROW_SCHEMA` (`time` plus `value` and/or `value_text`); supports concurrent uploads, batch-level `overwrite`, import `priority`, and automatic ~1M-row groups / ~16M-row file splits.
|
|
13
|
+
- `Signal.wait_until_available` to poll until a signal is queryable (storage status is no longer `FROZEN_TO_COLD`; typical after `add_signal`).
|
|
14
|
+
- `SignalUpload` input model and `SignalsAlreadyExistError` for HTTP 409 presign conflicts (duplicate / already exists).
|
|
15
|
+
- Exported `LAKE_ARROW_SCHEMA` describing the input columns for signal upload (alongside existing realtime `SCHEMA` for `Dataset.append`).
|
|
16
|
+
- `Dataset.get_signals(signal_ids=...)` to fetch signals by ID (order preserved), plus `refresh` on `get_signal` / `get_signals` to bypass the local cache.
|
|
17
|
+
|
|
8
18
|
## [3.3.0] - 2026-06-29
|
|
9
19
|
|
|
10
20
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marpledata
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0.dev1
|
|
4
4
|
Summary: Marple SDK for Python
|
|
5
5
|
Project-URL: Homepage, https://www.marpledata.com/
|
|
6
6
|
Project-URL: Documentation, https://marpledata.gitlab.io/marple-sdk/
|
|
@@ -87,6 +87,37 @@ dataset = stream.push_file("examples_race.csv", metadata={"driver": "Mbaerto"})
|
|
|
87
87
|
dataset = dataset.wait_for_import(timeout=10)
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
#### Add signals to an imported dataset
|
|
91
|
+
|
|
92
|
+
Upload additional signals (for example derived channels) on an existing dataset.
|
|
93
|
+
Each signal is a DataFrame, Arrow table, or on-disk parquet matching `LAKE_ARROW_SCHEMA`:
|
|
94
|
+
columns `time` (int64 nanoseconds) plus `value` and/or `value_text`.
|
|
95
|
+
Times must overlap the dataset time range. Use `overwrite=True` to replace an existing signal name;
|
|
96
|
+
a conflict without overwrite raises `SignalsAlreadyExistError`.
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import pandas as pd
|
|
100
|
+
from marple.db import LAKE_ARROW_SCHEMA # time + value and/or value_text
|
|
101
|
+
|
|
102
|
+
speed = dataset.get_signal("car.speed").get_data()
|
|
103
|
+
derived = pd.DataFrame({
|
|
104
|
+
"time": speed.index.asi8,
|
|
105
|
+
"value": speed["value"] * 3.6,
|
|
106
|
+
})
|
|
107
|
+
# Single signal: wait until available before reading
|
|
108
|
+
signal = dataset.add_signal(
|
|
109
|
+
"car.speed_kmh",
|
|
110
|
+
derived,
|
|
111
|
+
metadata={"unit": "km/h"},
|
|
112
|
+
).wait_until_available()
|
|
113
|
+
|
|
114
|
+
# Batch: returns IDs as soon as upload completes (no wait)
|
|
115
|
+
ids = dataset.add_signals([
|
|
116
|
+
{"name": "car.speed_kmh", "data": derived, "metadata": {"unit": "km/h"}},
|
|
117
|
+
], overwrite=True, concurrency=4)
|
|
118
|
+
signals = dataset.get_signals(signal_ids=ids)
|
|
119
|
+
```
|
|
120
|
+
|
|
90
121
|
#### Upload large files
|
|
91
122
|
|
|
92
123
|
`stream.push_file(...)` starts an ingestion and lets the Marple DB API choose the best upload mode. Depending on the deployment and file size, the SDK can upload through the API server, upload directly to Azure Blob Storage, use a single presigned URL, or split the file into multipart uploads.
|
|
@@ -173,6 +204,9 @@ if len(datasets) > 0:
|
|
|
173
204
|
- **List streams**: `db.get_streams()`
|
|
174
205
|
- **List datasets in a stream**: `stream.get_datasets()`
|
|
175
206
|
- **Upload a file to a file-stream**: `stream.push_file(file_path, metadata={...}, concurrency=4)`
|
|
207
|
+
- **Add signals to a dataset**: `dataset.add_signal(name, data, ...)` / `dataset.add_signals([...])` — data matches `LAKE_ARROW_SCHEMA` (`time` + `value` and/or `value_text`)
|
|
208
|
+
- **Wait until a signal is available**: `signal.wait_until_available(timeout=60)`
|
|
209
|
+
- **Fetch signals by ID**: `dataset.get_signals(signal_ids=[...], refresh=False)`
|
|
176
210
|
- **Wait for a dataset to import**: `dataset.wait_for_import(timeout=60)`
|
|
177
211
|
- **Download original uploaded file**: `dataset.download(destination_folder=".")`
|
|
178
212
|
- **Download parquet for a signal**: `dataset.get_signal(signal_name).download(destination_folder=".")`
|
|
@@ -52,6 +52,37 @@ dataset = stream.push_file("examples_race.csv", metadata={"driver": "Mbaerto"})
|
|
|
52
52
|
dataset = dataset.wait_for_import(timeout=10)
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
#### Add signals to an imported dataset
|
|
56
|
+
|
|
57
|
+
Upload additional signals (for example derived channels) on an existing dataset.
|
|
58
|
+
Each signal is a DataFrame, Arrow table, or on-disk parquet matching `LAKE_ARROW_SCHEMA`:
|
|
59
|
+
columns `time` (int64 nanoseconds) plus `value` and/or `value_text`.
|
|
60
|
+
Times must overlap the dataset time range. Use `overwrite=True` to replace an existing signal name;
|
|
61
|
+
a conflict without overwrite raises `SignalsAlreadyExistError`.
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import pandas as pd
|
|
65
|
+
from marple.db import LAKE_ARROW_SCHEMA # time + value and/or value_text
|
|
66
|
+
|
|
67
|
+
speed = dataset.get_signal("car.speed").get_data()
|
|
68
|
+
derived = pd.DataFrame({
|
|
69
|
+
"time": speed.index.asi8,
|
|
70
|
+
"value": speed["value"] * 3.6,
|
|
71
|
+
})
|
|
72
|
+
# Single signal: wait until available before reading
|
|
73
|
+
signal = dataset.add_signal(
|
|
74
|
+
"car.speed_kmh",
|
|
75
|
+
derived,
|
|
76
|
+
metadata={"unit": "km/h"},
|
|
77
|
+
).wait_until_available()
|
|
78
|
+
|
|
79
|
+
# Batch: returns IDs as soon as upload completes (no wait)
|
|
80
|
+
ids = dataset.add_signals([
|
|
81
|
+
{"name": "car.speed_kmh", "data": derived, "metadata": {"unit": "km/h"}},
|
|
82
|
+
], overwrite=True, concurrency=4)
|
|
83
|
+
signals = dataset.get_signals(signal_ids=ids)
|
|
84
|
+
```
|
|
85
|
+
|
|
55
86
|
#### Upload large files
|
|
56
87
|
|
|
57
88
|
`stream.push_file(...)` starts an ingestion and lets the Marple DB API choose the best upload mode. Depending on the deployment and file size, the SDK can upload through the API server, upload directly to Azure Blob Storage, use a single presigned URL, or split the file into multipart uploads.
|
|
@@ -138,6 +169,9 @@ if len(datasets) > 0:
|
|
|
138
169
|
- **List streams**: `db.get_streams()`
|
|
139
170
|
- **List datasets in a stream**: `stream.get_datasets()`
|
|
140
171
|
- **Upload a file to a file-stream**: `stream.push_file(file_path, metadata={...}, concurrency=4)`
|
|
172
|
+
- **Add signals to a dataset**: `dataset.add_signal(name, data, ...)` / `dataset.add_signals([...])` — data matches `LAKE_ARROW_SCHEMA` (`time` + `value` and/or `value_text`)
|
|
173
|
+
- **Wait until a signal is available**: `signal.wait_until_available(timeout=60)`
|
|
174
|
+
- **Fetch signals by ID**: `dataset.get_signals(signal_ids=[...], refresh=False)`
|
|
141
175
|
- **Wait for a dataset to import**: `dataset.wait_for_import(timeout=60)`
|
|
142
176
|
- **Download original uploaded file**: `dataset.download(destination_folder=".")`
|
|
143
177
|
- **Download parquet for a signal**: `dataset.get_signal(signal_name).download(destination_folder=".")`
|