pandahub 0.3.12__zip → 0.3.14__zip
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.
- {pandahub-0.3.12 → pandahub-0.3.14}/CHANGELOG.md +5 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/PKG-INFO +1 -1
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/variants.py +1 -1
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/PandaHub.py +116 -47
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/database_toolbox.py +44 -4
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub.egg-info/PKG-INFO +1 -1
- {pandahub-0.3.12 → pandahub-0.3.14}/pyproject.toml +1 -1
- {pandahub-0.3.12 → pandahub-0.3.14}/CONTRIBUTING.rst +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/LICENSE +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/MANIFEST.in +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/README.md +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/dependencies.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/db.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/schemas.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/settings.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/toolbox.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/internal/users.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/main.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/auth.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/net.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/projects.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/timeseries.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/api/routers/users.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/datatypes.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/mongodb_indexes.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/timeseries/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/timeseries/data_sources/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/timeseries/data_sources/mongo_data.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub/lib/timeseries/output_writer_mongodb.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub.egg-info/SOURCES.txt +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub.egg-info/dependency_links.txt +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub.egg-info/requires.txt +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/pandahub.egg-info/top_level.txt +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/requirements.txt +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/setup.cfg +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/setup.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/__init__.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/conftest.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/performance_test.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/test_client.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/test_networks.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/test_projects.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/test/test_timeseries.py +0 -0
- {pandahub-0.3.12 → pandahub-0.3.14}/tutorials/config.py +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [0.3.13]
|
|
4
|
+
- FIXED: fetching integer index on empty collection
|
|
5
|
+
- IMPROVED: context manager for mongo client /database / collection
|
|
6
|
+
- IMPROVED: project locking returns True if user already holds a lock on the project
|
|
7
|
+
|
|
3
8
|
## [0.3.11]
|
|
4
9
|
|
|
5
10
|
- IMPROVED: add lib.database_toolbox.get_mongo_client function
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pandahub
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Data hub for pandapower and pandapipes networks based on MongoDB
|
|
5
5
|
Author-email: Jan Ulffers <jan.ulffers@iee.fraunhofer.de>, Leon Thurner <leon.thurner@retoflow.de>, Jannis Kupka <jannis.kupka@retoflow.de>, Mike Vogt <mike.vogt@iee.fraunhofer.de>, Joschka Thurner <joschka.thurner@retoflow.de>, Alexander Scheidler <alexander.scheidler@iee.fraunhofer.de>
|
|
6
6
|
License: Copyright (c) 2022 by University of Kassel, Fraunhofer Institute for Energy Economics
|
|
@@ -22,7 +22,7 @@ class GetVariantsModel(BaseModel):
|
|
|
22
22
|
@router.post("/get_variants")
|
|
23
23
|
def get_variants(data: GetVariantsModel, ph=Depends(pandahub)):
|
|
24
24
|
ph.set_active_project_by_id(data.project_id)
|
|
25
|
-
variants_collection = ph.
|
|
25
|
+
variants_collection = ph.get_project_collection("variant")
|
|
26
26
|
|
|
27
27
|
variants = variants_collection.find({"net_id": data.net_id}, projection={"_id": 0})
|
|
28
28
|
return {variant.pop("index"): variant for variant in variants}
|
|
@@ -17,6 +17,8 @@ from functools import reduce
|
|
|
17
17
|
from operator import getitem
|
|
18
18
|
from uuid import UUID
|
|
19
19
|
from pymongo import MongoClient, ReplaceOne
|
|
20
|
+
from pymongo.database import Database
|
|
21
|
+
from pymongo.collection import Collection
|
|
20
22
|
from pymongo.errors import ServerSelectionTimeoutError, DuplicateKeyError
|
|
21
23
|
|
|
22
24
|
import pandapipes as pps
|
|
@@ -335,14 +337,23 @@ class PandaHub:
|
|
|
335
337
|
self.set_active_project(project_name, realm)
|
|
336
338
|
|
|
337
339
|
def lock_project(self):
|
|
338
|
-
|
|
339
|
-
result =
|
|
340
|
+
coll = self.mongo_client["user_management"]["projects"]
|
|
341
|
+
result = coll.find_one_and_update(
|
|
340
342
|
{
|
|
341
343
|
"_id": self.active_project["_id"],
|
|
344
|
+
"$or": [
|
|
345
|
+
{"locked": {"$eq": False}},
|
|
346
|
+
{
|
|
347
|
+
"$and": [
|
|
348
|
+
{"locked": {"$eq": True}},
|
|
349
|
+
{"locked_by": str(self.user_id)},
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
],
|
|
342
353
|
},
|
|
343
|
-
{"$set": {"locked": True, "locked_by": self.user_id}},
|
|
354
|
+
{"$set": {"locked": True, "locked_by": str(self.user_id)}},
|
|
344
355
|
)
|
|
345
|
-
return result
|
|
356
|
+
return result is not None
|
|
346
357
|
|
|
347
358
|
|
|
348
359
|
# def lock_project(self):
|
|
@@ -409,26 +420,42 @@ class PandaHub:
|
|
|
409
420
|
else:
|
|
410
421
|
return project_doc
|
|
411
422
|
|
|
412
|
-
def _get_project_database(self) ->
|
|
423
|
+
def _get_project_database(self) -> Database:
|
|
413
424
|
return self.get_project_database()
|
|
414
425
|
|
|
415
|
-
def get_project_database(self, collection: Optional[str] = None) ->
|
|
426
|
+
def get_project_database(self, collection: Optional[str] = None) -> Database:
|
|
427
|
+
"""
|
|
428
|
+
Get the database for the current active project.
|
|
429
|
+
|
|
430
|
+
Parameters
|
|
431
|
+
----------
|
|
432
|
+
collection or None
|
|
433
|
+
Name of document collection (DEPRECATED)
|
|
434
|
+
|
|
435
|
+
Returns
|
|
436
|
+
-------
|
|
437
|
+
pymongo.database.Database
|
|
438
|
+
"""
|
|
439
|
+
if collection is None:
|
|
440
|
+
return self.mongo_client[str(self.active_project["_id"])]
|
|
441
|
+
logger.warning(f"Passing a collection to get_project_database is deprecated. Use get_project_collection instead!")
|
|
442
|
+
return self.get_project_collection(collection)
|
|
443
|
+
|
|
444
|
+
def get_project_collection(self, collection_name: str) -> Collection:
|
|
416
445
|
"""
|
|
417
446
|
Get a MongoClient instance connected to the database for the current active project, optionally set to the given collection.
|
|
418
447
|
|
|
419
448
|
Parameters
|
|
420
449
|
----------
|
|
421
|
-
|
|
450
|
+
collection_name
|
|
422
451
|
Name of document collection
|
|
423
452
|
|
|
424
453
|
Returns
|
|
425
454
|
-------
|
|
426
|
-
|
|
455
|
+
pymongo.collection.Collection
|
|
427
456
|
"""
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
return project_db
|
|
431
|
-
return project_db[collection]
|
|
457
|
+
return self.get_project_database()[collection_name]
|
|
458
|
+
|
|
432
459
|
|
|
433
460
|
def _get_global_database(self) -> MongoClient:
|
|
434
461
|
if (
|
|
@@ -461,7 +488,7 @@ class PandaHub:
|
|
|
461
488
|
"""
|
|
462
489
|
if not self.active_project:
|
|
463
490
|
raise PandaHubError("No project activated!")
|
|
464
|
-
return self.
|
|
491
|
+
return self.get_project_collection("_networks").find({}, {"_id:": 1}).distinct("_id")
|
|
465
492
|
|
|
466
493
|
def get_project_version(self):
|
|
467
494
|
return self.active_project.get("version", "0.2.2")
|
|
@@ -1647,21 +1674,22 @@ class PandaHub:
|
|
|
1647
1674
|
var_data = {"var_type": "base", "not_in_var": [], "variant": None}
|
|
1648
1675
|
else:
|
|
1649
1676
|
var_data = {"var_type": "addition", "not_in_var": [], "variant": variant}
|
|
1650
|
-
|
|
1677
|
+
net_doc = db["_networks"].find_one({"_id": net_id})
|
|
1651
1678
|
data = []
|
|
1652
1679
|
for elm_data in elements_data:
|
|
1653
|
-
self._add_missing_defaults(
|
|
1680
|
+
self._add_missing_defaults(element_type, elm_data, net_doc)
|
|
1654
1681
|
self._ensure_dtypes(element_type, elm_data)
|
|
1655
1682
|
data.append({**elm_data, **var_data, "net_id": net_id})
|
|
1656
1683
|
collection = self._collection_name_of_element(element_type)
|
|
1657
1684
|
db[collection].insert_many(data, ordered=False)
|
|
1658
1685
|
return data
|
|
1659
1686
|
|
|
1660
|
-
def _add_missing_defaults(self,
|
|
1687
|
+
def _add_missing_defaults(self, element_type, element_data, net_doc):
|
|
1661
1688
|
func_str = f"create_{element_type}"
|
|
1662
|
-
|
|
1689
|
+
package = pp if net_doc['sector'] == 'power' else pps
|
|
1690
|
+
if not hasattr(package, func_str):
|
|
1663
1691
|
return
|
|
1664
|
-
create_func = getattr(
|
|
1692
|
+
create_func = getattr(package, func_str)
|
|
1665
1693
|
sig = signature(create_func)
|
|
1666
1694
|
params = sig.parameters
|
|
1667
1695
|
|
|
@@ -1677,7 +1705,6 @@ class PandaHub:
|
|
|
1677
1705
|
if element_type in ["line", "trafo", "trafo3w"]:
|
|
1678
1706
|
# add standard type values
|
|
1679
1707
|
std_type = element_data["std_type"]
|
|
1680
|
-
net_doc = db["_networks"].find_one({"_id": net_id})
|
|
1681
1708
|
if net_doc is not None:
|
|
1682
1709
|
# std_types = json.loads(net_doc["data"]["std_types"], cls=io_pp.PPJSONDecoder)[element_type]
|
|
1683
1710
|
std_types = net_doc["data"]["std_types"]
|
|
@@ -1688,6 +1715,9 @@ class PandaHub:
|
|
|
1688
1715
|
if element_type == "line":
|
|
1689
1716
|
if "g_us_per_km" not in element_data:
|
|
1690
1717
|
element_data["g_us_per_km"] = 0
|
|
1718
|
+
if element_type in ['sink', 'source']:
|
|
1719
|
+
if not 'mdot_kg_per_s' in element_data:
|
|
1720
|
+
element_data["mdot_kg_per_s"] = None
|
|
1691
1721
|
|
|
1692
1722
|
def _ensure_dtypes(self, element_type, data):
|
|
1693
1723
|
dtypes = self._datatypes.get(element_type)
|
|
@@ -1751,14 +1781,14 @@ class PandaHub:
|
|
|
1751
1781
|
The value of the created index.
|
|
1752
1782
|
"""
|
|
1753
1783
|
query_filter = query_filter if query_filter is not None else {}
|
|
1754
|
-
coll = self.
|
|
1784
|
+
coll = self.get_project_collection(collection)
|
|
1755
1785
|
for retry in range(retries):
|
|
1756
1786
|
try:
|
|
1757
|
-
|
|
1787
|
+
max_index_doc = next(coll.find(query_filter, projection={index_field: 1})
|
|
1758
1788
|
.sort(index_field, -1)
|
|
1759
1789
|
.limit(1),
|
|
1760
1790
|
None)
|
|
1761
|
-
index = 0 if
|
|
1791
|
+
index = 0 if max_index_doc is None else int(max_index_doc[index_field]) + 1
|
|
1762
1792
|
coll.insert_one({index_field: index})
|
|
1763
1793
|
break
|
|
1764
1794
|
except DuplicateKeyError:
|
|
@@ -2026,6 +2056,17 @@ class PandaHub:
|
|
|
2026
2056
|
metadata = kwargs
|
|
2027
2057
|
if data_type is not None:
|
|
2028
2058
|
metadata["data_type"] = data_type
|
|
2059
|
+
net_id = metadata.get('net_id', None)
|
|
2060
|
+
if net_id is None:
|
|
2061
|
+
net_ids = db["_networks"].distinct("_id")
|
|
2062
|
+
if len(net_ids) == 1:
|
|
2063
|
+
net_id = net_ids[0]
|
|
2064
|
+
else:
|
|
2065
|
+
raise ValueError(
|
|
2066
|
+
"No net_id was provided and multiple networks exist in the database. "
|
|
2067
|
+
"Please provide a net_id."
|
|
2068
|
+
)
|
|
2069
|
+
metadata["_id"] = f"{net_id}_{metadata.get('element_type', None)}_{metadata.get('element_index', None)}_{data_type}"
|
|
2029
2070
|
if isinstance(timeseries, pd.Series):
|
|
2030
2071
|
documents = [
|
|
2031
2072
|
{"metadata": metadata, "timestamp": idx, "value": value}
|
|
@@ -2036,7 +2077,10 @@ class PandaHub:
|
|
|
2036
2077
|
{"metadata": metadata, "timestamp": idx, **row.to_dict()}
|
|
2037
2078
|
for idx, row in timeseries.iterrows()
|
|
2038
2079
|
]
|
|
2039
|
-
|
|
2080
|
+
db[collection_name].insert_many(documents)
|
|
2081
|
+
if kwargs.get("return_id"):
|
|
2082
|
+
return metadata["_id"]
|
|
2083
|
+
return None
|
|
2040
2084
|
document = create_timeseries_document(
|
|
2041
2085
|
timeseries=timeseries,
|
|
2042
2086
|
data_type=data_type,
|
|
@@ -2308,12 +2352,17 @@ class PandaHub:
|
|
|
2308
2352
|
pipeline.append({"$match": meta_filter})
|
|
2309
2353
|
pipeline.append({"$project": {"_id": 0, "metadata": 0}})
|
|
2310
2354
|
timeseries = db[collection_name].aggregate_pandas_all(pipeline)
|
|
2355
|
+
if len(timeseries) == 0:
|
|
2356
|
+
raise PandaHubError("no documents matching the provided filter found", 404)
|
|
2311
2357
|
timeseries.set_index("timestamp", inplace=True)
|
|
2312
2358
|
if include_metadata:
|
|
2313
2359
|
raise NotImplementedError(
|
|
2314
2360
|
"Not implemented yet for timeseries collections"
|
|
2315
2361
|
)
|
|
2316
|
-
|
|
2362
|
+
if len(timeseries.columns) == 1:
|
|
2363
|
+
return timeseries[timeseries.columns[0]]
|
|
2364
|
+
else:
|
|
2365
|
+
return timeseries
|
|
2317
2366
|
filter_document = {**filter_document, **kwargs}
|
|
2318
2367
|
pipeline = [{"$match": filter_document}]
|
|
2319
2368
|
if not compressed_ts_data:
|
|
@@ -2400,6 +2449,7 @@ class PandaHub:
|
|
|
2400
2449
|
collection_name="timeseries",
|
|
2401
2450
|
global_database=False,
|
|
2402
2451
|
project_id=None,
|
|
2452
|
+
timestamp_range=None,
|
|
2403
2453
|
):
|
|
2404
2454
|
"""
|
|
2405
2455
|
Returns a DataFrame, containing all metadata matching the provided filter.
|
|
@@ -2440,10 +2490,17 @@ class PandaHub:
|
|
|
2440
2490
|
pipeline.append({"$match": document_filter})
|
|
2441
2491
|
else:
|
|
2442
2492
|
document_filter = {}
|
|
2493
|
+
if timestamp_range is not None:
|
|
2494
|
+
document_filter["timestamp"] = {
|
|
2495
|
+
"$gte": timestamp_range[0],
|
|
2496
|
+
"$lt": timestamp_range[1],
|
|
2497
|
+
}
|
|
2443
2498
|
document = db[collection_name].find_one(
|
|
2444
2499
|
document_filter, projection={"timestamp": 0, "_id": 0}
|
|
2445
2500
|
)
|
|
2446
|
-
|
|
2501
|
+
if document is None:
|
|
2502
|
+
return pd.DataFrame()
|
|
2503
|
+
value_fields = ["$%s" % field for field in document.keys() if field != "metadata"]
|
|
2447
2504
|
group_dict = {
|
|
2448
2505
|
"_id": "$metadata._id",
|
|
2449
2506
|
"max_value": {"$max": {"$max": value_fields}},
|
|
@@ -2568,27 +2625,30 @@ class PandaHub:
|
|
|
2568
2625
|
document_filter,
|
|
2569
2626
|
projection={"timestamp": 0, "metadata": 0, "_id": 0},
|
|
2570
2627
|
)
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
"
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2628
|
+
if document is None:
|
|
2629
|
+
meta_data = {}
|
|
2630
|
+
else:
|
|
2631
|
+
meta_pipeline = []
|
|
2632
|
+
meta_pipeline.append({"$match": document_filter})
|
|
2633
|
+
value_fields = ["$%s" % field for field in document.keys()]
|
|
2634
|
+
group_dict = {
|
|
2635
|
+
"_id": "$metadata._id",
|
|
2636
|
+
"max_value": {"$max": {"$max": value_fields}},
|
|
2637
|
+
"min_value": {"$min": {"$min": value_fields}},
|
|
2638
|
+
"first_timestamp": {"$min": "$timestamp"},
|
|
2639
|
+
"last_timestamp": {"$max": "$timestamp"},
|
|
2640
|
+
}
|
|
2641
|
+
document = db[collection_name].find_one(document_filter)
|
|
2642
|
+
metadata_fields = {
|
|
2643
|
+
metadata_field: {"$first": "$metadata.%s" % metadata_field}
|
|
2644
|
+
for metadata_field in document["metadata"].keys()
|
|
2645
|
+
if metadata_field != "_id"
|
|
2646
|
+
}
|
|
2647
|
+
group_dict.update(metadata_fields)
|
|
2648
|
+
meta_pipeline.append({"$group": group_dict})
|
|
2649
|
+
meta_data = {
|
|
2650
|
+
d["_id"]: d for d in db[collection_name].aggregate(meta_pipeline)
|
|
2651
|
+
}
|
|
2592
2652
|
timeseries = []
|
|
2593
2653
|
ts_all = db[collection_name].aggregate_pandas_all(pipeline)
|
|
2594
2654
|
if len(ts_all) == 0:
|
|
@@ -2934,7 +2994,16 @@ class PandaHub:
|
|
|
2934
2994
|
"""
|
|
2935
2995
|
self.check_permission("write")
|
|
2936
2996
|
db = self._get_project_database()
|
|
2937
|
-
|
|
2997
|
+
if self.collection_is_timeseries(collection_name):
|
|
2998
|
+
meta_filter = {
|
|
2999
|
+
"metadata.element_type": element_type,
|
|
3000
|
+
"metadata.data_type": data_type,
|
|
3001
|
+
}
|
|
3002
|
+
if netname is not None:
|
|
3003
|
+
meta_filter["metadata.netname"] = netname
|
|
3004
|
+
if element_index is not None:
|
|
3005
|
+
meta_filter["metadata.element_index"] = element_index
|
|
3006
|
+
return db[collection_name].delete_many(meta_filter)
|
|
2938
3007
|
filter_document = {"element_type": element_type, "data_type": data_type}
|
|
2939
3008
|
if netname is not None:
|
|
2940
3009
|
filter_document["netname"] = netname
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
from
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from collections.abc import Iterator
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
5
6
|
import pandas as pd
|
|
6
7
|
from pymongo import MongoClient
|
|
8
|
+
from pymongo.database import Database
|
|
9
|
+
from pymongo.collection import Collection
|
|
7
10
|
|
|
8
11
|
from pandahub.api.internal.settings import MONGODB_URL, MONGODB_USER, MONGODB_PASSWORD
|
|
9
12
|
from pandahub.lib.datatypes import DATATYPES
|
|
@@ -188,7 +191,7 @@ def create_timeseries_document(timeseries,
|
|
|
188
191
|
document = add_timestamp_info_to_document(document, timeseries, ts_format)
|
|
189
192
|
document = {**document, **kwargs}
|
|
190
193
|
|
|
191
|
-
if
|
|
194
|
+
if "_id" not in document: # IDs set by users will not be overwritten
|
|
192
195
|
document["_id"] = get_document_hash(document)
|
|
193
196
|
|
|
194
197
|
if compress_ts_data:
|
|
@@ -425,8 +428,8 @@ def migrate_userdb_to_beanie(ph):
|
|
|
425
428
|
{'$out': 'users'}]
|
|
426
429
|
userdb.aggregate(migration)
|
|
427
430
|
|
|
428
|
-
def get_mongo_client(connection_url=MONGODB_URL, connection_user=MONGODB_USER,
|
|
429
|
-
connection_password=MONGODB_PASSWORD) -> MongoClient:
|
|
431
|
+
def get_mongo_client(connection_url: str = MONGODB_URL, connection_user: str = MONGODB_USER,
|
|
432
|
+
connection_password: str = MONGODB_PASSWORD) -> MongoClient:
|
|
430
433
|
mongo_client_args = {
|
|
431
434
|
"host": connection_url,
|
|
432
435
|
"uuidRepresentation": "standard",
|
|
@@ -438,3 +441,40 @@ def get_mongo_client(connection_url=MONGODB_URL, connection_user=MONGODB_USER,
|
|
|
438
441
|
"password": connection_password,
|
|
439
442
|
}
|
|
440
443
|
return MongoClient(**mongo_client_args)
|
|
444
|
+
|
|
445
|
+
@contextmanager
|
|
446
|
+
def mongo_client(database: str | None = None, collection: str | None = None, connection_url: str = MONGODB_URL,
|
|
447
|
+
connection_user: str = MONGODB_USER, connection_password: str = MONGODB_PASSWORD) -> Iterator[MongoClient | Database | Collection]:
|
|
448
|
+
"""Contextmanager for pymongo MongoClient / Database / Collection with close after use.
|
|
449
|
+
|
|
450
|
+
Parameters
|
|
451
|
+
----------
|
|
452
|
+
database: str or None
|
|
453
|
+
The database to connect to
|
|
454
|
+
collection: str or None
|
|
455
|
+
The collection to connect to
|
|
456
|
+
connection_url: str or None
|
|
457
|
+
Defaults to MONGODB_URL env var
|
|
458
|
+
connection_user: str or None
|
|
459
|
+
Defaults to MONGODB_USER env var
|
|
460
|
+
connection_password: str or None
|
|
461
|
+
Defaults to MONGODB_PASSWORD env var
|
|
462
|
+
|
|
463
|
+
Returns
|
|
464
|
+
-------
|
|
465
|
+
Contextmanager yielding MongoClient / Database / Collection
|
|
466
|
+
"""
|
|
467
|
+
if collection is not None and database is None:
|
|
468
|
+
raise ValueError("Must specify database to access a collection!")
|
|
469
|
+
client = get_mongo_client(connection_url, connection_user, connection_password)
|
|
470
|
+
try:
|
|
471
|
+
if database is not None and collection is not None:
|
|
472
|
+
yield client[database][collection]
|
|
473
|
+
elif database is not None:
|
|
474
|
+
yield client[database]
|
|
475
|
+
else:
|
|
476
|
+
yield client
|
|
477
|
+
finally:
|
|
478
|
+
client.close()
|
|
479
|
+
|
|
480
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pandahub
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Data hub for pandapower and pandapipes networks based on MongoDB
|
|
5
5
|
Author-email: Jan Ulffers <jan.ulffers@iee.fraunhofer.de>, Leon Thurner <leon.thurner@retoflow.de>, Jannis Kupka <jannis.kupka@retoflow.de>, Mike Vogt <mike.vogt@iee.fraunhofer.de>, Joschka Thurner <joschka.thurner@retoflow.de>, Alexander Scheidler <alexander.scheidler@iee.fraunhofer.de>
|
|
6
6
|
License: Copyright (c) 2022 by University of Kassel, Fraunhofer Institute for Energy Economics
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pandahub"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.14" # File format version '__format_version__' is tracked in __init__.py
|
|
8
8
|
authors=[
|
|
9
9
|
{ name = "Jan Ulffers", email = "jan.ulffers@iee.fraunhofer.de" },
|
|
10
10
|
{ name = "Leon Thurner", email = "leon.thurner@retoflow.de" },
|
|
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
|
|
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
|