pandahub 0.3.5__zip → 0.3.6__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.
Files changed (55) hide show
  1. {pandahub-0.3.5 → pandahub-0.3.6}/CHANGELOG.md +7 -0
  2. {pandahub-0.3.5 → pandahub-0.3.6}/PKG-INFO +10 -70
  3. pandahub-0.3.6/README.md +16 -0
  4. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/__init__.py +0 -1
  5. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/db.py +4 -5
  6. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/settings.py +24 -19
  7. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/main.py +1 -1
  8. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/PandaHub.py +17 -19
  9. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub.egg-info/PKG-INFO +10 -70
  10. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub.egg-info/SOURCES.txt +8 -11
  11. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub.egg-info/requires.txt +1 -17
  12. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub.egg-info/top_level.txt +1 -0
  13. {pandahub-0.3.5 → pandahub-0.3.6}/pyproject.toml +5 -20
  14. pandahub-0.3.6/requirements.txt +13 -0
  15. pandahub-0.3.6/test/conftest.py +21 -0
  16. pandahub-0.3.5/AUTHORS +0 -6
  17. pandahub-0.3.5/README.md +0 -75
  18. pandahub-0.3.5/pandahub/client/PandaHubClient.py +0 -149
  19. pandahub-0.3.5/pandahub/client/user_management.py +0 -56
  20. pandahub-0.3.5/pandahub/test/conftest.py +0 -49
  21. pandahub-0.3.5/pandahub/test/test_client.py +0 -23
  22. {pandahub-0.3.5 → pandahub-0.3.6}/CONTRIBUTING.rst +0 -0
  23. {pandahub-0.3.5 → pandahub-0.3.6}/LICENSE +0 -0
  24. {pandahub-0.3.5 → pandahub-0.3.6}/MANIFEST.in +0 -0
  25. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/__init__.py +0 -0
  26. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/dependencies.py +0 -0
  27. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/__init__.py +0 -0
  28. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/schemas.py +0 -0
  29. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/toolbox.py +0 -0
  30. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/internal/users.py +0 -0
  31. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/__init__.py +0 -0
  32. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/auth.py +0 -0
  33. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/net.py +0 -0
  34. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/projects.py +0 -0
  35. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/timeseries.py +0 -0
  36. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/users.py +0 -0
  37. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/api/routers/variants.py +0 -0
  38. {pandahub-0.3.5/pandahub/client → pandahub-0.3.6/pandahub/lib}/__init__.py +0 -0
  39. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/database_toolbox.py +0 -0
  40. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/datatypes.py +0 -0
  41. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/mongodb_indexes.py +0 -0
  42. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/timeseries/__init__.py +0 -0
  43. {pandahub-0.3.5/pandahub/lib → pandahub-0.3.6/pandahub/lib/timeseries/data_sources}/__init__.py +0 -0
  44. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/timeseries/data_sources/mongo_data.py +0 -0
  45. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub/lib/timeseries/output_writer_mongodb.py +0 -0
  46. {pandahub-0.3.5 → pandahub-0.3.6}/pandahub.egg-info/dependency_links.txt +0 -0
  47. {pandahub-0.3.5 → pandahub-0.3.6}/setup.cfg +0 -0
  48. {pandahub-0.3.5 → pandahub-0.3.6}/setup.py +0 -0
  49. {pandahub-0.3.5/pandahub → pandahub-0.3.6}/test/__init__.py +0 -0
  50. {pandahub-0.3.5/pandahub → pandahub-0.3.6}/test/performance_test.py +0 -0
  51. /pandahub-0.3.5/pandahub/lib/timeseries/data_sources/__init__.py → /pandahub-0.3.6/test/test_client.py +0 -0
  52. {pandahub-0.3.5/pandahub → pandahub-0.3.6}/test/test_networks.py +0 -0
  53. {pandahub-0.3.5/pandahub → pandahub-0.3.6}/test/test_projects.py +0 -0
  54. {pandahub-0.3.5/pandahub → pandahub-0.3.6}/test/test_timeseries.py +0 -0
  55. {pandahub-0.3.5 → pandahub-0.3.6}/tutorials/config.py +0 -0
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## [0.3.6]
4
+
5
+ - IMPROVED consider realm when activating project by name
6
+ - IMPROVED housekeeping: clean up project layout, Docker, settings and remove PandaHubClient
7
+ - IMPROVED access of correct collection in get_net_ids
8
+ - IMPROVED cleaner project version upgrades (early exit, log spam)
9
+
3
10
  ## [0.3.5]
4
11
 
5
12
  - Fixed version and repaired pyproject.toml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pandahub
3
- Version: 0.3.5
3
+ Version: 0.3.6
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
@@ -58,80 +58,20 @@ Provides-Extra: docs
58
58
  Provides-Extra: test
59
59
  Provides-Extra: all
60
60
  License-File: LICENSE
61
- License-File: AUTHORS
62
61
 
63
62
  [![pandapower](https://www.pandapower.org/images/pp.svg)](https://www.pandapower.org) [![pandapipes](https://www.pandapipes.org/images/pp.svg)](https://www.pandapipes.org)
64
63
 
65
64
  [![pandahub](https://badge.fury.io/py/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/pypi/pyversions/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/e2nIEE/pandahub/blob/master/LICENSE)
66
65
 
66
+ pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and
67
+ pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly through the PandaHub class,
68
+ but also provides a REST-API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
67
69
 
68
- pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly for local development, but also includes a client/server architecture that exposes all relevant methods as an API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
70
+ ## Development
71
+ `docker compose up -d` runs a mongodb container alongside a pandahub api instance with live reload available
72
+ at http://localhost:8002. To connect to an existing database instead, set `MONGODB_URL` to the connection string through an environment variable / in you `.env` file.
69
73
 
70
- ## Setup a local pandahub api
74
+ Swagger UI is available at http://localhost:8002/docs.
71
75
 
72
- Steps to test the client/server structure locally:
73
-
74
- 1. Start a MongoDB on localhost:27017 (or another custom port)
75
-
76
- 2. Start the uvicorn server that exposes the API by navigating to "pandahub/api" and running:
77
-
78
- ```
79
- # windows
80
- set SECRET=secret & python main.py
81
-
82
- # linux
83
- SECRET=secret python main.py
84
- ```
85
-
86
- or if you don't run mongodb on the default port (27017)
87
-
88
- ```
89
- # windows
90
- set MONGODB_URL=mongodb://localhost:[mongo-port] & set SECRET=secret & python main.py
91
-
92
- # linux
93
- MONGODB_URL=mongodb://localhost:[mongo-port] SECRET=secret python main.py
94
- ```
95
-
96
- The API should now run on http://localhost:8002
97
-
98
- >**Note**
99
- >A full documentation of all api endpoints can be seen at http://localhost:8002/docs
100
-
101
- >**Note 2**
102
- >You can avoid always setting the environment variables for SECRET and MONGODB_URL by creating an `.env` file in `pandahub/api/` with the following content:
103
- >```
104
- >SECRET=secret
105
- >MONGODB_URL=mongodb://localhost:[mongo-port]
106
- >```
107
-
108
- ## Develop with Docker
109
-
110
- `docker compose up` starts a mongodb container alongside pandahub with live reload available at http://localhost:8002.
111
-
112
- If you want to connect to a running database, set the database url and specify only docker-compose.yml:
113
-
114
- MONGODB_URL=mongodb://localhost:[mongo-port] docker compose -f docker-compose.yml up
115
-
116
-
117
-
118
- ## Use pandahub api with pandahub client
119
-
120
- 1. Login with the pandahub client
121
-
122
- There are two ways to login with pandahub client
123
-
124
- - If you installed pandahub by pip or with setup.py just run `pandahub-login` in your shell.
125
-
126
- OR
127
-
128
- - Run the following in your python or IPython shell:
129
-
130
- ```
131
- from pandahub.client.user_management import login
132
- login()
133
- ```
134
-
135
- This will guide you through the login process.
136
-
137
- 2. You only need to login once. After you logged in successfully a configuration file (pandahub.config) containing an authentication token is created in your home directory and will be used every time you use the pandahub client. You only need to login again if you want to use a different instance of the pandahub api.
76
+ If you develop on the library and do not need the fastapi app, `docker compose up db -d` starts only the mongodb
77
+ container.
@@ -0,0 +1,16 @@
1
+ [![pandapower](https://www.pandapower.org/images/pp.svg)](https://www.pandapower.org) [![pandapipes](https://www.pandapipes.org/images/pp.svg)](https://www.pandapipes.org)
2
+
3
+ [![pandahub](https://badge.fury.io/py/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/pypi/pyversions/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/e2nIEE/pandahub/blob/master/LICENSE)
4
+
5
+ pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and
6
+ pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly through the PandaHub class,
7
+ but also provides a REST-API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
8
+
9
+ ## Development
10
+ `docker compose up -d` runs a mongodb container alongside a pandahub api instance with live reload available
11
+ at http://localhost:8002. To connect to an existing database instead, set `MONGODB_URL` to the connection string through an environment variable / in you `.env` file.
12
+
13
+ Swagger UI is available at http://localhost:8002/docs.
14
+
15
+ If you develop on the library and do not need the fastapi app, `docker compose up db -d` starts only the mongodb
16
+ container.
@@ -3,4 +3,3 @@ import importlib.metadata
3
3
  __version__ = importlib.metadata.version("pandahub")
4
4
 
5
5
  from pandahub.lib.PandaHub import PandaHub, PandaHubError
6
- from pandahub.client.PandaHubClient import PandaHubClient
@@ -9,13 +9,12 @@ from fastapi_users_db_beanie.access_token import (
9
9
  BeanieBaseAccessToken,
10
10
  )
11
11
 
12
- from pandahub.api.internal.settings import REGISTRATION_ADMIN_APPROVAL
13
- from pandahub.api.internal import settings
12
+ from pandahub.api.internal.settings import REGISTRATION_ADMIN_APPROVAL, MONGODB_URL, MONGODB_USER, MONGODB_PASSWORD
14
13
  from pydantic import Field
15
14
 
16
- mongo_client_args = {"host": settings.MONGODB_URL, "uuidRepresentation": "standard", "connect": False}
17
- if settings.MONGODB_USER:
18
- mongo_client_args |= {"username": settings.MONGODB_USER, "password": settings.MONGODB_PASSWORD}
15
+ mongo_client_args = {"host": MONGODB_URL, "uuidRepresentation": "standard", "connect": False}
16
+ if MONGODB_USER:
17
+ mongo_client_args |= {"username": MONGODB_USER, "password": MONGODB_PASSWORD}
19
18
 
20
19
  client = motor.motor_asyncio.AsyncIOMotorClient(**mongo_client_args)
21
20
  client.get_io_loop = asyncio.get_event_loop
@@ -1,8 +1,13 @@
1
1
  from dotenv import load_dotenv
2
2
  import os
3
3
 
4
+ def get_os_env(key, default=None):
5
+ value = os.getenv(key, default)
6
+ value = default if value == "" else value
7
+ return value
8
+
4
9
  def settings_bool(var_name, default=None):
5
- var = os.getenv(var_name)
10
+ var = get_os_env(var_name)
6
11
  if var is None:
7
12
  return default
8
13
  if isinstance(var, str) and var.lower() == "true":
@@ -12,7 +17,7 @@ def settings_bool(var_name, default=None):
12
17
  return False
13
18
 
14
19
  def get_secret(key, default=None):
15
- secret = os.getenv(key, default)
20
+ secret = get_os_env(key, default)
16
21
  if secret and os.path.isfile(secret):
17
22
  with open(secret) as f:
18
23
  secret = f.read()
@@ -21,28 +26,28 @@ def get_secret(key, default=None):
21
26
  # load variables from .env to environment variables
22
27
  load_dotenv()
23
28
 
24
- MONGODB_URL = get_secret("MONGODB_URL") or "mongodb://localhost:27017"
25
- MONGODB_USER = get_secret("MONGODB_USER") or None
26
- MONGODB_PASSWORD = get_secret("MONGODB_PASSWORD") or None
29
+ MONGODB_URL = get_secret("MONGODB_URL", "mongodb://localhost:27017")
30
+ MONGODB_USER = get_secret("MONGODB_USER")
31
+ MONGODB_PASSWORD = get_secret("MONGODB_PASSWORD")
27
32
 
28
- MONGODB_GLOBAL_DATABASE_URL = get_secret("MONGODB_GLOBAL_DATABASE_URL") or None
29
- MONGODB_GLOBAL_DATABASE_USER = get_secret("MONGODB_GLOBAL_DATABASE_USER") or None
30
- MONGODB_GLOBAL_DATABASE_PASSWORD = get_secret("MONGODB_GLOBAL_DATABASE_PASSWORD") or None
33
+ MONGODB_GLOBAL_DATABASE_URL = get_secret("MONGODB_GLOBAL_DATABASE_URL")
34
+ MONGODB_GLOBAL_DATABASE_USER = get_secret("MONGODB_GLOBAL_DATABASE_USER")
35
+ MONGODB_GLOBAL_DATABASE_PASSWORD = get_secret("MONGODB_GLOBAL_DATABASE_PASSWORD")
31
36
  if not MONGODB_GLOBAL_DATABASE_URL:
32
- MONGODB_GLOBAL_DATABASE_URL = os.getenv("MONGODB_URL_GLOBAL_DATABASE") or None
37
+ MONGODB_GLOBAL_DATABASE_URL = get_os_env("MONGODB_URL_GLOBAL_DATABASE")
33
38
 
34
39
  EMAIL_VERIFICATION_REQUIRED = settings_bool("EMAIL_VERIFICATION_REQUIRED", default=False)
35
40
 
36
- MAIL_USERNAME = os.getenv("MAIL_USERNAME") or "dummy@mail.de"
37
- MAIL_PASSWORD = os.getenv("MAIL_PASSWORD") or ""
38
- MAIL_PORT = os.getenv("MAIL_PORT") or 587
39
- MAIL_SMTP_SERVER = os.getenv("MAIL_SMTP_SERVER") or ""
41
+ MAIL_USERNAME = get_os_env("MAIL_USERNAME", "dummy@mail.de")
42
+ MAIL_PASSWORD = get_os_env("MAIL_PASSWORD", "")
43
+ MAIL_PORT = get_os_env("MAIL_PORT", 587)
44
+ MAIL_SMTP_SERVER = get_os_env("MAIL_SMTP_SERVER", "")
40
45
  MAIL_STARTTLS = settings_bool("MAIL_STARTTLS", default=True)
41
46
  MAIL_SSL_TLS = settings_bool("MAIL_SSL_TLS", default=False)
42
47
 
43
- PASSWORD_RESET_URL = os.getenv("PASSWORD_RESET_URL") or ""
44
- EMAIL_VERIFY_URL = os.getenv("EMAIL_VERIFY_URL") or ""
45
- SECRET = get_secret("SECRET") or None
48
+ PASSWORD_RESET_URL = get_os_env("PASSWORD_RESET_URL", "")
49
+ EMAIL_VERIFY_URL = get_os_env("EMAIL_VERIFY_URL", "")
50
+ SECRET = get_secret("SECRET")
46
51
 
47
52
  REGISTRATION_ENABLED = settings_bool("REGISTRATION_ENABLED", default=True)
48
53
  REGISTRATION_ADMIN_APPROVAL = settings_bool("REGISTRATION_ADMIN_APPROVAL", default=False)
@@ -50,6 +55,6 @@ REGISTRATION_ADMIN_APPROVAL = settings_bool("REGISTRATION_ADMIN_APPROVAL", defau
50
55
  CREATE_INDEXES_WITH_PROJECT = settings_bool("CREATE_INDEXES_WITH_PROJECT", default=True)
51
56
 
52
57
  DEBUG = settings_bool("DEBUG", default=False)
53
- PANDAHUB_SERVER_URL = os.getenv("PANDAHUB_SERVER_URL", "0.0.0.0")
54
- PANDAHUB_SERVER_PORT = int(os.getenv('PANDAHUB_SERVER_PORT', 8002))
55
- WORKERS = int(os.getenv('WORKER', 2))
58
+ PANDAHUB_SERVER_URL = get_os_env("PANDAHUB_SERVER_URL", "0.0.0.0")
59
+ PANDAHUB_SERVER_PORT = int(get_os_env('PANDAHUB_SERVER_PORT', 8002))
60
+ WORKERS = int(get_os_env('WORKER', 2))
@@ -61,7 +61,7 @@ async def ready():
61
61
 
62
62
 
63
63
  if __name__ == "__main__":
64
- uvicorn.run("main:app",
64
+ uvicorn.run("pandahub.api.main:app",
65
65
  host=settings.PANDAHUB_SERVER_URL,
66
66
  port=settings.PANDAHUB_SERVER_PORT,
67
67
  log_level="info",
@@ -234,14 +234,11 @@ class PandaHub:
234
234
  project_data["_id"] = project_id
235
235
  if self.user_id is not None:
236
236
  project_data["users"] = {self.user_id: "owner"}
237
- id = self.mongo_client["user_management"]["projects"].insert_one(project_data).inserted_id
237
+ self.mongo_client["user_management"]["projects"].insert_one(project_data)
238
238
  if CREATE_INDEXES_WITH_PROJECT:
239
239
  self._create_mongodb_indexes(project_data["_id"])
240
240
  if activate:
241
- if "_id" in project_data.keys():
242
- id = project_data["_id"]
243
-
244
- self.set_active_project_by_id(id)
241
+ self.set_active_project_by_id(project_data["_id"])
245
242
  return project_data
246
243
 
247
244
  def delete_project(self, i_know_this_action_is_final=False, project_id=None):
@@ -257,15 +254,16 @@ class PandaHub:
257
254
  self.mongo_client.user_management.projects.delete_one({"_id": project_id})
258
255
  self.active_project = None
259
256
 
260
- def get_projects(self):
257
+ def get_projects(self, realm: Optional[str] = None):
258
+ filter_dict = {}
261
259
  if self.user_id is not None:
262
260
  user = self._get_user()
263
- if user["is_superuser"]:
264
- filter_dict = {}
265
- else:
261
+ if not user["is_superuser"]:
266
262
  filter_dict = {"users.{}".format(self.user_id): {"$exists": True}}
267
263
  else:
268
264
  filter_dict = {"users": {"$exists": False}}
265
+ if realm is not None:
266
+ filter_dict["realm"] = realm
269
267
  db = self.mongo_client["user_management"]
270
268
  projects = list(db["projects"].find(filter_dict))
271
269
  return [
@@ -287,7 +285,7 @@ class PandaHub:
287
285
  ]
288
286
 
289
287
  def set_active_project(self, project_name:str, realm=None):
290
- projects = self.get_projects()
288
+ projects = self.get_projects(realm=realm)
291
289
  active_projects = [
292
290
  project for project in projects if project["name"] == project_name
293
291
  ]
@@ -459,7 +457,7 @@ class PandaHub:
459
457
  """
460
458
  if not self.active_project:
461
459
  raise PandaHubError("No project activated!")
462
- return self.get_project_database("_network").find({}, {"_id:": 1}).distinct("_id")
460
+ return self.get_project_database("_networks").find({}, {"_id:": 1}).distinct("_id")
463
461
 
464
462
  def get_project_version(self):
465
463
  return self.active_project.get("version", "0.2.2")
@@ -469,6 +467,9 @@ class PandaHub:
469
467
  # TODO these operations should be encapsulated in a transaction in order to avoid
470
468
  # inconsistent Database states in case of occuring errors
471
469
 
470
+ if self.active_project["version"] == __version__:
471
+ return
472
+
472
473
  if version.parse(self.get_project_version()) < version.parse("0.2.3"):
473
474
  db = self._get_project_database()
474
475
  all_collection_names = db.list_collection_names()
@@ -482,9 +483,6 @@ class PandaHub:
482
483
 
483
484
  for element in old_net_collections:
484
485
  db[element].rename(self._collection_name_of_element(element))
485
-
486
- if version.parse(self.get_project_version()) < version.parse("0.2.3"):
487
- db = self._get_project_database()
488
486
  # for all networks
489
487
  for d in list(
490
488
  db["_networks"].find({}, projection={"sector": 1, "data": 1})
@@ -504,17 +502,17 @@ class PandaHub:
504
502
  except:
505
503
  dat = f"serialized_{json.dumps(data, cls=io_pp.PPJSONEncoder)}"
506
504
  data[key] = dat
507
-
508
505
  db["_networks"].update_one({"_id": d["_id"]}, {"$set": {"data": data}})
509
506
 
507
+ logger.info(
508
+ f"upgraded projekt '{self.active_project['name']}' from version"
509
+ f" {self.get_project_version()} to version 0.2.3"
510
+ )
511
+
510
512
  project_collection = self.mongo_client["user_management"].projects
511
513
  project_collection.update_one(
512
514
  {"_id": self.active_project["_id"]}, {"$set": {"version": __version__}}
513
515
  )
514
- logger.info(
515
- f"upgraded projekt '{self.active_project['name']}' from version"
516
- f" {self.get_project_version()} to version {__version__}"
517
- )
518
516
  self.active_project["version"] = __version__
519
517
 
520
518
  # -------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pandahub
3
- Version: 0.3.5
3
+ Version: 0.3.6
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
@@ -58,80 +58,20 @@ Provides-Extra: docs
58
58
  Provides-Extra: test
59
59
  Provides-Extra: all
60
60
  License-File: LICENSE
61
- License-File: AUTHORS
62
61
 
63
62
  [![pandapower](https://www.pandapower.org/images/pp.svg)](https://www.pandapower.org) [![pandapipes](https://www.pandapipes.org/images/pp.svg)](https://www.pandapipes.org)
64
63
 
65
64
  [![pandahub](https://badge.fury.io/py/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/pypi/pyversions/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/e2nIEE/pandahub/blob/master/LICENSE)
66
65
 
66
+ pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and
67
+ pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly through the PandaHub class,
68
+ but also provides a REST-API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
67
69
 
68
- pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly for local development, but also includes a client/server architecture that exposes all relevant methods as an API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
70
+ ## Development
71
+ `docker compose up -d` runs a mongodb container alongside a pandahub api instance with live reload available
72
+ at http://localhost:8002. To connect to an existing database instead, set `MONGODB_URL` to the connection string through an environment variable / in you `.env` file.
69
73
 
70
- ## Setup a local pandahub api
74
+ Swagger UI is available at http://localhost:8002/docs.
71
75
 
72
- Steps to test the client/server structure locally:
73
-
74
- 1. Start a MongoDB on localhost:27017 (or another custom port)
75
-
76
- 2. Start the uvicorn server that exposes the API by navigating to "pandahub/api" and running:
77
-
78
- ```
79
- # windows
80
- set SECRET=secret & python main.py
81
-
82
- # linux
83
- SECRET=secret python main.py
84
- ```
85
-
86
- or if you don't run mongodb on the default port (27017)
87
-
88
- ```
89
- # windows
90
- set MONGODB_URL=mongodb://localhost:[mongo-port] & set SECRET=secret & python main.py
91
-
92
- # linux
93
- MONGODB_URL=mongodb://localhost:[mongo-port] SECRET=secret python main.py
94
- ```
95
-
96
- The API should now run on http://localhost:8002
97
-
98
- >**Note**
99
- >A full documentation of all api endpoints can be seen at http://localhost:8002/docs
100
-
101
- >**Note 2**
102
- >You can avoid always setting the environment variables for SECRET and MONGODB_URL by creating an `.env` file in `pandahub/api/` with the following content:
103
- >```
104
- >SECRET=secret
105
- >MONGODB_URL=mongodb://localhost:[mongo-port]
106
- >```
107
-
108
- ## Develop with Docker
109
-
110
- `docker compose up` starts a mongodb container alongside pandahub with live reload available at http://localhost:8002.
111
-
112
- If you want to connect to a running database, set the database url and specify only docker-compose.yml:
113
-
114
- MONGODB_URL=mongodb://localhost:[mongo-port] docker compose -f docker-compose.yml up
115
-
116
-
117
-
118
- ## Use pandahub api with pandahub client
119
-
120
- 1. Login with the pandahub client
121
-
122
- There are two ways to login with pandahub client
123
-
124
- - If you installed pandahub by pip or with setup.py just run `pandahub-login` in your shell.
125
-
126
- OR
127
-
128
- - Run the following in your python or IPython shell:
129
-
130
- ```
131
- from pandahub.client.user_management import login
132
- login()
133
- ```
134
-
135
- This will guide you through the login process.
136
-
137
- 2. You only need to login once. After you logged in successfully a configuration file (pandahub.config) containing an authentication token is created in your home directory and will be used every time you use the pandahub client. You only need to login again if you want to use a different instance of the pandahub api.
76
+ If you develop on the library and do not need the fastapi app, `docker compose up db -d` starts only the mongodb
77
+ container.
@@ -1,10 +1,10 @@
1
- AUTHORS
2
1
  CHANGELOG.md
3
2
  CONTRIBUTING.rst
4
3
  LICENSE
5
4
  MANIFEST.in
6
5
  README.md
7
6
  pyproject.toml
7
+ requirements.txt
8
8
  setup.py
9
9
  pandahub/__init__.py
10
10
  pandahub.egg-info/PKG-INFO
@@ -28,9 +28,6 @@ pandahub/api/routers/projects.py
28
28
  pandahub/api/routers/timeseries.py
29
29
  pandahub/api/routers/users.py
30
30
  pandahub/api/routers/variants.py
31
- pandahub/client/PandaHubClient.py
32
- pandahub/client/__init__.py
33
- pandahub/client/user_management.py
34
31
  pandahub/lib/PandaHub.py
35
32
  pandahub/lib/__init__.py
36
33
  pandahub/lib/database_toolbox.py
@@ -40,11 +37,11 @@ pandahub/lib/timeseries/__init__.py
40
37
  pandahub/lib/timeseries/output_writer_mongodb.py
41
38
  pandahub/lib/timeseries/data_sources/__init__.py
42
39
  pandahub/lib/timeseries/data_sources/mongo_data.py
43
- pandahub/test/__init__.py
44
- pandahub/test/conftest.py
45
- pandahub/test/performance_test.py
46
- pandahub/test/test_client.py
47
- pandahub/test/test_networks.py
48
- pandahub/test/test_projects.py
49
- pandahub/test/test_timeseries.py
40
+ test/__init__.py
41
+ test/conftest.py
42
+ test/performance_test.py
43
+ test/test_client.py
44
+ test/test_networks.py
45
+ test/test_projects.py
46
+ test/test_timeseries.py
50
47
  tutorials/config.py
@@ -1,19 +1,3 @@
1
- uvicorn>=0.24.0
2
- fastapi-users[beanie]>=12.0
3
- fastapi>=0.104.0
4
- fastapi-mail>=1.4.1
5
- pandapower~=2.14
6
- pandapipes>=0.7.0
7
- pymongo
8
- pydantic
9
- simplejson
10
- requests<2.28.0
11
- python-dotenv
12
- pymongoarrow
13
- blosc
14
- motor<3.0.0
15
- hypothesis-graphql<0.10.0
16
- attrs>=22.2.0
17
1
 
18
2
  [all]
19
3
  numpydoc
@@ -21,7 +5,7 @@ sphinx
21
5
  sphinx_rtd_theme
22
6
  sphinxcontrib.bibtex
23
7
  sphinx-pyproject
24
- pytest<8.0.0
8
+ pytest
25
9
  pytest-xdist
26
10
  nbmake
27
11
  simbench
@@ -1,2 +1,3 @@
1
1
  pandahub
2
+ test
2
3
  tutorials
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pandahub"
7
- version = "0.3.5" # File format version '__format_version__' is tracked in __init__.py
7
+ version = "0.3.6" # 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" },
@@ -35,24 +35,6 @@ classifiers = [
35
35
  "Programming Language :: Python :: 3.11",
36
36
  "Programming Language :: Python :: 3.12"
37
37
  ]
38
- dependencies = [
39
- "uvicorn>=0.24.0",
40
- "fastapi-users[beanie]>=12.0",
41
- "fastapi>=0.104.0",
42
- "fastapi-mail>=1.4.1",
43
- "pandapower~=2.14",
44
- "pandapipes>=0.7.0",
45
- "pymongo",
46
- "pydantic",
47
- "simplejson",
48
- "requests<2.28.0",
49
- "python-dotenv",
50
- "pymongoarrow",
51
- "blosc",
52
- "motor<3.0.0",
53
- "hypothesis-graphql<0.10.0",
54
- "attrs>=22.2.0"
55
- ]
56
38
  keywords = [
57
39
  "network", "analysis", "optimization", "automation", "grid", "energy", "engineering", "simulation",
58
40
  ]
@@ -66,12 +48,15 @@ Issues = "https://github.com/e2nIEE/pandahub/issues"
66
48
  Download = "https://pypi.org/project/pandahub/#files"
67
49
  Changelog = "https://github.com/e2nIEE/pandahub/blob/develop/CHANGELOG.md"
68
50
 
51
+ [tool.setuptools.dynamic]
52
+ dependencies = { file = ["requirements.txt"] }
53
+
69
54
  [project.optional-dependencies]
70
55
  docs = ["numpydoc", "sphinx", "sphinx_rtd_theme", "sphinxcontrib.bibtex", "sphinx-pyproject"]
71
56
  test = ["pytest", "pytest-xdist", "nbmake", "simbench", "line_profiler"]
72
57
  all = [
73
58
  "numpydoc", "sphinx", "sphinx_rtd_theme", "sphinxcontrib.bibtex", "sphinx-pyproject",
74
- "pytest<8.0.0", "pytest-xdist", "nbmake", "simbench", "line_profiler",
59
+ "pytest", "pytest-xdist", "nbmake", "simbench", "line_profiler",
75
60
  ]
76
61
 
77
62
  [tool.setuptools.packages]
@@ -0,0 +1,13 @@
1
+ uvicorn>=0.24.0
2
+ fastapi-users[beanie]>=12.0
3
+ fastapi>=0.104.0
4
+ fastapi-mail>=1.4.1
5
+ pandapower~=2.14
6
+ pandapipes>=0.7.0
7
+ pymongo
8
+ pydantic
9
+ simplejson
10
+ requests
11
+ python-dotenv
12
+ pymongoarrow
13
+ blosc
@@ -0,0 +1,21 @@
1
+ import pytest
2
+ from pandahub import PandaHub
3
+ from pandahub.api.internal import settings
4
+
5
+ @pytest.fixture(scope="session")
6
+ def ph():
7
+ ph = PandaHub(connection_url=settings.MONGODB_URL)
8
+
9
+ project_name = "pytest"
10
+
11
+ if ph.project_exists(project_name):
12
+ ph.set_active_project(project_name)
13
+ ph.delete_project(i_know_this_action_is_final=True)
14
+
15
+ ph.create_project(name=project_name)
16
+
17
+ yield ph
18
+
19
+ ph.delete_project(i_know_this_action_is_final=True)
20
+
21
+
pandahub-0.3.5/AUTHORS DELETED
@@ -1,6 +0,0 @@
1
- - Jan Ulffers
2
- - Mike Vogt
3
- - Leon Thurner
4
- - Jannis Kupka
5
- - Joschka Thurner
6
- - Alexander Scheidler
pandahub-0.3.5/README.md DELETED
@@ -1,75 +0,0 @@
1
- [![pandapower](https://www.pandapower.org/images/pp.svg)](https://www.pandapower.org) [![pandapipes](https://www.pandapipes.org/images/pp.svg)](https://www.pandapipes.org)
2
-
3
- [![pandahub](https://badge.fury.io/py/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/pypi/pyversions/pandahub.svg)](https://pypi.org/project/pandahub/) [![pandahub](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/e2nIEE/pandahub/blob/master/LICENSE)
4
-
5
-
6
- pandahub is a data hub for pandapower and pandapipes networks based on MongoDB. It allows you to store pandapower and pandapipes networks as well as timeseries in a MongoDB. pandahub allows you to access the database directly for local development, but also includes a client/server architecture that exposes all relevant methods as an API based on FastAPI. Access through the API is managed with a user management implementation based on FastAPI Users.
7
-
8
- ## Setup a local pandahub api
9
-
10
- Steps to test the client/server structure locally:
11
-
12
- 1. Start a MongoDB on localhost:27017 (or another custom port)
13
-
14
- 2. Start the uvicorn server that exposes the API by navigating to "pandahub/api" and running:
15
-
16
- ```
17
- # windows
18
- set SECRET=secret & python main.py
19
-
20
- # linux
21
- SECRET=secret python main.py
22
- ```
23
-
24
- or if you don't run mongodb on the default port (27017)
25
-
26
- ```
27
- # windows
28
- set MONGODB_URL=mongodb://localhost:[mongo-port] & set SECRET=secret & python main.py
29
-
30
- # linux
31
- MONGODB_URL=mongodb://localhost:[mongo-port] SECRET=secret python main.py
32
- ```
33
-
34
- The API should now run on http://localhost:8002
35
-
36
- >**Note**
37
- >A full documentation of all api endpoints can be seen at http://localhost:8002/docs
38
-
39
- >**Note 2**
40
- >You can avoid always setting the environment variables for SECRET and MONGODB_URL by creating an `.env` file in `pandahub/api/` with the following content:
41
- >```
42
- >SECRET=secret
43
- >MONGODB_URL=mongodb://localhost:[mongo-port]
44
- >```
45
-
46
- ## Develop with Docker
47
-
48
- `docker compose up` starts a mongodb container alongside pandahub with live reload available at http://localhost:8002.
49
-
50
- If you want to connect to a running database, set the database url and specify only docker-compose.yml:
51
-
52
- MONGODB_URL=mongodb://localhost:[mongo-port] docker compose -f docker-compose.yml up
53
-
54
-
55
-
56
- ## Use pandahub api with pandahub client
57
-
58
- 1. Login with the pandahub client
59
-
60
- There are two ways to login with pandahub client
61
-
62
- - If you installed pandahub by pip or with setup.py just run `pandahub-login` in your shell.
63
-
64
- OR
65
-
66
- - Run the following in your python or IPython shell:
67
-
68
- ```
69
- from pandahub.client.user_management import login
70
- login()
71
- ```
72
-
73
- This will guide you through the login process.
74
-
75
- 2. You only need to login once. After you logged in successfully a configuration file (pandahub.config) containing an authentication token is created in your home directory and will be used every time you use the pandahub client. You only need to login again if you want to use a different instance of the pandahub api.
@@ -1,149 +0,0 @@
1
- import requests
2
- import pandapower as pp
3
- import pandas as pd
4
- from pathlib import Path
5
- import os
6
- import json
7
- from fastapi.encoders import jsonable_encoder
8
-
9
-
10
- class PandaHubClient:
11
- def __init__(self, config=None):
12
- d = None
13
- if config is None:
14
- config = os.path.join(Path.home(), "pandahub.config")
15
- elif type(config) == dict:
16
- d = config
17
-
18
- try:
19
- if d is None:
20
- with open(config, "r") as f:
21
- d = json.load(f)
22
- except FileNotFoundError:
23
- raise UserWarning("No pandahub configuration file found - log in first")
24
-
25
- self.url = d["url"]
26
- self.token = d["token"]
27
- self.cert = None
28
- if d.get("client_cert_path") and d.get("client_key_path"):
29
- self.cert = (d["client_cert_path"], d["client_key_path"])
30
- self.project_id = None
31
-
32
- def set_active_project(self, project_name):
33
- r = self._post("/projects/set_active_project", json=locals())
34
- if r.ok:
35
- self.project_id = r.json()
36
- else:
37
- self.project_id = None
38
- return r
39
-
40
- ### PROJECT HANDLING
41
-
42
- def create_project(self, name):
43
- return self._post("/projects/create_project", json=locals())
44
-
45
- def delete_project(self, i_know_this_action_is_final=False,
46
- error_on_missing_project=True):
47
- return self._post("/projects/delete_project", json=locals())
48
-
49
- def project_exists(self, project_name):
50
- return self._post("/projects/project_exists", json=locals()).json()
51
-
52
- def get_projects(self):
53
- return self._post("/projects/get_projects").json()
54
-
55
- def get_project_settings(self):
56
- return self._post("/projects/get_project_settings").json()
57
-
58
- def set_project_settings(self, settings):
59
- return self._post("/projects/set_project_settings", json=locals())
60
-
61
- def get_project_metadata(self):
62
- return self._post("/projects/get_project_metadata").json()
63
-
64
- def set_project_metadata(self, metadata):
65
- return self._post("/projects/set_project_metadata", json=locals())
66
-
67
- ### NET HANDLING
68
-
69
- def write_network_to_db(self, net, name, overwrite=True):
70
- json = locals()
71
- json["net"] = pp.to_json(net)
72
- return self._post("/net/write_network_to_db", json=json)
73
-
74
- def get_net_from_db(self, name, include_results=True, only_tables=None):
75
- r = self._post("/net/get_net_from_db", json=locals())
76
- return pp.from_json_string(r.json())
77
-
78
-
79
- ### ELEMENT HANDLING
80
-
81
- def get_net_value_from_db(self, net_name, element, element_index, parameter):
82
- return self._post("/net/get_net_value_from_db", json=locals()).json()
83
-
84
- def set_net_value_in_db(self, net_name, element_type, element_index, parameter, value):
85
- return self._post("/net/set_net_value_in_db", json=locals())
86
-
87
- def create_element(self, net, element_type, element_index, element_data):
88
- return self._post("/net/create_element", json=locals())
89
-
90
- def create_elements(self, net, element_type, elements_data):
91
- return self._post("/net/create_elements", json=locals())
92
-
93
- def delete_element(self, net, element_type, element_index):
94
- return self._post("/net/delete_element", json=locals())
95
-
96
- def delete_elements(self, net, element_type, element_index):
97
- return self._post("/net/delete_elements", json=locals())
98
-
99
-
100
- ### deprecated functions
101
-
102
- def create_element_in_db(self, *args, **kwargs):
103
- raise RuntimeError("create_element_in_db was deprecated - use create_element instead!")
104
-
105
- def create_elements_in_db(self, *args, **kwargs):
106
- raise RuntimeError("ph.create_elements_in_db was deprecated - use ph.create_elements instead! "
107
- "Watch out for changed order of project_id and variant args")
108
-
109
- def delete_net_element(self, *args, **kwargs):
110
- raise RuntimeError("ph.delete_net_element was deprecated - use ph.delete_element instead!")
111
-
112
-
113
- ### TIMESERIES
114
-
115
- def multi_get_timeseries_from_db(self, filter_document={}, timestamp_range=None,
116
- exclude_timestamp_range=None,
117
- global_database=False):
118
- ts = self._post("/timeseries/multi_get_timeseries_from_db", json=locals()).json()
119
- for i, data in enumerate(ts):
120
- ts[i]["timeseries_data"] = pd.Series(json.loads(data["timeseries_data"]))
121
- return ts
122
-
123
- def get_timeseries_from_db(self, filter_document={}, timestamp_range=None,
124
- exclude_timestamp_range=None,
125
- global_database=False):
126
- r = self._post("/timeseries/get_timeseries_from_db", json=locals())
127
- return pd.Series(json.loads(r.json()))
128
-
129
- def write_timeseries_to_db(self, timeseries, data_type, element_type=None,
130
- netname=None, element_index=None, name=None,
131
- global_database=False, collection_name="timeseries"):
132
- json = locals()
133
- json["timeseries"] = json["timeseries"].to_json(date_format="iso")
134
- return self._post("/timeseries/write_timeseries_to_db", json=json)
135
-
136
-
137
-
138
- ### INTERNAL
139
-
140
- def _post(self, path, json=None, authorize=True):
141
- headers = {'Authorization': 'Bearer {}'.format(self.token)} if authorize else None
142
- path = self.url + path
143
- if json is None:
144
- json = {}
145
- if json is not None and "self" in json:
146
- del json['self']
147
- json = jsonable_encoder(json)
148
- json["project_id"] = self.project_id
149
- return requests.post(path, headers=headers, json=json, cert=self.cert)
@@ -1,56 +0,0 @@
1
- import os
2
- from pathlib import Path
3
- import requests
4
- import json
5
- import getpass
6
-
7
- config_file = os.path.join(Path.home(), "pandahub.config")
8
-
9
- def login():
10
- url = input("Enter pandahub URL: ")
11
- cert_path = None
12
- key_path = None
13
-
14
- # ask for client certificates
15
- while(True):
16
- with_client_ssl = input("Certificate for API needed? (y/n): ")
17
- if with_client_ssl != "y" and with_client_ssl != "n":
18
- print("ERROR: Wrong input! Only 'y' or 'n' are accepted!")
19
- else:
20
- if with_client_ssl == "y":
21
- cert_path = input("Path to client certificate (*.crt): ")
22
- key_path = input("Path to client key (*.key): ")
23
- break
24
-
25
- email = input("Enter E-Mail: ")
26
- password = getpass.getpass("Enter Password: ")
27
- _login(url, email, password, cert_path, key_path)
28
-
29
- def _login(url, email, password, cert_path=None, key_path=None):
30
- path = url + "/auth/login"
31
-
32
- cert = None
33
- if cert_path and key_path:
34
- cert = (cert_path, key_path)
35
-
36
- r = requests.post(path, data={"username": email, "password": password}, cert=cert)
37
-
38
- if r.status_code == 200:
39
- token = r.json()["access_token"]
40
- write_config(url, token, cert_path, key_path)
41
- elif r.status_code == 400:
42
- if "required SSL certificate" in r.text:
43
- print("Login failed - no client certificate provided")
44
- else:
45
- print("Login failed - bad credentials.")
46
- else:
47
- print(f"[ERROR] code: {r.status_code}, reason: {r.reason}")
48
-
49
- def write_config(url, token, cert_path="", key_path=""):
50
- with open(config_file, "w") as f:
51
- json.dump({
52
- "url": url,
53
- "token": token,
54
- "client_cert_path": cert_path,
55
- "client_key_path": key_path
56
- }, f)
@@ -1,49 +0,0 @@
1
- import pytest
2
- from pandahub import PandaHub
3
- from pandahub import PandaHubClient
4
- from pandahub.api.internal import settings
5
-
6
- @pytest.fixture(scope="session")
7
- def ph():
8
- ph = PandaHub(connection_url=settings.MONGODB_URL)
9
-
10
- project_name = "pytest"
11
-
12
- if ph.project_exists(project_name):
13
- ph.set_active_project(project_name)
14
- ph.delete_project(i_know_this_action_is_final=True)
15
-
16
- ph.create_project(name=project_name, activate=False)
17
- ph.set_active_project(project_name)
18
-
19
- yield ph
20
-
21
- ph.delete_project(i_know_this_action_is_final=True)
22
-
23
-
24
- @pytest.fixture(scope="session")
25
- def phc():
26
- url = settings.PANDAHUB_SERVER_URL
27
-
28
- if url == "0.0.0.0":
29
- url = "127.0.0.1"
30
-
31
- phc = PandaHubClient(
32
- config={
33
- "url": f"http://{url}:{settings.PANDAHUB_SERVER_PORT}",
34
- "token": settings.SECRET
35
- }
36
- )
37
-
38
- project_name = "pandahubclienttest"
39
-
40
- #if phc.project_exists(project_name):
41
- # phc.set_active_project(project_name)
42
- # phc.delete_project(i_know_this_action_is_final=True)
43
-
44
- phc.create_project(name=project_name)
45
- phc.set_active_project(project_name)
46
-
47
- yield phc
48
-
49
- phc.delete_project(i_know_this_action_is_final=True)
@@ -1,23 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- from pandahub import PandaHubClient
4
- import pandapower.networks as nw
5
-
6
-
7
- def test_client_io(phc: PandaHubClient):
8
- phc.set_active_project("Manderbach")
9
-
10
- net = nw.mv_oberrhein()
11
- phc.write_network_to_db(net, name='mv_oberrhein', overwrite=True)
12
- net_loaded = phc.get_net_from_db(name='mv_oberrhein')
13
-
14
- assert len(net_loaded) != 0
15
-
16
-
17
- if __name__ == '__main__':
18
- phc = PandaHubClient()
19
- phc.set_active_project("Manderbach")
20
- net = phc.get_net_from_db("power")
21
-
22
- ts = phc.multi_get_timeseries_from_db({"name": "H0"}, global_database=True)
23
- phc.write_timeseries_to_db(ts[0]["timeseries_data"], "p_mw", "sgen")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes