marpledata 3.6.0.dev2__tar.gz → 3.7.0__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.6.0.dev2 → marpledata-3.7.0}/CHANGELOG.md +11 -3
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/PKG-INFO +5 -1
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/README.md +4 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/getting-started.rst +1 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/tutorials.rst +3 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/example.py +2 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/pyproject.toml +1 -1
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/__init__.py +1 -1
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/__init__.py +11 -3
- marpledata-3.7.0/src/marple/db/activity.py +28 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/dataset.py +24 -1
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/datastream.py +7 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/script.py +8 -2
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/signal.py +2 -0
- marpledata-3.7.0/tests/test_activity.py +52 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_db.py +9 -5
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_signal_upload.py +15 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/uv.lock +1 -1
- marpledata-3.6.0.dev2/.uv-cache/.gitignore +0 -1
- marpledata-3.6.0.dev2/.uv-cache/.lock +0 -0
- marpledata-3.6.0.dev2/.uv-cache/CACHEDIR.TAG +0 -1
- marpledata-3.6.0.dev2/.uv-cache/interpreter-v4/c2c2931c8a99aae1/588e1e7c128e2872.msgpack +0 -0
- marpledata-3.6.0.dev2/.uv-cache/sdists-v9/.gitignore +0 -0
- marpledata-3.6.0.dev2/docs/api/marple.Insight.rst +0 -33
- marpledata-3.6.0.dev2/docs/api/marple.db.DB.rst +0 -60
- marpledata-3.6.0.dev2/docs/api/marple.db.DataStream.rst +0 -55
- marpledata-3.6.0.dev2/docs/api/marple.db.Dataset.rst +0 -67
- marpledata-3.6.0.dev2/docs/api/marple.db.DatasetList.rst +0 -40
- marpledata-3.6.0.dev2/docs/api/marple.db.LAKE_ARROW_SCHEMA.rst +0 -6
- marpledata-3.6.0.dev2/docs/api/marple.db.SCHEMA.rst +0 -6
- marpledata-3.6.0.dev2/docs/api/marple.db.SandboxJob.rst +0 -43
- marpledata-3.6.0.dev2/docs/api/marple.db.SandboxJobStatus.rst +0 -28
- marpledata-3.6.0.dev2/docs/api/marple.db.Script.rst +0 -41
- marpledata-3.6.0.dev2/docs/api/marple.db.ScriptVersion.rst +0 -21
- marpledata-3.6.0.dev2/docs/api/marple.db.Signal.rst +0 -47
- marpledata-3.6.0.dev2/docs/api/marple.db.SignalUpload.rst +0 -31
- marpledata-3.6.0.dev2/docs/api/marple.db.SignalsAlreadyExistError.rst +0 -6
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/.flake8 +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/.gitignore +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/.python-version +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/AGENTS.md +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/CONTRIBUTING.md +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/LICENSE +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/RELEASING.md +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/DEPLOYMENT.md +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/_static/custom.css +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/_static/favicon.png +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/_static/logo.png +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/api/db.rst +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/api/insight.rst +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/api.rst +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/conf.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/docs/index.rst +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/examples_race.csv +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/pytest.xml +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/constants.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/signal_upload.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/db/sql.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/insight.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/py.typed +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/src/marple/utils.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/conftest.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/support.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_insight.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_reliability.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_scripts.py +0 -0
- {marpledata-3.6.0.dev2 → marpledata-3.7.0}/tests/test_sql.py +0 -0
|
@@ -5,7 +5,14 @@ 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
|
-
## [
|
|
8
|
+
## [3.7.0] - 2026-09-28
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Clarify docs to use add_signals() for bulk adding signals
|
|
13
|
+
- `Dataset.add_signal` and `Dataset.add_signals` can upload onto a dataset in `POSTPROCESSING_FAILED`
|
|
14
|
+
|
|
15
|
+
## [3.6.0] - 2026-09-04
|
|
9
16
|
|
|
10
17
|
### Changed
|
|
11
18
|
|
|
@@ -20,8 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
27
|
- `Dataset.run` / `DB.run_script` to execute a stored processing script against a dataset via a server-side sandbox job.
|
|
21
28
|
- `DataStream.scripts`, `DataStream.update`, and `DataStream.rerun_processing` (`DB.rerun_processing`) to edit a stream and set the script pipeline
|
|
22
29
|
- `Dataset.rerun_processing` and `Dataset.get_debug_messages`.
|
|
23
|
-
- `DB.delete_signals`, `Dataset.delete_signal` / `Dataset.delete_signals`, and `Signal.delete` to remove signals from a dataset.
|
|
24
|
-
- `Dataset.reingest` to reingest a dataset from its original uploaded file, with optional `plugin_args`.
|
|
30
|
+
- `DB.delete_signals`, `Dataset.delete_signal` / `Dataset.delete_signals`, and `Signal.delete` to remove signals from a dataset.
|
|
31
|
+
- `Dataset.reingest` to reingest a dataset from its original uploaded file, with optional `plugin_args`.
|
|
32
|
+
- `logger.debug` lines on SDK mutations (`add_signal`, `update_metadata`, …), off by default. Call `db.verbose()` to print them.
|
|
25
33
|
|
|
26
34
|
### Fixed
|
|
27
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: marpledata
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
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/
|
|
@@ -78,6 +78,7 @@ API_TOKEN = "<your api token>"
|
|
|
78
78
|
API_URL = "https://db.marpledata.com/api/v1" # optional if using the default SaaS
|
|
79
79
|
|
|
80
80
|
db = DB(API_TOKEN, API_URL)
|
|
81
|
+
db.verbose() # print SDK mutation activity (push_file, add_signal, …) to stdout
|
|
81
82
|
|
|
82
83
|
db.check_connection()
|
|
83
84
|
|
|
@@ -98,6 +99,8 @@ a conflict without overwrite raises `SignalsAlreadyExistError`.
|
|
|
98
99
|
A Series, or a DataFrame without a `time` column, takes its times from a `DatetimeIndex` or
|
|
99
100
|
`TimedeltaIndex`. Indexed DataFrames must still have a `value` and/or `value_text` column.
|
|
100
101
|
|
|
102
|
+
Warning: for performance reasons, prefer adding signals in bulk using `add_signals` over multiple usages of `add_signal`.
|
|
103
|
+
|
|
101
104
|
```python
|
|
102
105
|
# Single signal: wait until available before reading
|
|
103
106
|
speed = dataset.get_signal("car.speed").get_data()
|
|
@@ -127,6 +130,7 @@ dataset.add_signal("car.custom", samples)
|
|
|
127
130
|
#### Processing scripts
|
|
128
131
|
|
|
129
132
|
Write a `process(dataset)` function, store it, and try it on any imported dataset. This runs on the server and writes to that dataset.
|
|
133
|
+
Warning: for performance reasons, prefer adding signals in bulk using `add_signals` over multiple usages of `add_signal`.
|
|
130
134
|
|
|
131
135
|
```python
|
|
132
136
|
source = """
|
|
@@ -43,6 +43,7 @@ API_TOKEN = "<your api token>"
|
|
|
43
43
|
API_URL = "https://db.marpledata.com/api/v1" # optional if using the default SaaS
|
|
44
44
|
|
|
45
45
|
db = DB(API_TOKEN, API_URL)
|
|
46
|
+
db.verbose() # print SDK mutation activity (push_file, add_signal, …) to stdout
|
|
46
47
|
|
|
47
48
|
db.check_connection()
|
|
48
49
|
|
|
@@ -63,6 +64,8 @@ a conflict without overwrite raises `SignalsAlreadyExistError`.
|
|
|
63
64
|
A Series, or a DataFrame without a `time` column, takes its times from a `DatetimeIndex` or
|
|
64
65
|
`TimedeltaIndex`. Indexed DataFrames must still have a `value` and/or `value_text` column.
|
|
65
66
|
|
|
67
|
+
Warning: for performance reasons, prefer adding signals in bulk using `add_signals` over multiple usages of `add_signal`.
|
|
68
|
+
|
|
66
69
|
```python
|
|
67
70
|
# Single signal: wait until available before reading
|
|
68
71
|
speed = dataset.get_signal("car.speed").get_data()
|
|
@@ -92,6 +95,7 @@ dataset.add_signal("car.custom", samples)
|
|
|
92
95
|
#### Processing scripts
|
|
93
96
|
|
|
94
97
|
Write a `process(dataset)` function, store it, and try it on any imported dataset. This runs on the server and writes to that dataset.
|
|
98
|
+
Warning: for performance reasons, prefer adding signals in bulk using `add_signals` over multiple usages of `add_signal`.
|
|
95
99
|
|
|
96
100
|
```python
|
|
97
101
|
source = """
|
|
@@ -40,6 +40,7 @@ After import, you can add derived signals with
|
|
|
40
40
|
``dataset.add_signal(...)`` / ``dataset.add_signals([...])``. For custom
|
|
41
41
|
ingest without file parsing, use ``stream.add_dataset(...)`` then
|
|
42
42
|
``add_signal``. See :doc:`tutorials` for a full example.
|
|
43
|
+
Warning: for performance reasons, prefer adding signals in bulk using ``add_signals`` over multiple usages of ``add_signal``.
|
|
43
44
|
|
|
44
45
|
``stream.push_file(...)`` starts an ingestion and lets the Marple DB API choose
|
|
45
46
|
the best upload mode for the deployment and file size. For large files, use a
|
|
@@ -46,6 +46,8 @@ Add signals after import, or start with an empty dataset using
|
|
|
46
46
|
A Series, or a DataFrame without a ``time`` column, takes its times from a
|
|
47
47
|
``DatetimeIndex`` or ``TimedeltaIndex``.
|
|
48
48
|
|
|
49
|
+
Warning: for performance reasons, prefer adding signals in bulk using ``add_signals`` over multiple usages of ``add_signal``.
|
|
50
|
+
|
|
49
51
|
.. code-block:: python
|
|
50
52
|
|
|
51
53
|
speed = dataset.get_signal("car.speed").get_data()
|
|
@@ -83,6 +85,7 @@ Processing scripts
|
|
|
83
85
|
|
|
84
86
|
Write a ``process(dataset)`` function, store it, and try it on any imported dataset.
|
|
85
87
|
This runs on the server and writes to that dataset.
|
|
88
|
+
Warning: for performance reasons, prefer adding signals in bulk using ``add_signals`` over multiple usages of ``add_signal``.
|
|
86
89
|
|
|
87
90
|
.. code-block:: python
|
|
88
91
|
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
4
|
import dotenv
|
|
5
|
+
|
|
5
6
|
from src.marple.db import DB, Dataset
|
|
6
7
|
|
|
7
8
|
dotenv.load_dotenv()
|
|
@@ -11,6 +12,7 @@ if api_token is None:
|
|
|
11
12
|
|
|
12
13
|
url = os.getenv("MDB_URL")
|
|
13
14
|
db = DB(api_token, url)
|
|
15
|
+
db.verbose() # print SDK mutation activity (push_file, add_signal, …) to stdout
|
|
14
16
|
db.check_connection()
|
|
15
17
|
|
|
16
18
|
stream_name = "CSV Stream"
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from functools import wraps
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, TextIO
|
|
5
5
|
|
|
6
6
|
import pandas as pd
|
|
7
7
|
from pydantic import ValidationError
|
|
8
8
|
from requests import Response
|
|
9
9
|
from requests.exceptions import ConnectionError
|
|
10
10
|
|
|
11
|
-
from marple.db import sql
|
|
11
|
+
from marple.db import activity, sql
|
|
12
|
+
from marple.db.activity import logger
|
|
12
13
|
from marple.db.constants import LAKE_ARROW_SCHEMA as _LAKE_ARROW_SCHEMA
|
|
13
14
|
from marple.db.constants import SAAS_URL
|
|
14
15
|
from marple.db.constants import SCHEMA as _SCHEMA
|
|
@@ -156,6 +157,10 @@ class DB:
|
|
|
156
157
|
self._refresh_stream_cache(r)
|
|
157
158
|
return True
|
|
158
159
|
|
|
160
|
+
def verbose(self, enabled: bool = True, file: TextIO | None = None) -> None:
|
|
161
|
+
"""Turn SDK mutation activity logging on or off (stdout by default)."""
|
|
162
|
+
activity.verbose(enabled, file)
|
|
163
|
+
|
|
159
164
|
# Stream functions #
|
|
160
165
|
|
|
161
166
|
def create_stream(
|
|
@@ -313,7 +318,9 @@ class DB:
|
|
|
313
318
|
"script": Script.resolve_source(script),
|
|
314
319
|
},
|
|
315
320
|
)
|
|
316
|
-
|
|
321
|
+
created = Script(client=self.client, **validate_response(r, "Create script failed"))
|
|
322
|
+
logger.debug(f"Created script {name}")
|
|
323
|
+
return created
|
|
317
324
|
|
|
318
325
|
def delete_script(self, script_id: int) -> None:
|
|
319
326
|
"""
|
|
@@ -324,6 +331,7 @@ class DB:
|
|
|
324
331
|
"""
|
|
325
332
|
r = self.delete(f"/script/{script_id}")
|
|
326
333
|
validate_response(r, "Delete script failed")
|
|
334
|
+
logger.debug(f"Deleted script {script_id}")
|
|
327
335
|
|
|
328
336
|
def _refresh_stream_cache(self, r: Response | None = None) -> None:
|
|
329
337
|
if r is None:
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
from typing import TextIO
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger("marple.sdk")
|
|
6
|
+
logger.addHandler(logging.NullHandler())
|
|
7
|
+
logger.propagate = False
|
|
8
|
+
|
|
9
|
+
_handler: logging.Handler | None = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def verbose(enabled: bool = True, file: TextIO | None = None) -> None:
|
|
13
|
+
"""Turn SDK mutation activity logging on or off (stdout by default)."""
|
|
14
|
+
global _handler
|
|
15
|
+
if enabled:
|
|
16
|
+
logger.setLevel(logging.DEBUG)
|
|
17
|
+
if _handler is not None:
|
|
18
|
+
return
|
|
19
|
+
_handler = logging.StreamHandler(file or sys.stdout)
|
|
20
|
+
_handler.setFormatter(logging.Formatter("%(message)s"))
|
|
21
|
+
logger.addHandler(_handler)
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
if _handler is not None:
|
|
25
|
+
logger.removeHandler(_handler)
|
|
26
|
+
_handler.close()
|
|
27
|
+
_handler = None
|
|
28
|
+
logger.setLevel(logging.NOTSET)
|
|
@@ -15,6 +15,7 @@ import pyarrow.parquet as pq
|
|
|
15
15
|
from pandas._typing import AggFuncType, Frequency
|
|
16
16
|
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, ValidationError
|
|
17
17
|
|
|
18
|
+
from marple.db.activity import logger
|
|
18
19
|
from marple.db.constants import (
|
|
19
20
|
COL_SIG,
|
|
20
21
|
COL_TIME,
|
|
@@ -55,6 +56,14 @@ STABLE_STATUSES = [
|
|
|
55
56
|
]
|
|
56
57
|
BUSY_STATUSES = [v for v in ImportStatus if v not in STABLE_STATUSES]
|
|
57
58
|
|
|
59
|
+
# A processing script may write in these statuses. POSTPROCESSING is in-flight;
|
|
60
|
+
# only the stable members can start a run.
|
|
61
|
+
SCRIPTABLE_STATUSES = [
|
|
62
|
+
ImportStatus.FINISHED,
|
|
63
|
+
ImportStatus.POSTPROCESSING,
|
|
64
|
+
ImportStatus.POSTPROCESSING_FAILED,
|
|
65
|
+
]
|
|
66
|
+
|
|
58
67
|
GET_SIGNALS_CHUNK_SIZE = 200
|
|
59
68
|
|
|
60
69
|
|
|
@@ -333,6 +342,8 @@ class Dataset(BaseModel):
|
|
|
333
342
|
new_metadata = metadata if overwrite else {**self.metadata, **metadata}
|
|
334
343
|
r = self._client.post(f"/stream/{self.datastream_id}/dataset/{self.id}/metadata", json=new_metadata)
|
|
335
344
|
validate_response(r, "Update metadata failed")
|
|
345
|
+
suffix = " (overwrite=True)" if overwrite else ""
|
|
346
|
+
logger.debug(f"Updated dataset metadata: {metadata}{suffix}")
|
|
336
347
|
return self.fetch(self._client, self.id)
|
|
337
348
|
|
|
338
349
|
def upsert_signals(self, signals: list[dict]) -> None:
|
|
@@ -347,6 +358,7 @@ class Dataset(BaseModel):
|
|
|
347
358
|
"""
|
|
348
359
|
r = self._client.post(f"/stream/{self.datastream_id}/dataset/{self.id}/signals", json=signals)
|
|
349
360
|
validate_response(r, "Upsert signals failed")
|
|
361
|
+
logger.debug(f"Upserted metadata for {len(signals)} signals from dataset {self.path}")
|
|
350
362
|
|
|
351
363
|
def add_signal(
|
|
352
364
|
self,
|
|
@@ -369,6 +381,8 @@ class Dataset(BaseModel):
|
|
|
369
381
|
Returns the new signal immediately after upload completes. Call
|
|
370
382
|
:meth:`Signal.wait_until_available` to wait until the signal is available.
|
|
371
383
|
|
|
384
|
+
Warning: for performance reasons, prefer adding signals in bulk using ``add_signals`` over multiple usages of ``add_signal``.
|
|
385
|
+
|
|
372
386
|
Args:
|
|
373
387
|
name: Signal name.
|
|
374
388
|
data: Signal samples (DataFrame, Series, Arrow table, or parquet path).
|
|
@@ -408,13 +422,15 @@ class Dataset(BaseModel):
|
|
|
408
422
|
return []
|
|
409
423
|
if len(signals) > MAX_SIGNALS_PER_ADD:
|
|
410
424
|
raise ValueError(f"Provide at most {MAX_SIGNALS_PER_ADD} signals per call")
|
|
411
|
-
if self.import_status not in
|
|
425
|
+
if self.import_status not in SCRIPTABLE_STATUSES:
|
|
412
426
|
raise ValueError(f"Dataset {self.id} is not in a writable state (status: {self.import_status})")
|
|
413
427
|
|
|
414
428
|
signal_ids = run_signal_uploads(self, signals, overwrite=overwrite, concurrency=concurrency)
|
|
415
429
|
for signal_id in signal_ids: # Invalidate new signals from cache
|
|
416
430
|
if signal_id in self._signals:
|
|
417
431
|
del self._signals[signal_id]
|
|
432
|
+
names = [item.name if isinstance(item, SignalUpload) else item["name"] for item in signals]
|
|
433
|
+
logger.debug(f"Added {', '.join(names)} to {self.path} (overwrite={overwrite})")
|
|
418
434
|
return signal_ids
|
|
419
435
|
|
|
420
436
|
def append(
|
|
@@ -461,6 +477,7 @@ class Dataset(BaseModel):
|
|
|
461
477
|
timeout=self._client.STORAGE_TIMEOUT,
|
|
462
478
|
)
|
|
463
479
|
validate_response(r, "Append data failed")
|
|
480
|
+
logger.debug(f"Appended {len(data)} rows to realtime dataset {self.path}")
|
|
464
481
|
|
|
465
482
|
def cool(self) -> "Dataset":
|
|
466
483
|
"""
|
|
@@ -481,6 +498,7 @@ class Dataset(BaseModel):
|
|
|
481
498
|
|
|
482
499
|
r = self._client.post(f"/stream/{self.datastream_id}/dataset/{self.id}/cool")
|
|
483
500
|
validate_response(r, "Cool dataset failed")
|
|
501
|
+
logger.debug(f"Started cooling dataset {self.path}")
|
|
484
502
|
return self.fetch(self._client, self.id)
|
|
485
503
|
|
|
486
504
|
def reingest(self, plugin_args: str | None = None) -> "Dataset":
|
|
@@ -500,6 +518,7 @@ class Dataset(BaseModel):
|
|
|
500
518
|
kwargs = {} if plugin_args is None else {"json": {"plugin_args": plugin_args}}
|
|
501
519
|
r = self._client.post(f"/stream/{self.datastream_id}/dataset/{self.id}/reingest", **kwargs)
|
|
502
520
|
validate_response(r, "Reingest dataset failed")
|
|
521
|
+
logger.debug(f"Started reingest of dataset {self.path}")
|
|
503
522
|
return self.fetch(self._client, self.id)
|
|
504
523
|
|
|
505
524
|
def wait_for_import(self, timeout: float = 60, force_fetch: bool = False) -> "Dataset":
|
|
@@ -551,6 +570,7 @@ class Dataset(BaseModel):
|
|
|
551
570
|
validate_response(r, "Delete signals failed")
|
|
552
571
|
for signal_id in to_delete:
|
|
553
572
|
self._signals.pop(signal_id, None)
|
|
573
|
+
logger.debug(f"Deleted {len(to_delete)} signals from dataset {self.path}")
|
|
554
574
|
|
|
555
575
|
def delete(self) -> None:
|
|
556
576
|
"""
|
|
@@ -561,6 +581,7 @@ class Dataset(BaseModel):
|
|
|
561
581
|
"""
|
|
562
582
|
r = self._client.post(f"/stream/{self.datastream_id}/dataset/{self.id}/delete")
|
|
563
583
|
validate_response(r, "Delete dataset failed")
|
|
584
|
+
logger.debug(f"Deleted dataset {self.path}")
|
|
564
585
|
|
|
565
586
|
def rerun_processing(self) -> "Dataset":
|
|
566
587
|
"""
|
|
@@ -574,6 +595,7 @@ class Dataset(BaseModel):
|
|
|
574
595
|
json=[self.id],
|
|
575
596
|
)
|
|
576
597
|
validate_response(r, "Rerun processing failed")
|
|
598
|
+
logger.debug(f"Reran processing for dataset {self.path}")
|
|
577
599
|
return self.fetch(self._client, self.id)
|
|
578
600
|
|
|
579
601
|
def get_debug_messages(self) -> list[str]:
|
|
@@ -641,6 +663,7 @@ class Dataset(BaseModel):
|
|
|
641
663
|
if job.status == SandboxJobStatus.FAILED:
|
|
642
664
|
raise RuntimeError(f"Script failed (job {job.id}): {job.log or 'no log'}")
|
|
643
665
|
|
|
666
|
+
logger.debug(f"Ran script {script_id} on dataset {self.path}")
|
|
644
667
|
return self.fetch(self._client, self.id)
|
|
645
668
|
|
|
646
669
|
|
|
@@ -7,6 +7,7 @@ from typing import Any, Literal, Optional
|
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field, PrivateAttr, field_validator
|
|
9
9
|
|
|
10
|
+
from marple.db.activity import logger
|
|
10
11
|
from marple.db.dataset import Dataset, DatasetList
|
|
11
12
|
from marple.utils import (
|
|
12
13
|
OMITTED,
|
|
@@ -123,6 +124,7 @@ class DataStream(BaseModel):
|
|
|
123
124
|
json={"dataset_name": dataset_name, "metadata": metadata or {}},
|
|
124
125
|
)
|
|
125
126
|
r_json = validate_response(r, "Add dataset failed")
|
|
127
|
+
logger.debug(f"Added dataset {dataset_name}")
|
|
126
128
|
return self.get_dataset(r_json["dataset_id"])
|
|
127
129
|
|
|
128
130
|
def push_file(
|
|
@@ -171,6 +173,7 @@ class DataStream(BaseModel):
|
|
|
171
173
|
self._abort_upload(init.ingestion_id, str(exc) or type(exc).__name__)
|
|
172
174
|
raise
|
|
173
175
|
|
|
176
|
+
logger.debug(f"Pushed file {file_name or path.name}")
|
|
174
177
|
return self.get_dataset(init.dataset_id)
|
|
175
178
|
|
|
176
179
|
def _init_ingestion(
|
|
@@ -337,6 +340,7 @@ class DataStream(BaseModel):
|
|
|
337
340
|
|
|
338
341
|
r = self._client.post(f"/stream/update/{self.id}", json=payload)
|
|
339
342
|
validate_response(r, "Update stream failed")
|
|
343
|
+
logger.debug(f"Updated stream {self.name}: {payload}")
|
|
340
344
|
return self.fetch(self._client, self.id)
|
|
341
345
|
|
|
342
346
|
def rerun_processing(self, dataset_ids: Sequence[int] | None = None) -> None:
|
|
@@ -354,6 +358,8 @@ class DataStream(BaseModel):
|
|
|
354
358
|
raise ValueError("rerun_processing requires at least one dataset id")
|
|
355
359
|
r = self._client.post(f"/stream/{self.id}/processing/datasets", json=ids)
|
|
356
360
|
validate_response(r, "Rerun processing failed")
|
|
361
|
+
target = f"{len(dataset_ids)} datasets" if dataset_ids is not None else "all datasets"
|
|
362
|
+
logger.debug(f"Reran processing for stream {self.name} ({target})")
|
|
357
363
|
|
|
358
364
|
def delete(self) -> None:
|
|
359
365
|
"""
|
|
@@ -364,3 +370,4 @@ class DataStream(BaseModel):
|
|
|
364
370
|
"""
|
|
365
371
|
r = self._client.post(f"/stream/{self.id}/delete")
|
|
366
372
|
validate_response(r, "Delete stream failed")
|
|
373
|
+
logger.debug(f"Deleted stream {self.name}")
|
|
@@ -5,6 +5,7 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, Field, PrivateAttr, field_validator
|
|
7
7
|
|
|
8
|
+
from marple.db.activity import logger
|
|
8
9
|
from marple.utils import OMITTED, DBClient, Omitted, validate_response
|
|
9
10
|
|
|
10
11
|
|
|
@@ -132,12 +133,16 @@ class Script(BaseModel):
|
|
|
132
133
|
payload["script"] = self.resolve_source(script)
|
|
133
134
|
|
|
134
135
|
r = self._client.post(f"/script/{self.id}", json=payload)
|
|
135
|
-
|
|
136
|
+
updated = Script(client=self._client, **validate_response(r, "Update script failed"))
|
|
137
|
+
logger.debug(f"Updated script {self.name}: {payload}")
|
|
138
|
+
return updated
|
|
136
139
|
|
|
137
140
|
def duplicate(self) -> "Script":
|
|
138
141
|
"""Create a copy of this script, including version history and stream attachments."""
|
|
139
142
|
r = self._client.post(f"/script/{self.id}/duplicate")
|
|
140
|
-
|
|
143
|
+
copy = Script(client=self._client, **validate_response(r, "Duplicate script failed"))
|
|
144
|
+
logger.debug(f"Duplicated script {self.name}")
|
|
145
|
+
return copy
|
|
141
146
|
|
|
142
147
|
def delete(self) -> None:
|
|
143
148
|
"""
|
|
@@ -148,6 +153,7 @@ class Script(BaseModel):
|
|
|
148
153
|
"""
|
|
149
154
|
r = self._client.delete(f"/script/{self.id}")
|
|
150
155
|
validate_response(r, "Delete script failed")
|
|
156
|
+
logger.debug(f"Deleted script {self.name}")
|
|
151
157
|
|
|
152
158
|
@staticmethod
|
|
153
159
|
def resolve_source(script: Path | str) -> str:
|
|
@@ -7,6 +7,7 @@ from typing import Literal
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
from pydantic import BaseModel, PrivateAttr
|
|
9
9
|
|
|
10
|
+
from marple.db.activity import logger
|
|
10
11
|
from marple.utils import DBClient, validate_response
|
|
11
12
|
|
|
12
13
|
|
|
@@ -150,3 +151,4 @@ class Signal(BaseModel):
|
|
|
150
151
|
json={"signal_ids": [self.id]},
|
|
151
152
|
)
|
|
152
153
|
validate_response(r, "Delete signal failed")
|
|
154
|
+
logger.debug(f"Deleted signal {self.name}")
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from io import StringIO
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from marple.db import DB
|
|
7
|
+
from marple.db.activity import logger, verbose
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(autouse=True)
|
|
11
|
+
def _reset_verbose():
|
|
12
|
+
verbose(False)
|
|
13
|
+
yield
|
|
14
|
+
verbose(False)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_verbose_writes_debug_to_file():
|
|
18
|
+
buf = StringIO()
|
|
19
|
+
verbose(True, buf)
|
|
20
|
+
logger.debug("hello activity")
|
|
21
|
+
assert "hello activity" in buf.getvalue()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_verbose_true_is_idempotent():
|
|
25
|
+
buf = StringIO()
|
|
26
|
+
verbose(True, buf)
|
|
27
|
+
verbose(True, buf)
|
|
28
|
+
logger.debug("once")
|
|
29
|
+
assert buf.getvalue().count("once") == 1
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_verbose_false_stops_output():
|
|
33
|
+
buf = StringIO()
|
|
34
|
+
verbose(True, buf)
|
|
35
|
+
logger.debug("before")
|
|
36
|
+
verbose(False)
|
|
37
|
+
logger.debug("after")
|
|
38
|
+
assert "before" in buf.getvalue()
|
|
39
|
+
assert "after" not in buf.getvalue()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_db_verbose_delegates():
|
|
43
|
+
with patch.object(DB, "check_connection", return_value=True):
|
|
44
|
+
with patch("marple.utils.DBClient"):
|
|
45
|
+
db = DB("token")
|
|
46
|
+
buf = StringIO()
|
|
47
|
+
db.verbose(True, buf)
|
|
48
|
+
logger.debug("via db")
|
|
49
|
+
assert "via db" in buf.getvalue()
|
|
50
|
+
db.verbose(False)
|
|
51
|
+
logger.debug("off")
|
|
52
|
+
assert "off" not in buf.getvalue()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import re
|
|
3
|
+
from datetime import datetime
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from tempfile import TemporaryDirectory
|
|
5
6
|
from typing import Literal
|
|
@@ -12,7 +13,7 @@ from requests import HTTPError
|
|
|
12
13
|
import marple
|
|
13
14
|
from marple import DB
|
|
14
15
|
from marple.db import Dataset, DatasetList, DataStream
|
|
15
|
-
from support import EXAMPLE_CSV, isolated_stream, unique_name
|
|
16
|
+
from support import EXAMPLE_CSV, ingest_dataset, isolated_stream, unique_name
|
|
16
17
|
|
|
17
18
|
pytestmark = pytest.mark.integration
|
|
18
19
|
|
|
@@ -313,13 +314,16 @@ def test_push_file_plugin_args(example_stream: DataStream) -> None:
|
|
|
313
314
|
assert dataset.plugin_args == "--use-index"
|
|
314
315
|
|
|
315
316
|
|
|
316
|
-
def test_dataset_reingest(
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
def test_dataset_reingest(example_stream: DataStream) -> None:
|
|
318
|
+
# Separate dataset on the shared session stream so reingest does not mutate
|
|
319
|
+
# example_dataset (Insight export and other shared consumers).
|
|
320
|
+
dataset = ingest_dataset(example_stream, metadata={"test": "reingest"})
|
|
321
|
+
reingested = dataset.reingest().wait_for_import(timeout=180)
|
|
322
|
+
assert reingested.id == dataset.id
|
|
319
323
|
assert reingested.import_status == "FINISHED"
|
|
320
324
|
|
|
321
325
|
with_args = reingested.reingest(plugin_args="--use-index").wait_for_import(timeout=180)
|
|
322
|
-
assert with_args.id ==
|
|
326
|
+
assert with_args.id == dataset.id
|
|
323
327
|
assert with_args.import_status == "FINISHED"
|
|
324
328
|
assert with_args.plugin_args == "--use-index"
|
|
325
329
|
|
|
@@ -23,6 +23,7 @@ from marple.db.constants import (
|
|
|
23
23
|
MAX_SIGNALS_PER_ADD,
|
|
24
24
|
ROW_GROUP_SIZE,
|
|
25
25
|
)
|
|
26
|
+
from marple.db.dataset import SCRIPTABLE_STATUSES
|
|
26
27
|
from marple.db.signal_upload import (
|
|
27
28
|
ParquetUploadMetadata,
|
|
28
29
|
PresignedParquetFile,
|
|
@@ -328,10 +329,24 @@ def test_add_signals_rejects_too_many() -> None:
|
|
|
328
329
|
Dataset.add_signals(dataset, too_many)
|
|
329
330
|
|
|
330
331
|
|
|
332
|
+
def test_add_signals_allows_scriptable_statuses(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
333
|
+
monkeypatch.setattr("marple.db.dataset.run_signal_uploads", lambda *_args, **_kwargs: [1])
|
|
334
|
+
for status in SCRIPTABLE_STATUSES:
|
|
335
|
+
dataset = cast(Dataset, SimpleNamespace(id=1, path="demo", import_status=status, _signals={}))
|
|
336
|
+
assert Dataset.add_signals(dataset, [{"name": "s", "data": object()}]) == [1]
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def test_add_signals_rejects_status_outside_scriptable() -> None:
|
|
340
|
+
dataset = cast(Dataset, SimpleNamespace(id=1, import_status="LIVE"))
|
|
341
|
+
with pytest.raises(ValueError, match="not in a writable state"):
|
|
342
|
+
Dataset.add_signals(dataset, [{"name": "s", "data": object()}])
|
|
343
|
+
|
|
344
|
+
|
|
331
345
|
def test_delete_signals_posts_and_clears_cache() -> None:
|
|
332
346
|
client = MagicMock()
|
|
333
347
|
client.post.return_value = SimpleNamespace(status_code=200, json=lambda: {"status": "success"})
|
|
334
348
|
dataset = SimpleNamespace(
|
|
349
|
+
path="dataset/10",
|
|
335
350
|
id=10,
|
|
336
351
|
datastream_id=5,
|
|
337
352
|
n_signals=3,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Signature: 8a477f597d28d172789f06886806bc55
|
|
Binary file
|
|
File without changes
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
marple.Insight
|
|
2
|
-
==============
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple
|
|
5
|
-
|
|
6
|
-
.. autoclass:: Insight
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~Insight.check_connection
|
|
17
|
-
~Insight.delete
|
|
18
|
-
~Insight.export_data
|
|
19
|
-
~Insight.export_data_mdb
|
|
20
|
-
~Insight.get
|
|
21
|
-
~Insight.get_dataset
|
|
22
|
-
~Insight.get_dataset_mdb
|
|
23
|
-
~Insight.get_datasets
|
|
24
|
-
~Insight.get_signals
|
|
25
|
-
~Insight.get_signals_mdb
|
|
26
|
-
~Insight.patch
|
|
27
|
-
~Insight.post
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
marple.db.DB
|
|
2
|
-
============
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: DB
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~DB.add_dataset
|
|
17
|
-
~DB.check_connection
|
|
18
|
-
~DB.connect_trino
|
|
19
|
-
~DB.create_script
|
|
20
|
-
~DB.create_stream
|
|
21
|
-
~DB.dataset_append
|
|
22
|
-
~DB.dataset_cool
|
|
23
|
-
~DB.delete
|
|
24
|
-
~DB.delete_dataset
|
|
25
|
-
~DB.delete_script
|
|
26
|
-
~DB.delete_stream
|
|
27
|
-
~DB.download_original
|
|
28
|
-
~DB.download_signal
|
|
29
|
-
~DB.get
|
|
30
|
-
~DB.get_dataset
|
|
31
|
-
~DB.get_datasets
|
|
32
|
-
~DB.get_script
|
|
33
|
-
~DB.get_scripts
|
|
34
|
-
~DB.get_signal
|
|
35
|
-
~DB.get_signals
|
|
36
|
-
~DB.get_status
|
|
37
|
-
~DB.get_stream
|
|
38
|
-
~DB.get_streams
|
|
39
|
-
~DB.patch
|
|
40
|
-
~DB.post
|
|
41
|
-
~DB.push_file
|
|
42
|
-
~DB.query
|
|
43
|
-
~DB.rerun_processing
|
|
44
|
-
~DB.run_script
|
|
45
|
-
~DB.update_metadata
|
|
46
|
-
~DB.update_stream
|
|
47
|
-
~DB.upsert_signals
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.. rubric:: Attributes
|
|
54
|
-
|
|
55
|
-
.. autosummary::
|
|
56
|
-
|
|
57
|
-
~DB.trino_info
|
|
58
|
-
~DB.client
|
|
59
|
-
|
|
60
|
-
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
marple.db.DataStream
|
|
2
|
-
====================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: DataStream
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~DataStream.add_dataset
|
|
17
|
-
~DataStream.delete
|
|
18
|
-
~DataStream.fetch
|
|
19
|
-
~DataStream.get_dataset
|
|
20
|
-
~DataStream.get_datasets
|
|
21
|
-
~DataStream.push_file
|
|
22
|
-
~DataStream.refresh
|
|
23
|
-
~DataStream.rerun_processing
|
|
24
|
-
~DataStream.update
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.. rubric:: Attributes
|
|
31
|
-
|
|
32
|
-
.. autosummary::
|
|
33
|
-
|
|
34
|
-
~DataStream.type
|
|
35
|
-
~DataStream.id
|
|
36
|
-
~DataStream.name
|
|
37
|
-
~DataStream.description
|
|
38
|
-
~DataStream.datapool
|
|
39
|
-
~DataStream.layer_shifts
|
|
40
|
-
~DataStream.version_id
|
|
41
|
-
~DataStream.insight_workspace
|
|
42
|
-
~DataStream.insight_project
|
|
43
|
-
~DataStream.created_at
|
|
44
|
-
~DataStream.last_updated
|
|
45
|
-
~DataStream.last_ingested
|
|
46
|
-
~DataStream.n_datasets
|
|
47
|
-
~DataStream.n_datapoints
|
|
48
|
-
~DataStream.cold_bytes
|
|
49
|
-
~DataStream.hot_bytes
|
|
50
|
-
~DataStream.plugin
|
|
51
|
-
~DataStream.plugin_args
|
|
52
|
-
~DataStream.signal_reduction
|
|
53
|
-
~DataStream.scripts
|
|
54
|
-
|
|
55
|
-
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
marple.db.Dataset
|
|
2
|
-
=================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: Dataset
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~Dataset.add_signal
|
|
17
|
-
~Dataset.add_signals
|
|
18
|
-
~Dataset.append
|
|
19
|
-
~Dataset.cool
|
|
20
|
-
~Dataset.delete
|
|
21
|
-
~Dataset.download
|
|
22
|
-
~Dataset.fetch
|
|
23
|
-
~Dataset.get_data
|
|
24
|
-
~Dataset.get_debug_messages
|
|
25
|
-
~Dataset.get_signal
|
|
26
|
-
~Dataset.get_signals
|
|
27
|
-
~Dataset.reingest
|
|
28
|
-
~Dataset.rerun_processing
|
|
29
|
-
~Dataset.run
|
|
30
|
-
~Dataset.update_metadata
|
|
31
|
-
~Dataset.upsert_signals
|
|
32
|
-
~Dataset.wait_for_import
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.. rubric:: Attributes
|
|
39
|
-
|
|
40
|
-
.. autosummary::
|
|
41
|
-
|
|
42
|
-
~Dataset.id
|
|
43
|
-
~Dataset.datastream_id
|
|
44
|
-
~Dataset.datastream_version
|
|
45
|
-
~Dataset.created_at
|
|
46
|
-
~Dataset.created_by
|
|
47
|
-
~Dataset.import_status
|
|
48
|
-
~Dataset.import_progress
|
|
49
|
-
~Dataset.import_message
|
|
50
|
-
~Dataset.import_time
|
|
51
|
-
~Dataset.path
|
|
52
|
-
~Dataset.metadata
|
|
53
|
-
~Dataset.cold_path
|
|
54
|
-
~Dataset.cold_bytes
|
|
55
|
-
~Dataset.hot_bytes
|
|
56
|
-
~Dataset.backup_path
|
|
57
|
-
~Dataset.backup_size
|
|
58
|
-
~Dataset.plugin
|
|
59
|
-
~Dataset.plugin_args
|
|
60
|
-
~Dataset.n_datapoints
|
|
61
|
-
~Dataset.n_signals
|
|
62
|
-
~Dataset.timestamp_start
|
|
63
|
-
~Dataset.timestamp_stop
|
|
64
|
-
~Dataset.import_speed
|
|
65
|
-
~Dataset.parquet_version
|
|
66
|
-
|
|
67
|
-
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
marple.db.DatasetList
|
|
2
|
-
=====================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: DatasetList
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~DatasetList.append
|
|
17
|
-
~DatasetList.clear
|
|
18
|
-
~DatasetList.count
|
|
19
|
-
~DatasetList.extend
|
|
20
|
-
~DatasetList.from_dicts
|
|
21
|
-
~DatasetList.get_data
|
|
22
|
-
~DatasetList.index
|
|
23
|
-
~DatasetList.insert
|
|
24
|
-
~DatasetList.pop
|
|
25
|
-
~DatasetList.remove
|
|
26
|
-
~DatasetList.reverse
|
|
27
|
-
~DatasetList.sort
|
|
28
|
-
~DatasetList.to_pandas
|
|
29
|
-
~DatasetList.wait_for_import
|
|
30
|
-
~DatasetList.where
|
|
31
|
-
~DatasetList.where_dataset
|
|
32
|
-
~DatasetList.where_imported
|
|
33
|
-
~DatasetList.where_metadata
|
|
34
|
-
~DatasetList.where_signal
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
marple.db.SandboxJob
|
|
2
|
-
====================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: SandboxJob
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.. rubric:: Methods
|
|
14
|
-
|
|
15
|
-
.. autosummary::
|
|
16
|
-
|
|
17
|
-
~SandboxJob.fetch
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.. rubric:: Attributes
|
|
24
|
-
|
|
25
|
-
.. autosummary::
|
|
26
|
-
|
|
27
|
-
~SandboxJob.id
|
|
28
|
-
~SandboxJob.dataset_id
|
|
29
|
-
~SandboxJob.stream_id
|
|
30
|
-
~SandboxJob.script_id
|
|
31
|
-
~SandboxJob.script_version
|
|
32
|
-
~SandboxJob.script_index
|
|
33
|
-
~SandboxJob.ingestion_id
|
|
34
|
-
~SandboxJob.status
|
|
35
|
-
~SandboxJob.batch_job_id
|
|
36
|
-
~SandboxJob.token_id
|
|
37
|
-
~SandboxJob.log
|
|
38
|
-
~SandboxJob.created_by
|
|
39
|
-
~SandboxJob.created_at
|
|
40
|
-
~SandboxJob.started_at
|
|
41
|
-
~SandboxJob.finished_at
|
|
42
|
-
|
|
43
|
-
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
marple.db.SandboxJobStatus
|
|
2
|
-
==========================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: SandboxJobStatus
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. rubric:: Methods
|
|
10
|
-
|
|
11
|
-
.. autosummary::
|
|
12
|
-
|
|
13
|
-
~SandboxJobStatus.is_terminal
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.. rubric:: Members
|
|
20
|
-
|
|
21
|
-
.. autosummary::
|
|
22
|
-
|
|
23
|
-
~SandboxJobStatus.QUEUED
|
|
24
|
-
~SandboxJobStatus.RUNNING
|
|
25
|
-
~SandboxJobStatus.SUCCEEDED
|
|
26
|
-
~SandboxJobStatus.FAILED
|
|
27
|
-
|
|
28
|
-
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
marple.db.Script
|
|
2
|
-
================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: Script
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~Script.delete
|
|
17
|
-
~Script.duplicate
|
|
18
|
-
~Script.fetch
|
|
19
|
-
~Script.refresh
|
|
20
|
-
~Script.update
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.. rubric:: Attributes
|
|
27
|
-
|
|
28
|
-
.. autosummary::
|
|
29
|
-
|
|
30
|
-
~Script.id
|
|
31
|
-
~Script.name
|
|
32
|
-
~Script.description
|
|
33
|
-
~Script.created_at
|
|
34
|
-
~Script.created_by
|
|
35
|
-
~Script.updated_at
|
|
36
|
-
~Script.updated_by
|
|
37
|
-
~Script.streams
|
|
38
|
-
~Script.versions
|
|
39
|
-
~Script.source
|
|
40
|
-
|
|
41
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
marple.db.ScriptVersion
|
|
2
|
-
=======================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: ScriptVersion
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Attributes
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~ScriptVersion.id
|
|
17
|
-
~ScriptVersion.script
|
|
18
|
-
~ScriptVersion.updated_at
|
|
19
|
-
~ScriptVersion.updated_by
|
|
20
|
-
|
|
21
|
-
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
marple.db.Signal
|
|
2
|
-
================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: Signal
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~Signal.cache_parquet
|
|
17
|
-
~Signal.get_data
|
|
18
|
-
~Signal.list_parquet_files
|
|
19
|
-
~Signal.wait_until_available
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.. rubric:: Attributes
|
|
26
|
-
|
|
27
|
-
.. autosummary::
|
|
28
|
-
|
|
29
|
-
~Signal.id
|
|
30
|
-
~Signal.name
|
|
31
|
-
~Signal.unit
|
|
32
|
-
~Signal.description
|
|
33
|
-
~Signal.metadata
|
|
34
|
-
~Signal.storage_status
|
|
35
|
-
~Signal.cold_bytes
|
|
36
|
-
~Signal.hot_bytes
|
|
37
|
-
~Signal.count
|
|
38
|
-
~Signal.stats
|
|
39
|
-
~Signal.count_value
|
|
40
|
-
~Signal.count_text
|
|
41
|
-
~Signal.time_min
|
|
42
|
-
~Signal.time_max
|
|
43
|
-
~Signal.parquet_version
|
|
44
|
-
~Signal.datastream_id
|
|
45
|
-
~Signal.dataset_id
|
|
46
|
-
|
|
47
|
-
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
marple.db.SignalUpload
|
|
2
|
-
======================
|
|
3
|
-
|
|
4
|
-
.. currentmodule:: marple.db
|
|
5
|
-
|
|
6
|
-
.. autoclass:: SignalUpload
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.. automethod:: __init__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.. rubric:: Methods
|
|
13
|
-
|
|
14
|
-
.. autosummary::
|
|
15
|
-
|
|
16
|
-
~SignalUpload.plan_upload
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.. rubric:: Attributes
|
|
23
|
-
|
|
24
|
-
.. autosummary::
|
|
25
|
-
|
|
26
|
-
~SignalUpload.name
|
|
27
|
-
~SignalUpload.data
|
|
28
|
-
~SignalUpload.metadata
|
|
29
|
-
~SignalUpload.priority
|
|
30
|
-
|
|
31
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|