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.
Files changed (31) hide show
  1. {tonik-0.1.16 → tonik-0.1.17}/.devcontainer/devcontainer.json +1 -1
  2. {tonik-0.1.16 → tonik-0.1.17}/PKG-INFO +1 -1
  3. tonik-0.1.17/pyproject.toml +76 -0
  4. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/api.py +9 -5
  5. {tonik-0.1.16 → tonik-0.1.17}/tests/conftest.py +20 -0
  6. {tonik-0.1.16 → tonik-0.1.17}/tests/test_api.py +30 -0
  7. {tonik-0.1.16 → tonik-0.1.17}/.gitignore +0 -0
  8. {tonik-0.1.16 → tonik-0.1.17}/HOW_TO_RELEASE.md +0 -0
  9. {tonik-0.1.16 → tonik-0.1.17}/LICENSE +0 -0
  10. {tonik-0.1.16 → tonik-0.1.17}/README.md +0 -0
  11. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/Dockerfile_api +0 -0
  12. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/Dockerfile_grafana +0 -0
  13. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/dashboards/demo_dashboard.json +0 -0
  14. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/docker-compose.yml +0 -0
  15. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/grafana.ini +0 -0
  16. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/provisioning/dashboards/default.yaml +0 -0
  17. {tonik-0.1.16 → tonik-0.1.17}/grafana_example/provisioning/datasources/default.yaml +0 -0
  18. {tonik-0.1.16 → tonik-0.1.17}/mkdocs.yml +0 -0
  19. /tonik-0.1.16/pyproject.toml → /tonik-0.1.17/pyproject.toml~ +0 -0
  20. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/__init__.py +0 -0
  21. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/grafana_annotations.py +0 -0
  22. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/package_data/index.html +0 -0
  23. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/package_data/whakaari_labels.json +0 -0
  24. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/storage.py +0 -0
  25. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/utils.py +0 -0
  26. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/xarray2netcdf.py +0 -0
  27. {tonik-0.1.16 → tonik-0.1.17}/src/tonik/xarray2zarr.py +0 -0
  28. {tonik-0.1.16 → tonik-0.1.17}/tests/backend_speed_test.py +0 -0
  29. {tonik-0.1.16 → tonik-0.1.17}/tests/test_save.py +0 -0
  30. {tonik-0.1.16 → tonik-0.1.17}/tests/test_storage.py +0 -0
  31. {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": "Python 3",
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.16
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, create=False)
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