pandahub 0.3.13__zip → 0.3.15__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.13 → pandahub-0.3.15}/PKG-INFO +1 -1
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/PandaHub.py +76 -38
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/database_toolbox.py +19 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub.egg-info/PKG-INFO +1 -1
- {pandahub-0.3.13 → pandahub-0.3.15}/pyproject.toml +1 -1
- {pandahub-0.3.13 → pandahub-0.3.15}/CHANGELOG.md +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/CONTRIBUTING.rst +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/LICENSE +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/MANIFEST.in +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/README.md +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/dependencies.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/db.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/schemas.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/settings.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/toolbox.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/internal/users.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/main.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/auth.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/net.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/projects.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/timeseries.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/users.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/api/routers/variants.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/datatypes.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/mongodb_indexes.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/timeseries/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/timeseries/data_sources/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/timeseries/data_sources/mongo_data.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub/lib/timeseries/output_writer_mongodb.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub.egg-info/SOURCES.txt +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub.egg-info/dependency_links.txt +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub.egg-info/requires.txt +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/pandahub.egg-info/top_level.txt +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/requirements.txt +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/setup.cfg +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/setup.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/__init__.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/conftest.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/performance_test.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/test_client.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/test_networks.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/test_projects.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/test/test_timeseries.py +0 -0
- {pandahub-0.3.13 → pandahub-0.3.15}/tutorials/config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pandahub
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.15
|
|
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
|
|
@@ -38,6 +38,7 @@ from pandahub.lib.database_toolbox import (
|
|
|
38
38
|
get_dtypes,
|
|
39
39
|
decompress_timeseries_data,
|
|
40
40
|
convert_geojsons,
|
|
41
|
+
get_metadata_for_timeseries_collections
|
|
41
42
|
)
|
|
42
43
|
from pandahub.lib.mongodb_indexes import MONGODB_INDEXES
|
|
43
44
|
|
|
@@ -1674,21 +1675,22 @@ class PandaHub:
|
|
|
1674
1675
|
var_data = {"var_type": "base", "not_in_var": [], "variant": None}
|
|
1675
1676
|
else:
|
|
1676
1677
|
var_data = {"var_type": "addition", "not_in_var": [], "variant": variant}
|
|
1677
|
-
|
|
1678
|
+
net_doc = db["_networks"].find_one({"_id": net_id})
|
|
1678
1679
|
data = []
|
|
1679
1680
|
for elm_data in elements_data:
|
|
1680
|
-
self._add_missing_defaults(
|
|
1681
|
+
self._add_missing_defaults(element_type, elm_data, net_doc)
|
|
1681
1682
|
self._ensure_dtypes(element_type, elm_data)
|
|
1682
1683
|
data.append({**elm_data, **var_data, "net_id": net_id})
|
|
1683
1684
|
collection = self._collection_name_of_element(element_type)
|
|
1684
1685
|
db[collection].insert_many(data, ordered=False)
|
|
1685
1686
|
return data
|
|
1686
1687
|
|
|
1687
|
-
def _add_missing_defaults(self,
|
|
1688
|
+
def _add_missing_defaults(self, element_type, element_data, net_doc):
|
|
1688
1689
|
func_str = f"create_{element_type}"
|
|
1689
|
-
|
|
1690
|
+
package = pp if net_doc['sector'] == 'power' else pps
|
|
1691
|
+
if not hasattr(package, func_str):
|
|
1690
1692
|
return
|
|
1691
|
-
create_func = getattr(
|
|
1693
|
+
create_func = getattr(package, func_str)
|
|
1692
1694
|
sig = signature(create_func)
|
|
1693
1695
|
params = sig.parameters
|
|
1694
1696
|
|
|
@@ -1704,7 +1706,6 @@ class PandaHub:
|
|
|
1704
1706
|
if element_type in ["line", "trafo", "trafo3w"]:
|
|
1705
1707
|
# add standard type values
|
|
1706
1708
|
std_type = element_data["std_type"]
|
|
1707
|
-
net_doc = db["_networks"].find_one({"_id": net_id})
|
|
1708
1709
|
if net_doc is not None:
|
|
1709
1710
|
# std_types = json.loads(net_doc["data"]["std_types"], cls=io_pp.PPJSONDecoder)[element_type]
|
|
1710
1711
|
std_types = net_doc["data"]["std_types"]
|
|
@@ -1715,6 +1716,9 @@ class PandaHub:
|
|
|
1715
1716
|
if element_type == "line":
|
|
1716
1717
|
if "g_us_per_km" not in element_data:
|
|
1717
1718
|
element_data["g_us_per_km"] = 0
|
|
1719
|
+
if element_type in ['sink', 'source']:
|
|
1720
|
+
if not 'mdot_kg_per_s' in element_data:
|
|
1721
|
+
element_data["mdot_kg_per_s"] = None
|
|
1718
1722
|
|
|
1719
1723
|
def _ensure_dtypes(self, element_type, data):
|
|
1720
1724
|
dtypes = self._datatypes.get(element_type)
|
|
@@ -2050,9 +2054,21 @@ class PandaHub:
|
|
|
2050
2054
|
self.check_permission("write")
|
|
2051
2055
|
db = self._get_project_database()
|
|
2052
2056
|
if self.collection_is_timeseries(collection_name, project_id, global_database):
|
|
2053
|
-
metadata
|
|
2054
|
-
|
|
2055
|
-
|
|
2057
|
+
# get metadata dictionary based on the input arguments
|
|
2058
|
+
metadata = get_metadata_for_timeseries_collections(db, data_type=data_type, **kwargs)
|
|
2059
|
+
_id = metadata["_id"]
|
|
2060
|
+
|
|
2061
|
+
# delete overlapping timeseries already in the database
|
|
2062
|
+
filter = {
|
|
2063
|
+
"metadata._id": _id,
|
|
2064
|
+
"timestamp": {
|
|
2065
|
+
"$gte": timeseries.index.min(),
|
|
2066
|
+
"$lte": timeseries.index.max()
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
db.timeseries.delete_many(filter)
|
|
2070
|
+
|
|
2071
|
+
# create new timeseries documents
|
|
2056
2072
|
if isinstance(timeseries, pd.Series):
|
|
2057
2073
|
documents = [
|
|
2058
2074
|
{"metadata": metadata, "timestamp": idx, "value": value}
|
|
@@ -2063,7 +2079,12 @@ class PandaHub:
|
|
|
2063
2079
|
{"metadata": metadata, "timestamp": idx, **row.to_dict()}
|
|
2064
2080
|
for idx, row in timeseries.iterrows()
|
|
2065
2081
|
]
|
|
2066
|
-
|
|
2082
|
+
db[collection_name].insert_many(documents)
|
|
2083
|
+
|
|
2084
|
+
if kwargs.get("return_id"):
|
|
2085
|
+
return _id
|
|
2086
|
+
return None
|
|
2087
|
+
|
|
2067
2088
|
document = create_timeseries_document(
|
|
2068
2089
|
timeseries=timeseries,
|
|
2069
2090
|
data_type=data_type,
|
|
@@ -2328,19 +2349,22 @@ class PandaHub:
|
|
|
2328
2349
|
self.check_permission("read")
|
|
2329
2350
|
db = self._get_project_database()
|
|
2330
2351
|
if self.collection_is_timeseries(collection_name, project_id, global_database):
|
|
2331
|
-
|
|
2332
|
-
"metadata." + key: value for key, value in filter_document.items()
|
|
2333
|
-
}
|
|
2352
|
+
metadata = get_metadata_for_timeseries_collections(db, **kwargs)
|
|
2334
2353
|
pipeline = []
|
|
2335
|
-
pipeline.append({"$match":
|
|
2354
|
+
pipeline.append({"$match": {"metadata._id": metadata["_id"]}})
|
|
2336
2355
|
pipeline.append({"$project": {"_id": 0, "metadata": 0}})
|
|
2337
2356
|
timeseries = db[collection_name].aggregate_pandas_all(pipeline)
|
|
2357
|
+
if len(timeseries) == 0:
|
|
2358
|
+
raise PandaHubError("no documents matching the provided filter found", 404)
|
|
2338
2359
|
timeseries.set_index("timestamp", inplace=True)
|
|
2339
2360
|
if include_metadata:
|
|
2340
2361
|
raise NotImplementedError(
|
|
2341
2362
|
"Not implemented yet for timeseries collections"
|
|
2342
2363
|
)
|
|
2343
|
-
|
|
2364
|
+
if len(timeseries.columns) == 1:
|
|
2365
|
+
return timeseries[timeseries.columns[0]]
|
|
2366
|
+
else:
|
|
2367
|
+
return timeseries
|
|
2344
2368
|
filter_document = {**filter_document, **kwargs}
|
|
2345
2369
|
pipeline = [{"$match": filter_document}]
|
|
2346
2370
|
if not compressed_ts_data:
|
|
@@ -2427,6 +2451,7 @@ class PandaHub:
|
|
|
2427
2451
|
collection_name="timeseries",
|
|
2428
2452
|
global_database=False,
|
|
2429
2453
|
project_id=None,
|
|
2454
|
+
timestamp_range=None,
|
|
2430
2455
|
):
|
|
2431
2456
|
"""
|
|
2432
2457
|
Returns a DataFrame, containing all metadata matching the provided filter.
|
|
@@ -2467,10 +2492,17 @@ class PandaHub:
|
|
|
2467
2492
|
pipeline.append({"$match": document_filter})
|
|
2468
2493
|
else:
|
|
2469
2494
|
document_filter = {}
|
|
2495
|
+
if timestamp_range is not None:
|
|
2496
|
+
document_filter["timestamp"] = {
|
|
2497
|
+
"$gte": timestamp_range[0],
|
|
2498
|
+
"$lt": timestamp_range[1],
|
|
2499
|
+
}
|
|
2470
2500
|
document = db[collection_name].find_one(
|
|
2471
2501
|
document_filter, projection={"timestamp": 0, "_id": 0}
|
|
2472
2502
|
)
|
|
2473
|
-
|
|
2503
|
+
if document is None:
|
|
2504
|
+
return pd.DataFrame()
|
|
2505
|
+
value_fields = ["$%s" % field for field in document.keys() if field != "metadata"]
|
|
2474
2506
|
group_dict = {
|
|
2475
2507
|
"_id": "$metadata._id",
|
|
2476
2508
|
"max_value": {"$max": {"$max": value_fields}},
|
|
@@ -2595,27 +2627,30 @@ class PandaHub:
|
|
|
2595
2627
|
document_filter,
|
|
2596
2628
|
projection={"timestamp": 0, "metadata": 0, "_id": 0},
|
|
2597
2629
|
)
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
"
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2630
|
+
if document is None:
|
|
2631
|
+
meta_data = {}
|
|
2632
|
+
else:
|
|
2633
|
+
meta_pipeline = []
|
|
2634
|
+
meta_pipeline.append({"$match": document_filter})
|
|
2635
|
+
value_fields = ["$%s" % field for field in document.keys()]
|
|
2636
|
+
group_dict = {
|
|
2637
|
+
"_id": "$metadata._id",
|
|
2638
|
+
"max_value": {"$max": {"$max": value_fields}},
|
|
2639
|
+
"min_value": {"$min": {"$min": value_fields}},
|
|
2640
|
+
"first_timestamp": {"$min": "$timestamp"},
|
|
2641
|
+
"last_timestamp": {"$max": "$timestamp"},
|
|
2642
|
+
}
|
|
2643
|
+
document = db[collection_name].find_one(document_filter)
|
|
2644
|
+
metadata_fields = {
|
|
2645
|
+
metadata_field: {"$first": "$metadata.%s" % metadata_field}
|
|
2646
|
+
for metadata_field in document["metadata"].keys()
|
|
2647
|
+
if metadata_field != "_id"
|
|
2648
|
+
}
|
|
2649
|
+
group_dict.update(metadata_fields)
|
|
2650
|
+
meta_pipeline.append({"$group": group_dict})
|
|
2651
|
+
meta_data = {
|
|
2652
|
+
d["_id"]: d for d in db[collection_name].aggregate(meta_pipeline)
|
|
2653
|
+
}
|
|
2619
2654
|
timeseries = []
|
|
2620
2655
|
ts_all = db[collection_name].aggregate_pandas_all(pipeline)
|
|
2621
2656
|
if len(ts_all) == 0:
|
|
@@ -2961,7 +2996,9 @@ class PandaHub:
|
|
|
2961
2996
|
"""
|
|
2962
2997
|
self.check_permission("write")
|
|
2963
2998
|
db = self._get_project_database()
|
|
2964
|
-
|
|
2999
|
+
if self.collection_is_timeseries(collection_name):
|
|
3000
|
+
metadata = get_metadata_for_timeseries_collections(db, data_type, **kwargs)
|
|
3001
|
+
return db[collection_name].delete_many({"metadata._id": metadata["_id"]})
|
|
2965
3002
|
filter_document = {"element_type": element_type, "data_type": data_type}
|
|
2966
3003
|
if netname is not None:
|
|
2967
3004
|
filter_document["netname"] = netname
|
|
@@ -3154,6 +3191,7 @@ class PandaHub:
|
|
|
3154
3191
|
return self.get_net_collections(db, with_areas)
|
|
3155
3192
|
|
|
3156
3193
|
|
|
3194
|
+
|
|
3157
3195
|
if __name__ == "__main__":
|
|
3158
3196
|
self = PandaHub()
|
|
3159
3197
|
project_name = "test_project"
|
|
@@ -478,3 +478,22 @@ def mongo_client(database: str | None = None, collection: str | None = None, con
|
|
|
478
478
|
client.close()
|
|
479
479
|
|
|
480
480
|
|
|
481
|
+
def get_metadata_for_timeseries_collections(db, data_type=None, net_id=None, element_type=None, element_index=None, **kwargs):
|
|
482
|
+
if element_type is None:
|
|
483
|
+
raise ValueError("element_type needs to be defined for timeseries collections")
|
|
484
|
+
if element_index is None:
|
|
485
|
+
raise ValueError("element_index needs to be defined for timeseries collections")
|
|
486
|
+
if data_type is None:
|
|
487
|
+
raise ValueError("data_type needs to be defined for timeseries collections")
|
|
488
|
+
if net_id is None:
|
|
489
|
+
net_ids = db["_networks"].distinct("_id")
|
|
490
|
+
if len(net_ids) == 1:
|
|
491
|
+
net_id = net_ids[0]
|
|
492
|
+
else:
|
|
493
|
+
raise ValueError(
|
|
494
|
+
"No net_id was provided and multiple networks exist in the database. "
|
|
495
|
+
"Please provide a net_id."
|
|
496
|
+
)
|
|
497
|
+
metadata = {"data_type": data_type, "net_id": net_id, "element_type": element_type, "element_index": element_index, **kwargs}
|
|
498
|
+
metadata["_id"] = f"{net_id}_{element_type}_{element_index}_{data_type}"
|
|
499
|
+
return metadata
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pandahub
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.15
|
|
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.15" # 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
|
|
File without changes
|
|
File without changes
|