gridappsd-python 2026.1.1b2__tar.gz → 2026.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/PKG-INFO +1 -1
  2. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/goss.py +51 -12
  3. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/pyproject.toml +1 -1
  4. gridappsd_python-2026.2.1/tests/test_simulation.py +65 -0
  5. gridappsd_python-2026.1.1b2/tests/test_simulation.py +0 -64
  6. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/.gitignore +0 -0
  7. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/CHANGELOG.md +0 -0
  8. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/README.md +0 -0
  9. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/conf/entrypoint.sh +0 -0
  10. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/conf/run-gridappsd.sh +0 -0
  11. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/example.env +0 -0
  12. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/__init__.py +0 -0
  13. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/__main__.py +0 -0
  14. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/app_registration.py +0 -0
  15. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/difference_builder.py +0 -0
  16. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/docker_handler.py +0 -0
  17. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/field_interface/__init__.py +0 -0
  18. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/gridappsd.py +0 -0
  19. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/houses.py +0 -0
  20. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/json_extension.py +0 -0
  21. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/loghandler.py +0 -0
  22. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/register_app.py +0 -0
  23. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/simulation.py +0 -0
  24. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/timeseries.py +0 -0
  25. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/topics.py +0 -0
  26. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd/utils.py +0 -0
  27. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/gridappsd_python_testing.ipynb +0 -0
  28. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/info/CHANGELOG.md +0 -0
  29. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/info/VERSION +0 -0
  30. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/poetry.toml +0 -0
  31. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/conftest.py +0 -0
  32. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/run_gridappsd.py +0 -0
  33. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/simulation_fixtures/13_node_2_min_base.json +0 -0
  34. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_containers.py +0 -0
  35. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_difference_builder.py +0 -0
  36. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_docker_handler.py +0 -0
  37. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_goss.py +0 -0
  38. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_gridappsd.py +0 -0
  39. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_houses.py +0 -0
  40. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_json.py +0 -0
  41. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_logging.py +0 -0
  42. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_logging_integration.py +0 -0
  43. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/test_topics.py +0 -0
  44. {gridappsd_python-2026.1.1b2 → gridappsd_python-2026.2.1}/tests/unittest_test_template.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gridappsd-python
3
- Version: 2026.1.1b2
3
+ Version: 2026.2.1
4
4
  Summary: A GridAPPS-D Python Adapter
5
5
  Project-URL: Repository, https://github.com/GRIDAPPSD/gridappsd-python
6
6
  Project-URL: Homepage, https://gridappsd.readthedocs.io
@@ -57,6 +57,7 @@ from enum import Enum
57
57
  from logging import Logger
58
58
  from queue import Queue
59
59
 
60
+ import stomp as _stomp_module
60
61
  from stomp import Connection12 as Connection
61
62
  from stomp.exception import NotConnectedException
62
63
  from time import sleep
@@ -65,6 +66,20 @@ from gridappsd import json_extension as json
65
66
 
66
67
  _log: Logger = logging.getLogger(inspect.getmodulename(__file__))
67
68
 
69
+ # stomp.py 8.x changed listener callbacks from (headers, body) to (frame)
70
+ _stomp_major = (
71
+ int(getattr(_stomp_module, "__version__", (0,))[0])
72
+ if isinstance(getattr(_stomp_module, "__version__", None), tuple)
73
+ else 0
74
+ )
75
+ try:
76
+ from importlib.metadata import version as _pkg_version
77
+
78
+ _stomp_major = int(_pkg_version("stomp-py").split(".")[0])
79
+ except Exception:
80
+ pass
81
+ _STOMP_V8 = _stomp_major >= 8
82
+
68
83
 
69
84
  class GRIDAPPSD_ENV_ENUM(Enum):
70
85
  GRIDAPPSD_USER = "GRIDAPPSD_USER"
@@ -182,7 +197,12 @@ class GOSS(object):
182
197
  self._topic = topic
183
198
  self.result_format = result_format
184
199
 
185
- def on_message(self, header, message):
200
+ def on_message(self, *args):
201
+ if _STOMP_V8:
202
+ frame = args[0]
203
+ header, message = frame.headers, frame.body
204
+ else:
205
+ header, message = args[0], args[1]
186
206
  _log.debug("Internal on message is: {} {}".format(header, message))
187
207
  try:
188
208
  if self.result_format == "JSON":
@@ -195,13 +215,15 @@ class GOSS(object):
195
215
  except ValueError:
196
216
  self.response = dict(error="Invalid json returned", header=header, message=message)
197
217
 
198
- def on_error(self, headers, message):
218
+ def on_error(self, *args):
219
+ if _STOMP_V8:
220
+ frame = args[0]
221
+ headers, message = frame.headers, frame.body
222
+ else:
223
+ headers, message = args[0], args[1]
199
224
  _log.error("ERR: {}".format(headers))
200
225
  _log.error("OUR ERROR: {}".format(message))
201
226
 
202
- def on_disconnect(self, header, message):
203
- _log.debug("Disconnected")
204
-
205
227
  listener = ResponseListener(reply_to, self.result_format)
206
228
  self.subscribe(reply_to, listener)
207
229
 
@@ -314,18 +336,25 @@ class GOSS(object):
314
336
  def get_token(self):
315
337
  return self.__token
316
338
 
317
- def on_message(self, header, message):
339
+ def on_message(self, *args):
340
+ if _STOMP_V8:
341
+ frame = args[0]
342
+ header, message = frame.headers, frame.body
343
+ else:
344
+ header, message = args[0], args[1]
318
345
  _log.debug("Internal on message is: {} {}".format(header, message))
319
346
 
320
347
  self.__token = str(message)
321
348
 
322
- def on_error(self, headers, message):
349
+ def on_error(self, *args):
350
+ if _STOMP_V8:
351
+ frame = args[0]
352
+ headers, message = frame.headers, frame.body
353
+ else:
354
+ headers, message = args[0], args[1]
323
355
  _log.error("ERR: {}".format(headers))
324
356
  _log.error("OUR ERROR: {}".format(message))
325
357
 
326
- def on_disconnect(self, header, message):
327
- _log.debug("Disconnected")
328
-
329
358
  # receive token and set token variable
330
359
  # set callback
331
360
  listener = TokenResponseListener()
@@ -399,7 +428,12 @@ class CallbackRouter(object):
399
428
  except ValueError:
400
429
  pass
401
430
 
402
- def on_message(self, headers, message):
431
+ def on_message(self, *args):
432
+ if _STOMP_V8:
433
+ frame = args[0]
434
+ headers, message = frame.headers, frame.body
435
+ else:
436
+ headers, message = args[0], args[1]
403
437
  destination = headers["destination"]
404
438
  # _log.debug("Topic map keys are: {keys}".format(keys=self._topics_callback_map.keys()))
405
439
  if destination in self._topics_callback_map:
@@ -407,7 +441,12 @@ class CallbackRouter(object):
407
441
  else:
408
442
  _log.error("INVALID DESTINATION {destination}".format(destination=destination))
409
443
 
410
- def on_error(self, header, message):
444
+ def on_error(self, *args):
445
+ if _STOMP_V8:
446
+ frame = args[0]
447
+ header, message = frame.headers, frame.body
448
+ else:
449
+ header, message = args[0], args[1]
411
450
  _log.error("Error in callback router")
412
451
  _log.error(header)
413
452
  _log.error(message)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "gridappsd-python"
7
- version = "2026.1.1b2"
7
+ version = "2026.02.1"
8
8
  description = "A GridAPPS-D Python Adapter"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -0,0 +1,65 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ import sys
5
+ import time
6
+ import pytest
7
+ from datetime import datetime, timezone
8
+
9
+ logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
10
+
11
+ from gridappsd import GridAPPSD, topics as t
12
+ from gridappsd.simulation import Simulation, PowerSystemConfig, SimulationArgs, SimulationConfig
13
+
14
+ simulation_is_complete = False
15
+ measurements_received = 0
16
+
17
+ @pytest.fixture
18
+ def createGadObject():
19
+ gad_user = os.environ.get('GRIDAPPSD_USER')
20
+ if gad_user is None:
21
+ os.environ['GRIDAPPSD_USER'] = 'system'
22
+ gad_password = os.environ.get('GRIDAPPSD_PASSWORD')
23
+ if gad_password is None:
24
+ os.environ['GRIDAPPSD_PASSWORD'] = 'manager'
25
+ return GridAPPSD()
26
+
27
+ @pytest.mark.integration
28
+ def test_createSimulations(createGadObject):
29
+ gadObj = createGadObject
30
+ response = gadObj.query_model_info()
31
+ models = response.get("data", {}).get("models", {})
32
+ start_time = int(datetime(year=2025, month=1, day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc).timestamp())
33
+ simulationArgs = SimulationArgs(start_time=f"{start_time}",
34
+ duration="120",
35
+ run_realtime=False,
36
+ pause_after_measurements=False)
37
+ sim_config = SimulationConfig(simulation_config=simulationArgs)
38
+ modelsToRun = [
39
+ "49AD8E07-3BF9-A4E2-CB8F-C3722F837B62", # IEEE 13 Node Test Feeder
40
+ "C1C3E687-6FFD-C753-582B-632A27E28507" # IEEE 123 Node Test Feeder
41
+ ]
42
+ for m in models:
43
+ if m.get("modelId") not in modelsToRun:
44
+ continue
45
+ line_name = m.get("modelId")
46
+ subregion_name = m.get("subRegionId")
47
+ region_name = m.get("regionId")
48
+ psc = PowerSystemConfig(Line_name=line_name,
49
+ SubGeographicalRegion_name=subregion_name,
50
+ GeographicalRegion_name=region_name)
51
+ sim_config.power_system_configs.append(psc)
52
+ sim_obj = Simulation(gapps=gadObj, run_config=sim_config)
53
+ def on_measurement(sim, ts, m):
54
+ global measurements_received
55
+ measurements_received += 1
56
+ def on_simulation_complete(sim):
57
+ global simulation_is_complete
58
+ simulation_is_complete = True
59
+ sim_obj.add_onmeasurement_callback(on_measurement)
60
+ sim_obj.add_oncomplete_callback(on_simulation_complete)
61
+ sim_obj.start_simulation()
62
+ while not simulation_is_complete:
63
+ time.sleep(1)
64
+ assert measurements_received == 1
65
+ gadObj.disconnect()
@@ -1,64 +0,0 @@
1
- #import json
2
- #import logging
3
- #import os
4
- #import sys
5
- #import time
6
- #import pytest
7
- #from datetime import datetime, timezone
8
-
9
- #logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
10
-
11
- #from gridappsd import GridAPPSD, topics as t
12
- #from gridappsd.simulation import Simulation, PowerSystemConfig, SimulationArgs, SimulationConfig
13
-
14
- #simulation_is_complete = False
15
- #measurements_received = 0
16
-
17
- #@pytest.fixture
18
- #def createGadObject():
19
- # gad_user = os.environ.get('GRIDAPPSD_USER')
20
- # if gad_user is None:
21
- # os.environ['GRIDAPPSD_USER'] = 'system'
22
- # gad_password = os.environ.get('GRIDAPPSD_PASSWORD')
23
- # if gad_password is None:
24
- # os.environ['GRIDAPPSD_PASSWORD'] = 'manager'
25
- # return GridAPPSD()
26
-
27
- #def test_createSimulations(createGadObject):
28
- # gadObj = createGadObject
29
- # response = gadObj.query_model_info()
30
- # models = response.get("data", {}).get("models", {})
31
- # start_time = int(datetime(year=2025, month=1, day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc).timestamp())
32
- # simulationArgs = SimulationArgs(start_time=f"{start_time}",
33
- # duration="120",
34
- # run_realtime=False,
35
- # pause_after_measurements=False)
36
- # sim_config = SimulationConfig(simulation_config=simulationArgs)
37
- # modelsToRun = [
38
- # "49AD8E07-3BF9-A4E2-CB8F-C3722F837B62", # IEEE 13 Node Test Feeder
39
- # "C1C3E687-6FFD-C753-582B-632A27E28507" # IEEE 123 Node Test Feeder
40
- # ]
41
- # for m in models:
42
- # if m.get("modelId") not in modelsToRun:
43
- # continue
44
- # line_name = m.get("modelId")
45
- # subregion_name = m.get("subRegionId")
46
- # region_name = m.get("regionId")
47
- # psc = PowerSystemConfig(Line_name=line_name,
48
- # SubGeographicalRegion_name=subregion_name,
49
- # GeographicalRegion_name=region_name)
50
- # sim_config.power_system_configs.append(psc)
51
- # sim_obj = Simulation(gapps=gadObj, run_config=sim_config)
52
- # def on_measurement(sim, ts, m):
53
- # global measurements_received
54
- # measurements_received += 1
55
- # def on_simulation_complete(sim):
56
- # global simulation_is_complete
57
- # simulation_is_complete = True
58
- # sim_obj.add_onmeasurement_callback(on_measurement)
59
- # sim_obj.add_oncomplete_callback(on_simulation_complete)
60
- # sim_obj.start_simulation()
61
- # while not simulation_is_complete:
62
- # time.sleep(1)
63
- # assert measurements_received == 1
64
- # gadObj.disconnect()