pastastore 1.4.0__py3-none-any.whl → 1.6.0__py3-none-any.whl

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.
pastastore/connectors.py CHANGED
@@ -1,8 +1,9 @@
1
+ """Module containing classes for connecting to different data stores."""
2
+
1
3
  import json
2
4
  import os
3
5
  import warnings
4
6
  from copy import deepcopy
5
- from importlib import import_module
6
7
  from typing import Dict, Optional, Union
7
8
 
8
9
  import pandas as pd
@@ -15,190 +16,9 @@ FrameorSeriesUnion = Union[pd.DataFrame, pd.Series]
15
16
  warnings.showwarning = _custom_warning
16
17
 
17
18
 
18
- class ArcticConnector(BaseConnector, ConnectorUtil): # pragma: no cover
19
- conn_type = "arctic"
20
-
21
- def __init__(self, name: str, connstr: str):
22
- """Create an ArcticConnector object that connects to a running MongoDB
23
- database via Arctic.
24
-
25
- Parameters
26
- ----------
27
- name : str
28
- name of the database
29
- connstr : str
30
- connection string (e.g. 'mongodb://localhost:27017/')
31
- """
32
- try:
33
- import arctic
34
- except ModuleNotFoundError as e:
35
- print(
36
- "Please install arctic (also requires "
37
- "a MongoDB instance running somewhere, e.g. "
38
- "MongoDB Community: \n"
39
- "https://docs.mongodb.com/manual/administration"
40
- "/install-community/)!"
41
- )
42
- raise e
43
- self.connstr = connstr
44
- self.name = name
45
-
46
- self.libs: dict = {}
47
- self.arc = arctic.Arctic(connstr)
48
- self._initialize()
49
- self.models = ModelAccessor(self)
50
- # for older versions of PastaStore, if oseries_models library is empty
51
- # populate oseries - models database
52
- self._update_all_oseries_model_links()
53
-
54
- def _initialize(self) -> None:
55
- """Internal method to initalize the libraries."""
56
-
57
- for libname in self._default_library_names:
58
- if self._library_name(libname) not in self.arc.list_libraries():
59
- self.arc.initialize_library(self._library_name(libname))
60
- else:
61
- print(
62
- f"ArcticConnector: library "
63
- f"'{self._library_name(libname)}'"
64
- " already exists. Linking to existing library."
65
- )
66
- self.libs[libname] = self._get_library(libname)
67
-
68
- def _library_name(self, libname: str) -> str:
69
- """Internal method to get full library name according to Arctic."""
70
- return ".".join([self.name, libname])
71
-
72
- def _get_library(self, libname: str):
73
- """Get Arctic library handle.
74
-
75
- Parameters
76
- ----------
77
- libname : str
78
- name of the library
79
-
80
- Returns
81
- -------
82
- lib : arctic.Library handle
83
- handle to the library
84
- """
85
- # get library handle
86
- lib = self.arc.get_library(self._library_name(libname))
87
- return lib
88
-
89
- def _add_item(
90
- self,
91
- libname: str,
92
- item: Union[FrameorSeriesUnion, Dict],
93
- name: str,
94
- metadata: Optional[Dict] = None,
95
- **_,
96
- ) -> None:
97
- """Internal method to add item to library (time series or model).
98
-
99
- Parameters
100
- ----------
101
- libname : str
102
- name of the library
103
- item : Union[FrameorSeriesUnion, Dict]
104
- item to add, either time series or pastas.Model as dictionary
105
- name : str
106
- name of the item
107
- metadata : Optional[Dict], optional
108
- dictionary containing metadata, by default None
109
- """
110
- lib = self._get_library(libname)
111
- lib.write(name, item, metadata=metadata)
112
-
113
- def _get_item(self, libname: str, name: str) -> Union[FrameorSeriesUnion, Dict]:
114
- """Internal method to retrieve item from library.
115
-
116
- Parameters
117
- ----------
118
- libname : str
119
- name of the library
120
- name : str
121
- name of the item
122
-
123
- Returns
124
- -------
125
- item : Union[FrameorSeriesUnion, Dict]
126
- time series or model dictionary
127
- """
128
- lib = self._get_library(libname)
129
- return lib.read(name).data
130
-
131
- def _del_item(self, libname: str, name: str) -> None:
132
- """Internal method to delete items (series or models).
133
-
134
- Parameters
135
- ----------
136
- libname : str
137
- name of library to delete item from
138
- name : str
139
- name of item to delete
140
- """
141
- lib = self._get_library(libname)
142
- lib.delete(name)
143
-
144
- def _get_metadata(self, libname: str, name: str) -> dict:
145
- """Internal method to retrieve metadata for an item.
146
-
147
- Parameters
148
- ----------
149
- libname : str
150
- name of the library
151
- name : str
152
- name of the item
153
-
154
- Returns
155
- -------
156
- dict
157
- dictionary containing metadata
158
- """
159
- lib = self._get_library(libname)
160
- return lib.read_metadata(name).metadata
161
-
162
- @property
163
- def oseries_names(self):
164
- """List of oseries names.
165
-
166
- Returns
167
- -------
168
- list
169
- list of oseries in library
170
- """
171
- return self._get_library("oseries").list_symbols()
172
-
173
- @property
174
- def stresses_names(self):
175
- """List of stresses names.
176
-
177
- Returns
178
- -------
179
- list
180
- list of stresses in library
181
- """
182
- return self._get_library("stresses").list_symbols()
183
-
184
- @property
185
- def model_names(self):
186
- """List of model names.
187
-
188
- Returns
189
- -------
190
- list
191
- list of models in library
192
- """
193
- return self._get_library("models").list_symbols()
194
-
195
- @property
196
- def oseries_with_models(self):
197
- """List of oseries with models."""
198
- return self._get_library("oseries_models").list_symbols()
199
-
200
-
201
19
  class ArcticDBConnector(BaseConnector, ConnectorUtil):
20
+ """ArcticDBConnector object using ArcticDB to store data."""
21
+
202
22
  conn_type = "arcticdb"
203
23
 
204
24
  def __init__(self, name: str, uri: str):
@@ -228,8 +48,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
228
48
  self._update_all_oseries_model_links()
229
49
 
230
50
  def _initialize(self) -> None:
231
- """Internal method to initalize the libraries."""
232
-
51
+ """Initialize the libraries (internal method)."""
233
52
  for libname in self._default_library_names:
234
53
  if self._library_name(libname) not in self.arc.list_libraries():
235
54
  self.arc.create_library(self._library_name(libname))
@@ -242,7 +61,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
242
61
  self.libs[libname] = self._get_library(libname)
243
62
 
244
63
  def _library_name(self, libname: str) -> str:
245
- """Internal method to get full library name according to ArcticDB."""
64
+ """Get full library name according to ArcticDB (internal method)."""
246
65
  return ".".join([self.name, libname])
247
66
 
248
67
  def _get_library(self, libname: str):
@@ -270,7 +89,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
270
89
  metadata: Optional[Dict] = None,
271
90
  **_,
272
91
  ) -> None:
273
- """Internal method to add item to library (time series or model).
92
+ """Add item to library (time series or model) (internal method).
274
93
 
275
94
  Parameters
276
95
  ----------
@@ -292,7 +111,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
292
111
  lib.write(name, item, metadata=metadata)
293
112
 
294
113
  def _get_item(self, libname: str, name: str) -> Union[FrameorSeriesUnion, Dict]:
295
- """Internal method to retrieve item from library.
114
+ """Retrieve item from library (internal method).
296
115
 
297
116
  Parameters
298
117
  ----------
@@ -310,7 +129,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
310
129
  return lib.read(name).data
311
130
 
312
131
  def _del_item(self, libname: str, name: str) -> None:
313
- """Internal method to delete items (series or models).
132
+ """Delete items (series or models) (internal method).
314
133
 
315
134
  Parameters
316
135
  ----------
@@ -323,7 +142,7 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
323
142
  lib.delete(name)
324
143
 
325
144
  def _get_metadata(self, libname: str, name: str) -> dict:
326
- """Internal method to retrieve metadata for an item.
145
+ """Retrieve metadata for an item (internal method).
327
146
 
328
147
  Parameters
329
148
  ----------
@@ -379,227 +198,9 @@ class ArcticDBConnector(BaseConnector, ConnectorUtil):
379
198
  return self._get_library("oseries_models").list_symbols()
380
199
 
381
200
 
382
- class PystoreConnector(BaseConnector, ConnectorUtil): # pragma: no cover
383
- conn_type = "pystore"
384
-
385
- def __init__(self, name: str, path: str):
386
- """Create a PystoreConnector object that points to a Pystore.
387
-
388
- Parameters
389
- ----------
390
- name : str
391
- name of the store
392
- path : str
393
- path to the pystore directory
394
- """
395
- try:
396
- import pystore
397
- except ModuleNotFoundError as e:
398
- print(
399
- "Install pystore, follow instructions at "
400
- "https://github.com/ranaroussi/pystore#dependencies"
401
- )
402
- raise e
403
- self.name = name
404
- self.path = path
405
- pystore.set_path(self.path)
406
- self.store = pystore.store(self.name)
407
- self.libs: dict = {}
408
- self._initialize()
409
- self.models = ModelAccessor(self)
410
- # for older versions of PastaStore, if oseries_models library is empty
411
- # populate oseries - models database
412
- self._update_all_oseries_model_links()
413
-
414
- def _initialize(self) -> None:
415
- """Internal method to initalize the libraries (stores)."""
416
- for libname in self._default_library_names:
417
- if libname in self.store.list_collections():
418
- print(
419
- f"PystoreConnector: library '{self.path}/{libname}' "
420
- "already exists. Linking to existing library."
421
- )
422
- lib = self.store.collection(libname)
423
- self.libs[libname] = lib
424
-
425
- def _get_library(self, libname: str):
426
- """Get Pystore library handle.
427
-
428
- Parameters
429
- ----------
430
- libname : str
431
- name of the library
432
-
433
- Returns
434
- -------
435
- Pystore.Collection handle
436
- handle to the library
437
- """
438
- # get library handle
439
- lib = self.store.collection(libname)
440
- return lib
441
-
442
- def _add_item(
443
- self,
444
- libname: str,
445
- item: Union[FrameorSeriesUnion, Dict],
446
- name: str,
447
- metadata: Optional[Dict] = None,
448
- overwrite: bool = False,
449
- ) -> None:
450
- """Internal method to add item to library (time series or model).
451
-
452
- Parameters
453
- ----------
454
- libname : str
455
- name of the library
456
- item : Union[FrameorSeriesUnion, Dict]
457
- item to add, either time series or pastas.Model as dictionary
458
- name : str
459
- name of the item
460
- metadata : Optional[Dict], optional
461
- dictionary containing metadata, by default None
462
- overwrite : bool, optional
463
- overwrite item if it already exists, by default False.
464
- """
465
- # convert to DataFrame because pystore doesn't accept pandas.Series
466
- # (maybe has an easy fix, but converting w to_frame for now)
467
- if isinstance(item, pd.Series):
468
- s = item.to_frame(name=name)
469
- is_type = "series"
470
- elif isinstance(item, dict):
471
- s = pd.DataFrame() # empty DataFrame as placeholder
472
- jsondict = json.loads(json.dumps(item, cls=PastasEncoder, indent=4))
473
- metadata = jsondict # model dict is stored in metadata
474
- is_type = "series"
475
- elif isinstance(item, list):
476
- s = pd.Series(item).to_frame(name="modelnames")
477
- is_type = "list"
478
- elif isinstance(item, pd.DataFrame):
479
- s = item
480
- is_type = "dataframe"
481
-
482
- # store info about input type to ensure same type is returned
483
- if metadata is None:
484
- metadata = {"_is_type": is_type}
485
- else:
486
- metadata["_is_type"] = is_type
487
-
488
- lib = self._get_library(libname)
489
- lib.write(name, s, metadata=metadata, overwrite=overwrite)
490
-
491
- def _get_item(self, libname: str, name: str) -> Union[FrameorSeriesUnion, Dict]:
492
- """Internal method to retrieve item from pystore library.
493
-
494
- Parameters
495
- ----------
496
- libname : str
497
- name of the library
498
- name : str
499
- name of the item
500
-
501
- Returns
502
- -------
503
- item : Union[FrameorSeriesUnion, Dict]
504
- time series or model dictionary
505
- """
506
- load_mod = import_module("pastas.io.pas") # type: ignore
507
- lib = self._get_library(libname)
508
- # hack for storing models, stored as metadata
509
- if libname == "models":
510
- jsonpath = lib._item_path(name).joinpath("metadata.json")
511
- s = load_mod.load(jsonpath) # type: ignore
512
- else:
513
- # read series and convert to pandas
514
- item = lib.item(name)
515
- s = item.to_pandas()
516
- # remove _is_type key and return correct type
517
- is_type = item.metadata.pop("_is_type")
518
- if is_type == "series":
519
- s = s.squeeze()
520
- elif is_type == "list":
521
- s = s["modelnames"].tolist()
522
- return s
523
-
524
- def _del_item(self, libname: str, name: str) -> None:
525
- """Internal method to delete data from the store.
526
-
527
- Parameters
528
- ----------
529
- libname : str
530
- name of the library
531
- name : str
532
- name of the item to delete
533
- """
534
- lib = self._get_library(libname)
535
- lib.delete_item(name)
536
- self._clear_cache(libname)
537
-
538
- def _get_metadata(self, libname: str, name: str) -> dict:
539
- """Internal method to read metadata from pystore.
540
-
541
- Parameters
542
- ----------
543
- libname : str
544
- name of the library the series are in ("oseries" or "stresses")
545
- name : str
546
- name of item to load metadata for
547
-
548
- Returns
549
- -------
550
- imeta : dict
551
- dictionary containing metadata
552
- """
553
- from pystore.utils import read_metadata
554
-
555
- lib = self._get_library(libname)
556
- imeta = read_metadata(lib._item_path(name))
557
- if "name" not in imeta.keys():
558
- imeta["name"] = name
559
- if "_is_type" in imeta.keys():
560
- imeta.pop("_is_type")
561
- return imeta
562
-
563
- @property
564
- def oseries_names(self):
565
- """List of oseries names.
566
-
567
- Returns
568
- -------
569
- list
570
- list of oseries in library
571
- """
572
- return list(self._get_library("oseries").list_items())
573
-
574
- @property
575
- def stresses_names(self):
576
- """List of stresses names.
577
-
578
- Returns
579
- -------
580
- list
581
- list of stresses in library
582
- """
583
- return list(self._get_library("stresses").list_items())
584
-
585
- @property
586
- def model_names(self):
587
- """List of model names.
588
-
589
- Returns
590
- -------
591
- list
592
- list of models in library
593
- """
594
- return list(self._get_library("models").list_items())
595
-
596
- @property
597
- def oseries_with_models(self):
598
- """List of oseries with models."""
599
- return list(self._get_library("oseries_models").list_items())
600
-
601
-
602
201
  class DictConnector(BaseConnector, ConnectorUtil):
202
+ """DictConnector object that stores timeseries and models in dictionaries."""
203
+
603
204
  conn_type = "dict"
604
205
 
605
206
  def __init__(self, name: str = "pastas_db"):
@@ -643,7 +244,7 @@ class DictConnector(BaseConnector, ConnectorUtil):
643
244
  metadata: Optional[Dict] = None,
644
245
  **_,
645
246
  ) -> None:
646
- """Internal method to add item (time series or models).
247
+ """Add item (time series or models) (internal method).
647
248
 
648
249
  Parameters
649
250
  ----------
@@ -663,7 +264,7 @@ class DictConnector(BaseConnector, ConnectorUtil):
663
264
  lib[name] = (metadata, item)
664
265
 
665
266
  def _get_item(self, libname: str, name: str) -> Union[FrameorSeriesUnion, Dict]:
666
- """Internal method to retrieve item from pystore library.
267
+ """Retrieve item from database (internal method).
667
268
 
668
269
  Parameters
669
270
  ----------
@@ -685,7 +286,7 @@ class DictConnector(BaseConnector, ConnectorUtil):
685
286
  return item
686
287
 
687
288
  def _del_item(self, libname: str, name: str) -> None:
688
- """Internal method to delete items (series or models).
289
+ """Delete items (series or models) (internal method).
689
290
 
690
291
  Parameters
691
292
  ----------
@@ -698,7 +299,7 @@ class DictConnector(BaseConnector, ConnectorUtil):
698
299
  _ = lib.pop(name)
699
300
 
700
301
  def _get_metadata(self, libname: str, name: str) -> dict:
701
- """Internal method to read metadata.
302
+ """Read metadata (internal method).
702
303
 
703
304
  Parameters
704
305
  ----------
@@ -742,6 +343,8 @@ class DictConnector(BaseConnector, ConnectorUtil):
742
343
 
743
344
 
744
345
  class PasConnector(BaseConnector, ConnectorUtil):
346
+ """PasConnector object that stores time series and models as JSON files on disk."""
347
+
745
348
  conn_type = "pas"
746
349
 
747
350
  def __init__(self, name: str, path: str):
@@ -767,7 +370,7 @@ class PasConnector(BaseConnector, ConnectorUtil):
767
370
  self._update_all_oseries_model_links()
768
371
 
769
372
  def _initialize(self) -> None:
770
- """Internal method to initialize the libraries."""
373
+ """Initialize the libraries (internal method)."""
771
374
  for val in self._default_library_names:
772
375
  libdir = os.path.join(self.path, val)
773
376
  if not os.path.exists(libdir):
@@ -803,7 +406,7 @@ class PasConnector(BaseConnector, ConnectorUtil):
803
406
  metadata: Optional[Dict] = None,
804
407
  **_,
805
408
  ) -> None:
806
- """Internal method to add item (time series or models).
409
+ """Add item (time series or models) (internal method).
807
410
 
808
411
  Parameters
809
412
  ----------
@@ -845,7 +448,7 @@ class PasConnector(BaseConnector, ConnectorUtil):
845
448
  fm.write(jsondict)
846
449
 
847
450
  def _get_item(self, libname: str, name: str) -> Union[FrameorSeriesUnion, Dict]:
848
- """Internal method to retrieve item.
451
+ """Retrieve item (internal method).
849
452
 
850
453
  Parameters
851
454
  ----------
@@ -878,7 +481,7 @@ class PasConnector(BaseConnector, ConnectorUtil):
878
481
  return item
879
482
 
880
483
  def _del_item(self, libname: str, name: str) -> None:
881
- """Internal method to delete items (series or models).
484
+ """Delete items (series or models) (internal method).
882
485
 
883
486
  Parameters
884
487
  ----------
@@ -898,7 +501,7 @@ class PasConnector(BaseConnector, ConnectorUtil):
898
501
  pass
899
502
 
900
503
  def _get_metadata(self, libname: str, name: str) -> dict:
901
- """Internal method to read metadata.
504
+ """Read metadata (internal method).
902
505
 
903
506
  Parameters
904
507
  ----------
pastastore/datasets.py CHANGED
@@ -1,3 +1,5 @@
1
+ """Module containing example dataset."""
2
+
1
3
  import os
2
4
 
3
5
  import pandas as pd
@@ -13,7 +15,7 @@ from pastastore.base import BaseConnector
13
15
 
14
16
 
15
17
  def example_pastastore(conn="DictConnector"):
16
- """Example dataset loaded into PastaStore.
18
+ """Get example PastaStore.
17
19
 
18
20
  Parameters
19
21
  ----------
@@ -27,7 +29,6 @@ def example_pastastore(conn="DictConnector"):
27
29
  pstore : pastastore.PastaStore
28
30
  PastaStore containing example dataset
29
31
  """
30
-
31
32
  # check it test dataset is available
32
33
  datadir = os.path.join(os.path.dirname(__file__), "../tests/data")
33
34
  if not os.path.exists(datadir):
@@ -175,8 +176,7 @@ def _default_connector(conntype: str):
175
176
  Parameters
176
177
  ----------
177
178
  conntype : str
178
- name of connector (DictConnector, PasConnector,
179
- ArcticConnector, ArcticDBConnector or PystoreConnector)
179
+ name of connector (DictConnector, PasConnector, ArcticDBConnector)
180
180
 
181
181
  Returns
182
182
  -------
@@ -184,14 +184,9 @@ def _default_connector(conntype: str):
184
184
  default Connector based on type.
185
185
  """
186
186
  Conn = getattr(pst, conntype)
187
- if Conn.conn_type == "arctic":
188
- connstr = "mongodb://localhost:27017/"
189
- conn = Conn("my_db", connstr)
190
- elif Conn.conn_type == "arcticdb":
187
+ if Conn.conn_type == "arcticdb":
191
188
  uri = "lmdb://./arctic_db"
192
189
  conn = Conn("my_db", uri)
193
- elif Conn.conn_type == "pystore":
194
- conn = Conn("my_db", "./pystore_db")
195
190
  elif Conn.conn_type == "dict":
196
191
  conn = Conn("my_db")
197
192
  elif Conn.conn_type == "pas":