tonik 0.1.16__tar.gz → 0.1.17__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.
- {tonik-0.1.16 → tonik-0.1.17}/.devcontainer/devcontainer.json +1 -1
- {tonik-0.1.16 → tonik-0.1.17}/PKG-INFO +1 -1
- tonik-0.1.17/pyproject.toml +76 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/api.py +9 -5
- {tonik-0.1.16 → tonik-0.1.17}/tests/conftest.py +20 -0
- {tonik-0.1.16 → tonik-0.1.17}/tests/test_api.py +30 -0
- {tonik-0.1.16 → tonik-0.1.17}/.gitignore +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/HOW_TO_RELEASE.md +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/LICENSE +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/README.md +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/Dockerfile_api +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/Dockerfile_grafana +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/dashboards/demo_dashboard.json +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/docker-compose.yml +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/grafana.ini +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/provisioning/dashboards/default.yaml +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/grafana_example/provisioning/datasources/default.yaml +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/mkdocs.yml +0 -0
- /tonik-0.1.16/pyproject.toml → /tonik-0.1.17/pyproject.toml~ +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/__init__.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/grafana_annotations.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/package_data/index.html +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/package_data/whakaari_labels.json +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/storage.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/utils.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/xarray2netcdf.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/src/tonik/xarray2zarr.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/tests/backend_speed_test.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/tests/test_save.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/tests/test_storage.py +0 -0
- {tonik-0.1.16 → tonik-0.1.17}/tests/test_utils.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
2
2
|
// README at: https://github.com/devcontainers/templates/tree/main/src/python
|
|
3
3
|
{
|
|
4
|
-
"name": "
|
|
4
|
+
"name": "Tonik",
|
|
5
5
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
|
6
6
|
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tonik
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary: Store time series data as HDF5 files and access them through an API.
|
|
5
5
|
Project-URL: Homepage, https://tsc-tools.github.io/tonik
|
|
6
6
|
Project-URL: Issues, https://github.com/tsc-tools/tonik/issues
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[tool.hatch.build.targets.sdist]
|
|
6
|
+
exclude = [
|
|
7
|
+
"/.github",
|
|
8
|
+
"/site",
|
|
9
|
+
"/docs",
|
|
10
|
+
"/sandbox.ipynb"
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[project]
|
|
14
|
+
name = "tonik"
|
|
15
|
+
version = "0.1.17"
|
|
16
|
+
authors = [
|
|
17
|
+
{ name="Yannik Behr", email="y.behr@gns.cri.nz" },
|
|
18
|
+
{ name="Christof Mueller", email="c.mueller@gns.cri.nz" }
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
description = "Store time series data as HDF5 files and access them through an API."
|
|
22
|
+
readme = "README.md"
|
|
23
|
+
requires-python = ">=3.9"
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"h5py>=3.8",
|
|
31
|
+
"datashader>=0.14",
|
|
32
|
+
"xarray[io,accel,parallel]",
|
|
33
|
+
"pandas>=2.0",
|
|
34
|
+
"netcdf4>=1.6",
|
|
35
|
+
"h5netcdf>=1.1",
|
|
36
|
+
"python-json-logger>=2.0",
|
|
37
|
+
"uvicorn[standard]>=0.22",
|
|
38
|
+
"fastapi>=0.112",
|
|
39
|
+
"matplotlib",
|
|
40
|
+
"zarr[remote_tests]>=3.0.3; python_version >= '3.11'",
|
|
41
|
+
"zarr[remote_tests]<3; python_version < '3.11'",
|
|
42
|
+
"s3fs"
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
dev = ["pytest",
|
|
47
|
+
"httpx",
|
|
48
|
+
"ipykernel",
|
|
49
|
+
"mkdocs",
|
|
50
|
+
"mkdocstrings[python]",
|
|
51
|
+
"mkdocs-jupyter"]
|
|
52
|
+
|
|
53
|
+
[project.urls]
|
|
54
|
+
Homepage = "https://tsc-tools.github.io/tonik"
|
|
55
|
+
Issues = "https://github.com/tsc-tools/tonik/issues"
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
tonik_api = "tonik.api:main"
|
|
59
|
+
test_data = "tonik.utils:main"
|
|
60
|
+
grafana_annotations = "tonik.grafana_annotations:main"
|
|
61
|
+
|
|
62
|
+
[tool.pytest.ini_options]
|
|
63
|
+
log_cli = true
|
|
64
|
+
|
|
65
|
+
[tool.hatch.envs.test]
|
|
66
|
+
dependencies = [
|
|
67
|
+
"coverage[toml]",
|
|
68
|
+
"pytest",
|
|
69
|
+
"httpx"
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[[tool.hatch.envs.test.matrix]]
|
|
73
|
+
python = ["3.11", "3.9"]
|
|
74
|
+
|
|
75
|
+
[tool.hatch.envs.test.scripts]
|
|
76
|
+
run-pytest = "pytest tests"
|
|
@@ -26,8 +26,9 @@ InventoryReturnType = Union[list, dict]
|
|
|
26
26
|
|
|
27
27
|
class TonikAPI:
|
|
28
28
|
|
|
29
|
-
def __init__(self, rootdir) -> None:
|
|
29
|
+
def __init__(self, rootdir, backend='netcdf') -> None:
|
|
30
30
|
self.rootdir = rootdir
|
|
31
|
+
self.backend = backend
|
|
31
32
|
self.app = FastAPI()
|
|
32
33
|
|
|
33
34
|
# -- allow any origin to query API
|
|
@@ -72,7 +73,7 @@ class TonikAPI:
|
|
|
72
73
|
_et = self.preprocess_datetime(endtime)
|
|
73
74
|
g = Storage(group, rootdir=self.rootdir,
|
|
74
75
|
starttime=_st, endtime=_et,
|
|
75
|
-
create=False)
|
|
76
|
+
create=False, backend=self.backend)
|
|
76
77
|
c = g
|
|
77
78
|
if subdir:
|
|
78
79
|
c = g.get_substore(*subdir)
|
|
@@ -147,7 +148,8 @@ class TonikAPI:
|
|
|
147
148
|
return freq, dates, spec
|
|
148
149
|
|
|
149
150
|
async def inventory(self, group: str, subdir: SubdirType = None, tree: bool = True) -> InventoryReturnType:
|
|
150
|
-
sg = Storage(group, rootdir=self.rootdir,
|
|
151
|
+
sg = Storage(group, rootdir=self.rootdir,
|
|
152
|
+
create=False, backend=self.backend)
|
|
151
153
|
try:
|
|
152
154
|
c = sg.get_substore(*subdir)
|
|
153
155
|
except TypeError:
|
|
@@ -168,7 +170,8 @@ class TonikAPI:
|
|
|
168
170
|
_st = self.preprocess_datetime(starttime)
|
|
169
171
|
_et = self.preprocess_datetime(endtime)
|
|
170
172
|
sg = Storage(group, rootdir=self.rootdir,
|
|
171
|
-
starttime=_st, endtime=_et, create=False
|
|
173
|
+
starttime=_st, endtime=_et, create=False,
|
|
174
|
+
backend=self.backend)
|
|
172
175
|
try:
|
|
173
176
|
c = sg.get_substore(*subdir)
|
|
174
177
|
except TypeError:
|
|
@@ -183,10 +186,11 @@ class TonikAPI:
|
|
|
183
186
|
def main(argv=None):
|
|
184
187
|
parser = ArgumentParser()
|
|
185
188
|
parser.add_argument("--rootdir", default='/tmp')
|
|
189
|
+
parser.add_argument("--backend", default='netcdf')
|
|
186
190
|
parser.add_argument("-p", "--port", default=8003, type=int)
|
|
187
191
|
parser.add_argument("--host", default='0.0.0.0')
|
|
188
192
|
args = parser.parse_args(argv)
|
|
189
|
-
ta = TonikAPI(args.rootdir)
|
|
193
|
+
ta = TonikAPI(args.rootdir, backend=args.backend)
|
|
190
194
|
uvicorn.run(ta.app, host=args.host, port=args.port)
|
|
191
195
|
|
|
192
196
|
|
|
@@ -93,6 +93,26 @@ def setup_api(setup):
|
|
|
93
93
|
return client, g.get_substore('MDR', '00', 'BHZ')
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
@pytest.fixture(scope='module')
|
|
97
|
+
def setup_api_zarr(tmp_path_factory):
|
|
98
|
+
savedir = tmp_path_factory.mktemp('vumt_test_tmp_zarr', numbered=True)
|
|
99
|
+
g = Storage('volcanoes', rootdir=savedir, backend='zarr')
|
|
100
|
+
from tonik.api import TonikAPI
|
|
101
|
+
ta = TonikAPI(str(savedir), backend='zarr')
|
|
102
|
+
client = TestClient(ta.app)
|
|
103
|
+
g.starttime = datetime(2023, 1, 1)
|
|
104
|
+
g.endtime = datetime(2023, 1, 6)
|
|
105
|
+
feat = generate_test_data(tstart=tstart,
|
|
106
|
+
feature_names=['ssam'],
|
|
107
|
+
ndays=ndays,
|
|
108
|
+
nfreqs=8,
|
|
109
|
+
freq_names=['frequency'],
|
|
110
|
+
dim=2)
|
|
111
|
+
c = g.get_substore('MDR', '00', 'BHZ')
|
|
112
|
+
c.save(feat)
|
|
113
|
+
return client, c
|
|
114
|
+
|
|
115
|
+
|
|
96
116
|
@pytest.fixture(scope='module')
|
|
97
117
|
def setup_multi_dimensional(tmp_path_factory):
|
|
98
118
|
tempdir = tmp_path_factory.mktemp('test_xarray2zarr_high_dimensionality')
|
|
@@ -96,6 +96,36 @@ def test_read_ssam(setup_api):
|
|
|
96
96
|
assert len(np.unique(df['freqs'])) == 8
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
def test_read_ssam_from_zarr(setup_api_zarr):
|
|
100
|
+
client, l = setup_api_zarr
|
|
101
|
+
params = dict(name='ssam',
|
|
102
|
+
group='volcanoes',
|
|
103
|
+
subdir=['MDR', '00', 'BHZ'],
|
|
104
|
+
starttime=str(l.starttime),
|
|
105
|
+
endtime=str(l.endtime),
|
|
106
|
+
resolution='full',
|
|
107
|
+
log=False)
|
|
108
|
+
with client.stream("GET", "/feature", params=params) as r:
|
|
109
|
+
r.read()
|
|
110
|
+
txt = r.text
|
|
111
|
+
df = pd.read_csv(StringIO(txt), parse_dates=True, index_col=0)
|
|
112
|
+
np.testing.assert_array_almost_equal(df['feature'].values,
|
|
113
|
+
l('ssam').values.ravel(order='C'))
|
|
114
|
+
|
|
115
|
+
params = dict(name='ssam',
|
|
116
|
+
group='volcanoes',
|
|
117
|
+
subdir=['MDR', '00', 'BHZ'],
|
|
118
|
+
starttime=str(l.starttime),
|
|
119
|
+
endtime=str(l.endtime),
|
|
120
|
+
resolution='1D')
|
|
121
|
+
with client.stream("GET", "/feature", params=params) as r:
|
|
122
|
+
r.read()
|
|
123
|
+
txt = r.text
|
|
124
|
+
df = pd.read_csv(StringIO(txt), parse_dates=True, index_col=0)
|
|
125
|
+
assert len(np.unique(df.index)) == 5
|
|
126
|
+
assert len(np.unique(df['freqs'])) == 8
|
|
127
|
+
|
|
128
|
+
|
|
99
129
|
def test_read_filterbank(setup_api):
|
|
100
130
|
client, l = setup_api
|
|
101
131
|
params = dict(name='filterbank',
|
|
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
|