From 1c489bcff887462367e652ffa7ea5fa3d6040264 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:47:36 +1000 Subject: [PATCH 1/9] migrate workflows from pyeasclient Signed-off-by: Max Chesterfield --- .dockerignore | 5 + .env | 1 + .github/workflows/python-hotfix-branch.yml | 14 - .github/workflows/python-lib-build.yml | 11 - .github/workflows/python-lib-release.yml | 10 - .github/workflows/python-lib-snapshot.yml | 16 - .github/workflows/python-lts-branch.yml | 14 - .gitignore | 8 + Dockerfile | 6 + README.md | 32 +- ariadne-codegen.py | 39 +- .../eas/lib => ariadne_plugins}/__init__.py | 0 .../custom_query_type_hinter.py | 23 +- .../gql_all_fields.py | 3 +- .../license_headers.py | 2 +- .../missed_import_checker.py | 7 +- .../types.py | 4 +- changelog.md | 1 - compose.yml | 54 + pyproject.toml | 25 +- src/zepben/eas/__init__.py | 15 +- src/zepben/eas/client/decorators.py | 15 +- src/zepben/eas/client/eas_client.py | 142 +- .../eas/lib/ariadne_plugins/__init__.py | 5 - .../lib/generated_graphql_client/__init__.py | 233 -- .../async_base_client.py | 207 -- .../generated_graphql_client/base_model.py | 26 - .../base_operation.py | 119 - .../lib/generated_graphql_client/client.py | 114 - .../generated_graphql_client/custom_fields.py | 1966 ----------------- .../custom_mutations.py | 530 ----- .../custom_queries.py | 1031 --------- .../custom_typing_fields.py | 434 ---- .../eas/lib/generated_graphql_client/enums.py | 251 --- .../generated_graphql_client/exceptions.py | 66 - .../generated_graphql_client/input_types.py | 876 -------- test/test_client_generation.py | 40 +- test/test_eas_client.py | 958 +++++--- test/test_feeder_load_analysis.py | 9 +- test/test_integration_testing.py | 59 +- test/test_patched_client.py | 10 +- 41 files changed, 957 insertions(+), 6424 deletions(-) create mode 100644 .dockerignore create mode 100644 .env delete mode 100644 .github/workflows/python-hotfix-branch.yml delete mode 100644 .github/workflows/python-lib-build.yml delete mode 100644 .github/workflows/python-lib-release.yml delete mode 100644 .github/workflows/python-lib-snapshot.yml delete mode 100644 .github/workflows/python-lts-branch.yml create mode 100644 Dockerfile rename {src/zepben/eas/lib => ariadne_plugins}/__init__.py (100%) rename {src/zepben/eas/lib/ariadne_plugins => ariadne_plugins}/custom_query_type_hinter.py (57%) rename {src/zepben/eas/lib/ariadne_plugins => ariadne_plugins}/gql_all_fields.py (99%) rename {src/zepben/eas/lib/ariadne_plugins => ariadne_plugins}/license_headers.py (100%) rename {src/zepben/eas/lib/ariadne_plugins => ariadne_plugins}/missed_import_checker.py (77%) rename {src/zepben/eas/lib/ariadne_plugins => ariadne_plugins}/types.py (89%) create mode 100644 compose.yml delete mode 100644 src/zepben/eas/lib/ariadne_plugins/__init__.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/__init__.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/async_base_client.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/base_model.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/base_operation.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/client.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/custom_fields.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/custom_mutations.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/custom_queries.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/custom_typing_fields.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/enums.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/exceptions.py delete mode 100644 src/zepben/eas/lib/generated_graphql_client/input_types.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..422ad53 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.tox +.git +.github/workflows +.venv* +src/zepben/lib/generated_graphql_client \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 0000000..3e748cb --- /dev/null +++ b/.env @@ -0,0 +1 @@ +EAS_TAG=edge \ No newline at end of file diff --git a/.github/workflows/python-hotfix-branch.yml b/.github/workflows/python-hotfix-branch.yml deleted file mode 100644 index 31e754c..0000000 --- a/.github/workflows/python-hotfix-branch.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Create Hotfix Branch - -on: - workflow_dispatch: - inputs: - version: - description: 'Major.Minor version to create next hotfix patch for (e.g. 2.5)' - required: true -jobs: - run: - uses: zepben/.github/.github/workflows/python-hotfix-branch.yml@main - with: - version: ${{ inputs.version }} - secrets: inherit diff --git a/.github/workflows/python-lib-build.yml b/.github/workflows/python-lib-build.yml deleted file mode 100644 index bc8d582..0000000 --- a/.github/workflows/python-lib-build.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Python Lib Build - -on: - pull_request: - workflow_dispatch: - -jobs: - run: - uses: zepben/.github/.github/workflows/python-build.yml@main - secrets: inherit - diff --git a/.github/workflows/python-lib-release.yml b/.github/workflows/python-lib-release.yml deleted file mode 100644 index 7f4d31a..0000000 --- a/.github/workflows/python-lib-release.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: Python Library Release - -on: workflow_dispatch - -jobs: - run: - uses: zepben/.github/.github/workflows/python-lib-release.yml@main - with: - private: false - secrets: inherit diff --git a/.github/workflows/python-lib-snapshot.yml b/.github/workflows/python-lib-snapshot.yml deleted file mode 100644 index e3f5d88..0000000 --- a/.github/workflows/python-lib-snapshot.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Python Library Snapshot - -on: - push: - branches: - - main - - LTS/* - workflow_dispatch: - -jobs: - run: - uses: zepben/.github/.github/workflows/python-lib-snapshot.yml@main - with: - product-key: "eas-client-python" - product-repo: "zepben/eas-client-python" - secrets: inherit diff --git a/.github/workflows/python-lts-branch.yml b/.github/workflows/python-lts-branch.yml deleted file mode 100644 index 481295d..0000000 --- a/.github/workflows/python-lts-branch.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Create LTS Branch - -on: - workflow_dispatch: - inputs: - version: - description: 'Major.Minor version to create the LTS branch for (e.g. 2.5)' - required: true -jobs: - run: - uses: zepben/.github/.github/workflows/python-lts-branch.yml@main - with: - version: ${{ inputs.version }} - secrets: inherit diff --git a/.gitignore b/.gitignore index 068bc72..c7c7599 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,11 @@ docs/yarn-error.log* docs/versioned_docs/static/ .tox/ + +src/zepben/eas/lib/generated_graphql_client/ + +src/zepben/eas/lib/ + +.coverage + +coverage.xml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f3028e2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.10 +RUN mkdir /app +WORKDIR /app +COPY . . +RUN pip install ".[codegen, test]" +CMD ["python", "ariadne-codegen.py"] \ No newline at end of file diff --git a/README.md b/README.md index cbbc568..64b96bf 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ the Evolve App Server and upload studies. ```python from geojson import FeatureCollection -from zepben.eas import EasClient, StudyInput, StudyResultInput, GeoJsonOverlayInput, ResultSectionInput, SectionType, Mutation +from src.zepben.eas import EasClient, StudyInput, StudyResultInput, GeoJsonOverlayInput, ResultSectionInput, + SectionType, Mutation eas_client = EasClient( host="", @@ -40,8 +41,10 @@ eas_client.mutation( {"key": "", "name": ""}, ], data=[ - {"": "", "": ""}, - {"": "", "": ""} + {"": "", + "": ""}, + {"": "", + "": ""} ] ) ] @@ -67,7 +70,8 @@ The EasClient can operate in async mode if specified, like so: ```python from aiohttp import ClientSession from geojson import FeatureCollection -from zepben.eas import EasClient, StudyInput, StudyResultInput, GeoJsonOverlayInput, ResultSectionInput, SectionType, Mutation +from src.zepben.eas import EasClient, StudyInput, StudyResultInput, GeoJsonOverlayInput, ResultSectionInput, + SectionType, Mutation async def upload(): @@ -102,8 +106,10 @@ async def upload(): {"key": "", "name": ""}, ], data=[ - {"": "", "": ""}, - {"": "", "": ""} + {"": "", + "": ""}, + {"": "", + "": ""} ] ) ] @@ -133,7 +139,7 @@ The new EasClient is fully type hinted and self documenting. For example. ```python -from zepben.eas import EasClient, WorkPackageInput, HcExecutorConfigInput, FeederConfigsInput, FeederConfigInput +from src.zepben.eas import EasClient, WorkPackageInput, HcExecutorConfigInput, FeederConfigsInput, FeederConfigInput client = EasClient(host='host', port=1234) client.get_work_package_cost_estimation( @@ -158,7 +164,7 @@ Hovering over any kwarg or looking at any class definition will show all possibl Legacy convenience methods can be enabled by passing `enable_legacy_methods` to `__init__` of `EasClient`. eg: ```python -from zepben.eas import EasClient +from src.zepben.eas import EasClient client = EasClient(enable_legacy_methods=True) ``` @@ -167,14 +173,16 @@ This will enable all `deprecated` and `opt_in` methods on the class, they are di # Development # -To regenerate the graphql client you will need to install `zepben.eas` with `eas-codegen` optional dependencies: +To regenerate the graphql client, run the following command ```shell -pip install -e ".[eas-codegen]" +docker compose run codegen ``` -With these installed and EAS running locally on port 7654, you can then generate the client: +If you have done any of the following, you will need to regenerate the docker image if testing locally. +- Made changes to anything that affects the python package +- Changed anything under `ariadne_plugins` ```shell -python ariadne-codegen.py +docker build . ``` diff --git a/ariadne-codegen.py b/ariadne-codegen.py index 69a2f67..9ea2c68 100644 --- a/ariadne-codegen.py +++ b/ariadne-codegen.py @@ -23,11 +23,17 @@ def generate_custom_method(self, method_def: ast.FunctionDef) -> ast.FunctionDef return self._apply_plugins_on_object("generate_custom_method", method_def) -class ZBPatchedCustomOperationGenerator(ariadne_codegen.client_generators.custom_operation.CustomOperationGenerator): +class ZBPatchedCustomOperationGenerator( + ariadne_codegen.client_generators.custom_operation.CustomOperationGenerator +): plugin_manager: ZBPatchedPluginManager def _generate_method( - self, operation_name: str, operation_args, final_type, description: Optional[str] = None + self, + operation_name: str, + operation_args, + final_type, + description: Optional[str] = None, ) -> ast.FunctionDef: return self.plugin_manager.generate_custom_method( super()._generate_method( @@ -39,15 +45,20 @@ def _generate_method( ) def generate(self) -> ast.Module: - return self.plugin_manager.generate_custom_module( - super().generate() - ) + return self.plugin_manager.generate_custom_module(super().generate()) + -ariadne_codegen.client_generators.custom_operation.CustomOperationGenerator = ZBPatchedCustomOperationGenerator +ariadne_codegen.client_generators.custom_operation.CustomOperationGenerator = ( + ZBPatchedCustomOperationGenerator +) from ariadne_codegen.client_generators.package import get_package_generator -from ariadne_codegen.config import get_client_settings, get_config_dict, get_graphql_schema_settings +from ariadne_codegen.config import ( + get_client_settings, + get_config_dict, + get_graphql_schema_settings, +) from ariadne_codegen.graphql_schema_generators.schema import ( generate_graphql_schema_graphql_file, generate_graphql_schema_python_file, @@ -67,10 +78,16 @@ def generate(self) -> ast.Module: Plugin.generate_custom_method = lambda self, method: method Plugin.generate_custom_module = lambda self, module: module + @click.command() @click.version_option() @click.option("--config", default=None, help="Path to custom configuration file.") -@click.argument("strategy", default=Strategy.CLIENT.value, type=click.Choice([e.value for e in Strategy]), required=False,) +@click.argument( + "strategy", + default=Strategy.CLIENT.value, + type=click.Choice([e.value for e in Strategy]), + required=False, +) def main(strategy=Strategy.CLIENT.value, config=None): config_dict = get_config_dict(config) if strategy == Strategy.CLIENT: @@ -168,5 +185,9 @@ def graphql_schema(config_dict): if __name__ == "__main__": - print("TEMPORARY PATCHED VERSION IN USE. check if ariadne-codegen has been released > 0.10.8") + import os + print(os.getcwd()) + print( + "TEMPORARY PATCHED VERSION IN USE. check if ariadne-codegen has been released > 0.10.8" + ) main() diff --git a/src/zepben/eas/lib/__init__.py b/ariadne_plugins/__init__.py similarity index 100% rename from src/zepben/eas/lib/__init__.py rename to ariadne_plugins/__init__.py diff --git a/src/zepben/eas/lib/ariadne_plugins/custom_query_type_hinter.py b/ariadne_plugins/custom_query_type_hinter.py similarity index 57% rename from src/zepben/eas/lib/ariadne_plugins/custom_query_type_hinter.py rename to ariadne_plugins/custom_query_type_hinter.py index f328b46..93bf726 100644 --- a/src/zepben/eas/lib/ariadne_plugins/custom_query_type_hinter.py +++ b/ariadne_plugins/custom_query_type_hinter.py @@ -9,25 +9,32 @@ from ariadne_codegen.plugins.base import Plugin -class CustomQueryTypeHinterPlugin(Plugin): +class CustomQueryTypeHinterPlugin(Plugin): def generate_custom_module(self, module: ast.Module) -> ast.Module: for b in module.body: if isinstance((class_def := b), ClassDef): if class_def.name == "Query": for method in class_def.body: - injected_type = method.returns.id.replace("Fields", "GraphQLField") + injected_type = method.returns.id.replace( + "Fields", "GraphQLField" + ) method.returns = ast.Name( - f'\"GraphQLQuery[{method.returns.id}, {injected_type}]\"' + f'"GraphQLQuery[{method.returns.id}, {injected_type}]"' ) module.body.extend( [ - ast.ImportFrom('.custom_typing_fields', [ast.alias(injected_type)], level=0), - ast.ImportFrom('zepben.eas.lib.ariadne_plugins.types', [ - ast.alias('GraphQLQuery') - ], level=0) + ast.ImportFrom( + ".custom_typing_fields", + [ast.alias(injected_type)], + level=0, + ), + ast.ImportFrom( + "zepben.eas.lib.types", + [ast.alias("GraphQLQuery")], + level=0, + ), ] ) return module - diff --git a/src/zepben/eas/lib/ariadne_plugins/gql_all_fields.py b/ariadne_plugins/gql_all_fields.py similarity index 99% rename from src/zepben/eas/lib/ariadne_plugins/gql_all_fields.py rename to ariadne_plugins/gql_all_fields.py index 0f2de43..e44dea3 100644 --- a/src/zepben/eas/lib/ariadne_plugins/gql_all_fields.py +++ b/ariadne_plugins/gql_all_fields.py @@ -33,8 +33,8 @@ def all_fields(cls) -> "Generator[GraphQLField | MethodType, None, None]": yield v().fields(*v().all_fields()) """).body[0] -class GqlAllFieldsPlugin(Plugin): +class GqlAllFieldsPlugin(Plugin): def copy_code(self, copied_code: str) -> str: code_as_ast = ast.parse(copied_code) for b in code_as_ast.body: @@ -42,4 +42,3 @@ def copy_code(self, copied_code: str) -> str: if class_def.name == "GraphQLField": class_def.body.append(gql_field_all_fields_ast) return ast.unparse(code_as_ast) - diff --git a/src/zepben/eas/lib/ariadne_plugins/license_headers.py b/ariadne_plugins/license_headers.py similarity index 100% rename from src/zepben/eas/lib/ariadne_plugins/license_headers.py rename to ariadne_plugins/license_headers.py index c5bdc1e..262fe9b 100644 --- a/src/zepben/eas/lib/ariadne_plugins/license_headers.py +++ b/ariadne_plugins/license_headers.py @@ -22,8 +22,8 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. """ -class LicenseHeadersPlugin(Plugin): +class LicenseHeadersPlugin(Plugin): def get_file_comment( self, comment: str, code: str, source: Optional[str] = None ) -> str: diff --git a/src/zepben/eas/lib/ariadne_plugins/missed_import_checker.py b/ariadne_plugins/missed_import_checker.py similarity index 77% rename from src/zepben/eas/lib/ariadne_plugins/missed_import_checker.py rename to ariadne_plugins/missed_import_checker.py index 8ddd281..3e2dcd4 100644 --- a/src/zepben/eas/lib/ariadne_plugins/missed_import_checker.py +++ b/ariadne_plugins/missed_import_checker.py @@ -3,6 +3,7 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. + import ast from ariadne_codegen import Plugin @@ -13,6 +14,8 @@ class MissedImportCheckerPlugin(Plugin): def generate_client_import(self, import_: ast.ImportFrom) -> ast.ImportFrom: # Somethings wrong with how the import is being generated without `module` if import_.module is None: - print(f"[ZBEX] Assuming class import {import_.names[0].name} is from module 'enums.py'") - import_.module = 'enums' + print( + f"[ZBEX] Assuming class import {import_.names[0].name} is from module 'enums.py'" + ) + import_.module = "enums" return import_ diff --git a/src/zepben/eas/lib/ariadne_plugins/types.py b/ariadne_plugins/types.py similarity index 89% rename from src/zepben/eas/lib/ariadne_plugins/types.py rename to ariadne_plugins/types.py index 6a46186..214b192 100644 --- a/src/zepben/eas/lib/ariadne_plugins/types.py +++ b/ariadne_plugins/types.py @@ -3,10 +3,12 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. + from typing import Generic, TypeVar TGraphQLField = TypeVar("TGraphQLField") TGraphQLQueryField = TypeVar("TGraphQLQueryField") + class GraphQLQuery(Generic[TGraphQLQueryField, TGraphQLField]): - def fields(self, *fields: TGraphQLField): ... + def fields(self, *fields: TGraphQLField): ... diff --git a/changelog.md b/changelog.md index 3036ce0..5fd988d 100644 --- a/changelog.md +++ b/changelog.md @@ -28,7 +28,6 @@ ### Enhancements * EasClient has new `query` and `mutation` methods that will accept `Query` and `Mutation` objects respectively. * Available queries and mutations can be found as `@classmethods` on `Queries` and `Mutations`. -* Added support for `negligibleImpedanceMinHvThreshold` and `negligibleImpedanceMinLvThreshold` in `ModelConfig`. ### Fixes * Patched ariadne-codegen while waiting for release of dependent code. diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..570353f --- /dev/null +++ b/compose.yml @@ -0,0 +1,54 @@ + +services: + postgres: + image: postgres:16 + container_name: postgres + restart: unless-stopped + environment: + POSTGRES_USER: eas + POSTGRES_PASSWORD: password + POSTGRES_DB: eas + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U eas"] + interval: 5s + timeout: 5s + retries: 5 + + evolve-app-server: + image: ghcr.io/zepben/evolve-app-server:${EAS_TAG} + container_name: evolve-app-server + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + volumes: + - ./.github/evolve-app-server:/config + environment: + EAS_HOST: localhost + ports: + - "7654:7654" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:7654/internal/health/ready"] + interval: 5s + timeout: 5s + retries: 5 + + codegen: + build: + context: . + no_cache: true + container_name: eas-client-generate +# command: ["sleep", "10000"] + depends_on: + evolve-app-server: + condition: service_healthy + restart: "no" + volumes: + - ./src/zepben/eas/lib:/app/src/zepben/eas/lib + +volumes: + postgres_data: \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 1b523cc..f3983d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,8 +12,8 @@ requires = [ build-backend = "setuptools.build_meta" [project] -name = "zepben.eas" -version = "1.0.0b4" +name = "zepben.test-eas-client-python" +version = "0.0.0b1" description = "Python SDK for interacting with the Evolve App Server" readme = {file = "README.md", content-type = "text/markdown"} license = "MPL-2.0" @@ -51,24 +51,27 @@ test = [ "trustme==0.9.0" ] codegen = [ - "ariadne-codegen==0.18.0" -# "ariadne-codegen>0.18.0" # Waiting on https://github.com/mirumee/ariadne-codegen/pull/413 to be included in a release + "ariadne-codegen==0.18.0", + "click" ] [tool.setuptools.packages.find] where = ["src/"] [tool.ariadne-codegen] -remote_schema_url = "http://127.0.0.1:7654/api/graphql" # Set to address of Evolve App Server +remote_schema_url = "http://evolve-app-server:7654/api/graphql" # Set to address of Evolve App Server enable_custom_operations=true include_comments=false -target_package_path='src/zepben/eas/lib' -target_package_name='generated_graphql_client' +target_package_path='src/zepben/eas' +target_package_name='lib' introspection_descriptions=true introspection_input_value_deprecations=true plugins=[ - "zepben.eas.lib.ariadne_plugins.custom_query_type_hinter.CustomQueryTypeHinterPlugin", - "zepben.eas.lib.ariadne_plugins.missed_import_checker.MissedImportCheckerPlugin", - "zepben.eas.lib.ariadne_plugins.gql_all_fields.GqlAllFieldsPlugin", - "zepben.eas.lib.ariadne_plugins.license_headers.LicenseHeadersPlugin", + "ariadne_plugins.custom_query_type_hinter.CustomQueryTypeHinterPlugin", + "ariadne_plugins.missed_import_checker.MissedImportCheckerPlugin", + "ariadne_plugins.gql_all_fields.GqlAllFieldsPlugin", + "ariadne_plugins.license_headers.LicenseHeadersPlugin", +] +files_to_include=[ + "./ariadne_plugins/types.py" ] diff --git a/src/zepben/eas/__init__.py b/src/zepben/eas/__init__.py index e901cff..40a59d0 100644 --- a/src/zepben/eas/__init__.py +++ b/src/zepben/eas/__init__.py @@ -4,16 +4,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # -import warnings from zepben.eas.client.eas_client import * -try: - from zepben.eas.lib.generated_graphql_client import * - from zepben.eas.lib.generated_graphql_client.custom_mutations import * - from zepben.eas.lib.generated_graphql_client.custom_queries import * - from zepben.eas.lib.generated_graphql_client.custom_fields import * -except ImportError: - warnings.warn( - "Could not import `zepben.eas.lib.generated_graphql_client`. " - ) +from zepben.eas.lib import * +from zepben.eas.lib.custom_mutations import * +from zepben.eas.lib.custom_queries import * +from zepben.eas.lib.custom_fields import * +from zepben.eas.lib.enums import * diff --git a/src/zepben/eas/client/decorators.py b/src/zepben/eas/client/decorators.py index 43a4076..7ae3e7b 100644 --- a/src/zepben/eas/client/decorators.py +++ b/src/zepben/eas/client/decorators.py @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -__all__ = ['catch_warnings', 'async_func', 'opt_in'] +__all__ = ["catch_warnings", "async_func", "opt_in"] import asyncio import functools @@ -16,10 +16,12 @@ def catch_warnings(func: Callable) -> Callable: """ Wrap a function in `warnings.catch_warnings() """ + @functools.wraps(func) def wrapper(*args, **kwargs): with warnings.catch_warnings(): return func(*args, **kwargs) + return wrapper @@ -36,15 +38,22 @@ def wrapper(self, *args, **kwargs): return func(self, *args, **kwargs) try: - return asyncio.get_running_loop().run_until_complete(func(self, *args, **kwargs)) + return asyncio.get_running_loop().run_until_complete( + func(self, *args, **kwargs) + ) except RuntimeError: return asyncio.run(func(self, *args, **kwargs)) + return wrapper + def opt_in(func: Callable) -> Callable: @functools.wraps(func) def wrapper(self, *args, **kwargs): if self._opt_in_legacy: return func(self, *args, **kwargs) - raise AttributeError(f"'{func.__qualname__}' is a legacy function and must be explicitly opted into.") + raise AttributeError( + f"'{func.__qualname__}' is a legacy function and must be explicitly opted into." + ) + return wrapper diff --git a/src/zepben/eas/client/eas_client.py b/src/zepben/eas/client/eas_client.py index 1f944e2..c554297 100644 --- a/src/zepben/eas/client/eas_client.py +++ b/src/zepben/eas/client/eas_client.py @@ -26,21 +26,35 @@ from zepben.eas.client.decorators import async_func, catch_warnings, opt_in -try: - from zepben.eas.lib.generated_graphql_client import GraphQLClientHttpError, GraphQLClientInvalidResponseError, \ - GraphQLClientGraphQLMultiError, Client, WorkPackageInput, FeederLoadAnalysisInput, StudyInput, IngestorConfigInput, \ - IngestorRunsFilterInput, IngestorRunsSortCriteriaInput, HcGeneratorConfigInput, HcModelConfigInput, OpenDssModelInput, \ - GetOpenDssModelsFilterInput, GetOpenDssModelsSortCriteriaInput - from zepben.eas.lib.generated_graphql_client.base_operation import GraphQLField - from zepben.eas.lib.generated_graphql_client.custom_fields import FeederLoadAnalysisReportFields, IngestionRunFields, \ - HcCalibrationFields, GqlTxTapRecordFields, OpenDssModelPageFields, OpenDssModelFields - from zepben.eas.lib.generated_graphql_client.custom_mutations import Mutation - from zepben.eas.lib.generated_graphql_client.custom_queries import Query - - -except ImportError: - warnings.warn("could not import generated graphql client.") - Client = object +from zepben.eas.lib import ( + GraphQLClientHttpError, + GraphQLClientInvalidResponseError, + GraphQLClientGraphQLMultiError, + Client, + WorkPackageInput, + FeederLoadAnalysisInput, + StudyInput, + IngestorConfigInput, + IngestorRunsFilterInput, + IngestorRunsSortCriteriaInput, + HcGeneratorConfigInput, + HcModelConfigInput, + OpenDssModelInput, + GetOpenDssModelsFilterInput, + GetOpenDssModelsSortCriteriaInput, +) +from zepben.eas.lib.custom_typing_fields import GraphQLField +from zepben.eas.lib.custom_fields import ( + FeederLoadAnalysisReportFields, + IngestionRunFields, + HcCalibrationFields, + GqlTxTapRecordFields, + OpenDssModelPageFields, + OpenDssModelFields, +) +from zepben.eas.lib.custom_mutations import Mutation +from zepben.eas.lib.custom_queries import Query + if TYPE_CHECKING: from zepben.eas import GraphQLQuery @@ -103,7 +117,9 @@ def __init__( verify = ssl.create_default_context(capath=ca_filename) http_client = httpx.AsyncClient( - headers=dict(authorization=f"Bearer {access_token}") if access_token else None, + headers=dict(authorization=f"Bearer {access_token}") + if access_token + else None, verify=verify, ) super().__init__( @@ -116,21 +132,31 @@ async def close(self): await self.http_client.aclose() @async_func - async def query(self, query: GraphQLQuery[T, R], *returned_fields: R, operation_name: str = None) -> T: + async def query( + self, query: GraphQLQuery[T, R], *returned_fields: R, operation_name: str = None + ) -> T: """Execute a query against the Evolve App Server.""" query = query.fields(*returned_fields) if hasattr(query, "fields") else query return await super().query(query, operation_name=operation_name) @async_func - async def mutation(self, *fields: GraphQLField, operation_name: str = None) -> dict[str, Any]: + async def mutation( + self, *fields: GraphQLField, operation_name: str = None + ) -> dict[str, Any]: """Execute a mutation against the Evolve App Server.""" return await super().mutation(*fields, operation_name=operation_name) - async def execute_custom_operation(self, *fields: GraphQLField, operation_type: OperationType, operation_name: str = None) -> dict[str, Any]: + async def execute_custom_operation( + self, + *fields: GraphQLField, + operation_type: OperationType, + operation_name: str = None, + ) -> dict[str, Any]: return await super().execute_custom_operation( *fields, operation_type=operation_type, - operation_name=operation_name or str('-'.join(f._field_name for f in fields)) + operation_name=operation_name + or str("-".join(f._field_name for f in fields)), ) @async_func @@ -141,11 +167,11 @@ async def get_opendss_model_download_url(self, run_id: int): :param run_id: The opendss export run ID :return: The HTTP response received from the Evolve App Server after requesting opendss export model download url """ - response = (await self.http_client.get( + response = await self.http_client.get( f"{self._base_url}/api/opendss-model/{run_id}", headers=self.headers, - follow_redirects=False - )) + follow_redirects=False, + ) if response.status_code == HTTPStatus.FOUND: return response.headers["Location"] elif not response.ok: @@ -212,7 +238,9 @@ def get_work_package_cost_estimation(self, work_package: WorkPackageInput): @deprecated("Use query()/mutation() methods directly instead.") @catch_warnings @opt_in - def run_hosting_capacity_work_package(self, work_package: WorkPackageInput, work_package_name: str): + def run_hosting_capacity_work_package( + self, work_package: WorkPackageInput, work_package_name: str + ): """ Send request to hosting capacity service to run work package @@ -221,7 +249,9 @@ def run_hosting_capacity_work_package(self, work_package: WorkPackageInput, work :return: The HTTP response received from the Evolve App Server after attempting to run work package """ return self.mutation( - Mutation.run_work_package(work_package, work_package_name=work_package_name), + Mutation.run_work_package( + work_package, work_package_name=work_package_name + ), ) @deprecated("Use query()/mutation() methods directly instead.") @@ -241,7 +271,9 @@ def cancel_hosting_capacity_work_package(self, work_package_id: str): @deprecated("Use query()/mutation() methods directly instead.") @catch_warnings @opt_in - def get_hosting_capacity_work_packages_progress(self): # FIXME: why is this info not returned by get_work_package_by_id ? + def get_hosting_capacity_work_packages_progress( + self, + ): # FIXME: why is this info not returned by get_work_package_by_id ? """ Retrieve running work packages progress information from hosting capacity service @@ -251,11 +283,12 @@ def get_hosting_capacity_work_packages_progress(self): # FIXME: why is this inf Query.get_active_work_packages(), ) - @deprecated("Use query()/mutation() methods directly instead.") @catch_warnings @opt_in - def run_feeder_load_analysis_report(self, feeder_load_analysis_input: FeederLoadAnalysisInput): + def run_feeder_load_analysis_report( + self, feeder_load_analysis_input: FeederLoadAnalysisInput + ): """ Send request to evolve app server to run a feeder load analysis study @@ -269,7 +302,9 @@ def run_feeder_load_analysis_report(self, feeder_load_analysis_input: FeederLoad @deprecated("Use query()/mutation() methods directly instead.") @catch_warnings @opt_in - def get_feeder_load_analysis_report_status(self, report_id: str, full_spec: bool = False): + def get_feeder_load_analysis_report_status( + self, report_id: str, full_spec: bool = False + ): """ Send request to evolve app server to retrieve a feeder load analysis report status @@ -278,9 +313,9 @@ def get_feeder_load_analysis_report_status(self, report_id: str, full_spec: bool :return: The HTTP response received from the Evolve App Server after requesting a feeder load analysis report status """ return self.query( - Query.get_feeder_load_analysis_report_status(report_id, full_spec=full_spec).fields( - *FeederLoadAnalysisReportFields.all_fields() - ), + Query.get_feeder_load_analysis_report_status( + report_id, full_spec=full_spec + ).fields(*FeederLoadAnalysisReportFields.all_fields()), ) @deprecated("Use query()/mutation() methods directly instead.") @@ -330,9 +365,9 @@ def get_ingestor_run(self, ingestor_run_id: int): @catch_warnings @opt_in def get_ingestor_run_list( - self, - query_filter: IngestorRunsFilterInput | None = None, - query_sort: IngestorRunsSortCriteriaInput | None = None + self, + query_filter: IngestorRunsFilterInput | None = None, + query_sort: IngestorRunsSortCriteriaInput | None = None, ): """ Send request to retrieve a list of ingestor run records matching the provided filter parameters. @@ -359,12 +394,13 @@ def get_ingestor_run_list( @catch_warnings @opt_in def run_hosting_capacity_calibration( - self, - calibration_name: str, - local_calibration_time: datetime, - feeders: list[str] | None = None, - transformer_tap_settings: str | None = None, - generator_config: HcGeneratorConfigInput | None = None): + self, + calibration_name: str, + local_calibration_time: datetime, + feeders: list[str] | None = None, + transformer_tap_settings: str | None = None, + generator_config: HcGeneratorConfigInput | None = None, + ): """ Send request to run hosting capacity calibration @@ -385,7 +421,9 @@ def run_hosting_capacity_calibration( if generator_config.model is None: generator_config.model = HcModelConfigInput() if generator_config.model: - generator_config.model.transformer_tap_settings = transformer_tap_settings + generator_config.model.transformer_tap_settings = ( + transformer_tap_settings + ) return self.mutation( Mutation.run_calibration( @@ -438,10 +476,10 @@ def get_hosting_capacity_calibration_sets(self): @catch_warnings @opt_in def get_transformer_tap_settings( - self, - calibration_name: str, - feeder: str | None = None, - transformer_mrid: str | None = None + self, + calibration_name: str, + feeder: str | None = None, + transformer_mrid: str | None = None, ): """ Retrieve distribution transformer tap settings from a calibration set in the hosting capacity input database @@ -455,7 +493,7 @@ def get_transformer_tap_settings( Query.get_transformer_tap_settings( calibration_name=calibration_name, feeder=feeder, - transformer_mrid=transformer_mrid + transformer_mrid=transformer_mrid, ).fields( GqlTxTapRecordFields.id, GqlTxTapRecordFields.high_step, @@ -489,7 +527,8 @@ def get_paged_opendss_models( limit: int | None = None, offset: int | None = None, query_filter: GetOpenDssModelsFilterInput | None = None, - query_sort: GetOpenDssModelsSortCriteriaInput | None = None): + query_sort: GetOpenDssModelsSortCriteriaInput | None = None, + ): """ Retrieve a paginated opendss export run information @@ -501,10 +540,7 @@ def get_paged_opendss_models( """ return self.query( Query.paged_open_dss_models( - limit=limit, - offset=offset, - filter_=query_filter, - sort=query_sort + limit=limit, offset=offset, filter_=query_filter, sort=query_sort ), OpenDssModelPageFields.total_count, OpenDssModelPageFields.offset, @@ -516,7 +552,7 @@ def get_paged_opendss_models( OpenDssModelFields.download_url, OpenDssModelFields.is_public, OpenDssModelFields.errors, - OpenDssModelFields.generation_spec + OpenDssModelFields.generation_spec, ), ) diff --git a/src/zepben/eas/lib/ariadne_plugins/__init__.py b/src/zepben/eas/lib/ariadne_plugins/__init__.py deleted file mode 100644 index 4a7146f..0000000 --- a/src/zepben/eas/lib/ariadne_plugins/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. diff --git a/src/zepben/eas/lib/generated_graphql_client/__init__.py b/src/zepben/eas/lib/generated_graphql_client/__init__.py deleted file mode 100644 index 57e1ef0..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/__init__.py +++ /dev/null @@ -1,233 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from .async_base_client import AsyncBaseClient -from .base_model import BaseModel, Upload -from .client import Client -from .enums import ( - CandidateGenerationType, - ColumnGroup, - ColumnName, - ContainerType, - DaysRequired, - DiffType, - HcFeederScenarioAllocationStrategy, - HcLoadPlacement, - HcSolveMode, - HcSwitchClass, - HcWriterType, - HostingCapacityFileType, - IngestorRunState, - IngestorRuntimeKind, - InterventionClass, - MeasurementZoneType, - OpenDssModelState, - OpportunitiesNeed, - OpportunitiesType, - PowerFactoryModelState, - SectionType, - SerializationType, - SincalFileType, - SincalModelState, - SortOrder, - VariantFileType, - VariantStatus, - VariantWorkflowStatus, - WorkflowStatus, - WorkPackageState, -) -from .exceptions import ( - GraphQLClientError, - GraphQLClientGraphQLError, - GraphQLClientGraphQLMultiError, - GraphQLClientHttpError, - GraphQLClientInvalidResponseError, -) -from .input_types import ( - AppOptionsInput, - CandidateGenerationConfigInput, - DvmsConfigInput, - DvmsRegulatorConfigInput, - FeederConfigInput, - FeederConfigsInput, - FeederLoadAnalysisInput, - FixedTimeInput, - FixedTimeLoadOverrideInput, - FlaForecastConfigInput, - ForecastConfigInput, - GeoJsonOverlayInput, - GetOpenDssModelsFilterInput, - GetOpenDssModelsSortCriteriaInput, - GetPowerFactoryModelsFilterInput, - GetPowerFactoryModelsSortCriteriaInput, - GetPowerFactoryModelTemplatesFilterInput, - GetPowerFactoryModelTemplatesSortCriteriaInput, - GetSincalModelPresetsFilterInput, - GetSincalModelPresetsSortCriteriaInput, - GetSincalModelsFilterInput, - GetSincalModelsSortCriteriaInput, - GetStudiesFilterInput, - GetStudiesSortCriteriaInput, - GqlDistributionTransformerConfigInput, - GqlLoadConfigInput, - GqlScenarioConfigInput, - GqlSincalModelForecastSpecInput, - HcEnhancedMetricsConfigInput, - HcExecutorConfigInput, - HcGeneratorConfigInput, - HcInverterControlConfigInput, - HcMeterPlacementConfigInput, - HcMetricsResultsConfigInput, - HcModelConfigInput, - HcNodeLevelResultsConfigInput, - HcRawResultsConfigInput, - HcResultProcessorConfigInput, - HcScenarioConfigsFilterInput, - HcSolveConfigInput, - HcStoredResultsConfigInput, - HcSwitchMeterPlacementConfigInput, - HcWorkPackagesFilterInput, - HcWorkPackagesSortCriteriaInput, - HcWriterConfigInput, - HcWriterOutputConfigInput, - IngestorConfigInput, - IngestorRunsFilterInput, - IngestorRunsSortCriteriaInput, - InterventionConfigInput, - OpenDssCommonConfigInput, - OpenDssModelGenerationSpecInput, - OpenDssModelInput, - OpenDssModelOptionsInput, - OpenDssModulesConfigInput, - PhaseRebalanceProportionsInput, - PowerFactoryModelGenerationSpecInput, - PowerFactoryModelInput, - ProcessedDiffFilterInput, - ProcessedDiffSortCriteriaInput, - ResultSectionInput, - SincalModelGenerationSpecInput, - SincalModelInput, - StateOverlayInput, - StudyInput, - StudyResultInput, - TimePeriodInput, - TimePeriodLoadOverrideInput, - WorkPackageInput, - YearRangeInput, -) - -__all__ = [ - "AppOptionsInput", - "AsyncBaseClient", - "BaseModel", - "CandidateGenerationConfigInput", - "CandidateGenerationType", - "Client", - "ColumnGroup", - "ColumnName", - "ContainerType", - "DaysRequired", - "DiffType", - "DvmsConfigInput", - "DvmsRegulatorConfigInput", - "FeederConfigInput", - "FeederConfigsInput", - "FeederLoadAnalysisInput", - "FixedTimeInput", - "FixedTimeLoadOverrideInput", - "FlaForecastConfigInput", - "ForecastConfigInput", - "GeoJsonOverlayInput", - "GetOpenDssModelsFilterInput", - "GetOpenDssModelsSortCriteriaInput", - "GetPowerFactoryModelTemplatesFilterInput", - "GetPowerFactoryModelTemplatesSortCriteriaInput", - "GetPowerFactoryModelsFilterInput", - "GetPowerFactoryModelsSortCriteriaInput", - "GetSincalModelPresetsFilterInput", - "GetSincalModelPresetsSortCriteriaInput", - "GetSincalModelsFilterInput", - "GetSincalModelsSortCriteriaInput", - "GetStudiesFilterInput", - "GetStudiesSortCriteriaInput", - "GqlDistributionTransformerConfigInput", - "GqlLoadConfigInput", - "GqlScenarioConfigInput", - "GqlSincalModelForecastSpecInput", - "GraphQLClientError", - "GraphQLClientGraphQLError", - "GraphQLClientGraphQLMultiError", - "GraphQLClientHttpError", - "GraphQLClientInvalidResponseError", - "HcEnhancedMetricsConfigInput", - "HcExecutorConfigInput", - "HcFeederScenarioAllocationStrategy", - "HcGeneratorConfigInput", - "HcInverterControlConfigInput", - "HcLoadPlacement", - "HcMeterPlacementConfigInput", - "HcMetricsResultsConfigInput", - "HcModelConfigInput", - "HcNodeLevelResultsConfigInput", - "HcRawResultsConfigInput", - "HcResultProcessorConfigInput", - "HcScenarioConfigsFilterInput", - "HcSolveConfigInput", - "HcSolveMode", - "HcStoredResultsConfigInput", - "HcSwitchClass", - "HcSwitchMeterPlacementConfigInput", - "HcWorkPackagesFilterInput", - "HcWorkPackagesSortCriteriaInput", - "HcWriterConfigInput", - "HcWriterOutputConfigInput", - "HcWriterType", - "HostingCapacityFileType", - "IngestorConfigInput", - "IngestorRunState", - "IngestorRunsFilterInput", - "IngestorRunsSortCriteriaInput", - "IngestorRuntimeKind", - "InterventionClass", - "InterventionConfigInput", - "MeasurementZoneType", - "OpenDssCommonConfigInput", - "OpenDssModelGenerationSpecInput", - "OpenDssModelInput", - "OpenDssModelOptionsInput", - "OpenDssModelState", - "OpenDssModulesConfigInput", - "OpportunitiesNeed", - "OpportunitiesType", - "PhaseRebalanceProportionsInput", - "PowerFactoryModelGenerationSpecInput", - "PowerFactoryModelInput", - "PowerFactoryModelState", - "ProcessedDiffFilterInput", - "ProcessedDiffSortCriteriaInput", - "ResultSectionInput", - "SectionType", - "SerializationType", - "SincalFileType", - "SincalModelGenerationSpecInput", - "SincalModelInput", - "SincalModelState", - "SortOrder", - "StateOverlayInput", - "StudyInput", - "StudyResultInput", - "TimePeriodInput", - "TimePeriodLoadOverrideInput", - "Upload", - "VariantFileType", - "VariantStatus", - "VariantWorkflowStatus", - "WorkPackageInput", - "WorkPackageState", - "WorkflowStatus", - "YearRangeInput", -] diff --git a/src/zepben/eas/lib/generated_graphql_client/async_base_client.py b/src/zepben/eas/lib/generated_graphql_client/async_base_client.py deleted file mode 100644 index d9d808c..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/async_base_client.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -import asyncio -import enum -import json -from collections.abc import AsyncIterator -from typing import IO, Any, Optional, TypeVar, cast -from uuid import uuid4 -import httpx -from pydantic import BaseModel -from pydantic_core import to_jsonable_python -from .base_model import UNSET, Upload -from .exceptions import GraphQLClientError, GraphQLClientGraphQLMultiError, GraphQLClientHttpError, GraphQLClientInvalidMessageFormat, GraphQLClientInvalidResponseError -try: - from websockets import ClientConnection - from websockets import connect as ws_connect - from websockets.typing import Data, Origin, Subprotocol -except ImportError: - from contextlib import asynccontextmanager - - @asynccontextmanager - async def ws_connect(*args, **kwargs): - raise NotImplementedError("Subscriptions require 'websockets' package.") - yield - ClientConnection = Any - Data = Any - Origin = Any - - def Subprotocol(*args, **kwargs): - raise NotImplementedError("Subscriptions require 'websockets' package.") -Self = TypeVar('Self', bound='AsyncBaseClient') -GRAPHQL_TRANSPORT_WS = 'graphql-transport-ws' - -class GraphQLTransportWSMessageType(str, enum.Enum): - CONNECTION_INIT = 'connection_init' - CONNECTION_ACK = 'connection_ack' - PING = 'ping' - PONG = 'pong' - SUBSCRIBE = 'subscribe' - NEXT = 'next' - ERROR = 'error' - COMPLETE = 'complete' - -class AsyncBaseClient: - - def __init__(self, url: str='', headers: Optional[dict[str, str]]=None, http_client: Optional[httpx.AsyncClient]=None, ws_url: str='', ws_headers: Optional[dict[str, Any]]=None, ws_origin: Optional[str]=None, ws_connection_init_payload: Optional[dict[str, Any]]=None) -> None: - self.url = url - self.headers = headers - self.http_client = http_client if http_client else httpx.AsyncClient(headers=headers) - self.ws_url = ws_url - self.ws_headers = ws_headers or {} - self.ws_origin = Origin(ws_origin) if ws_origin else None - self.ws_connection_init_payload = ws_connection_init_payload - - async def __aenter__(self: Self) -> Self: - return self - - async def __aexit__(self, exc_type: object, exc_val: object, exc_tb: object) -> None: - await self.http_client.aclose() - - async def execute(self, query: str, operation_name: Optional[str]=None, variables: Optional[dict[str, Any]]=None, **kwargs: Any) -> httpx.Response: - (processed_variables, files, files_map) = self._process_variables(variables) - if files and files_map: - return await self._execute_multipart(query=query, operation_name=operation_name, variables=processed_variables, files=files, files_map=files_map, **kwargs) - return await self._execute_json(query=query, operation_name=operation_name, variables=processed_variables, **kwargs) - - def get_data(self, response: httpx.Response) -> dict[str, Any]: - if not response.is_success: - raise GraphQLClientHttpError(status_code=response.status_code, response=response) - try: - response_json = response.json() - except ValueError as exc: - raise GraphQLClientInvalidResponseError(response=response) from exc - if not isinstance(response_json, dict) or ('data' not in response_json and 'errors' not in response_json): - raise GraphQLClientInvalidResponseError(response=response) - data = response_json.get('data') - errors = response_json.get('errors') - if errors: - raise GraphQLClientGraphQLMultiError.from_errors_dicts(errors_dicts=errors, data=data) - return cast(dict[str, Any], data) - - async def execute_ws(self, query: str, operation_name: Optional[str]=None, variables: Optional[dict[str, Any]]=None, **kwargs: Any) -> AsyncIterator[dict[str, Any]]: - headers = self.ws_headers.copy() - headers.update(kwargs.pop('additional_headers', {})) - merged_kwargs: dict[str, Any] = {'origin': self.ws_origin} - merged_kwargs.update(kwargs) - merged_kwargs['additional_headers'] = headers - operation_id = str(uuid4()) - async with ws_connect(self.ws_url, subprotocols=[Subprotocol(GRAPHQL_TRANSPORT_WS)], **merged_kwargs) as websocket: - await self._send_connection_init(websocket) - try: - await asyncio.wait_for(self._wait_for_connection_ack(websocket), timeout=5.0) - except asyncio.TimeoutError as exc: - raise GraphQLClientError('Connection ack not received within 5 seconds') from exc - await self._send_subscribe(websocket, operation_id=operation_id, query=query, operation_name=operation_name, variables=variables) - async for message in websocket: - data = await self._handle_ws_message(message, websocket) - if data and 'connection_ack' not in data: - yield data - - def _process_variables(self, variables: Optional[dict[str, Any]]) -> tuple[dict[str, Any], dict[str, tuple[str, IO[bytes], str]], dict[str, list[str]]]: - if not variables: - return ({}, {}, {}) - serializable_variables = self._convert_dict_to_json_serializable(variables) - return self._get_files_from_variables(serializable_variables) - - def _convert_dict_to_json_serializable(self, dict_: dict[str, Any]) -> dict[str, Any]: - return {key: self._convert_value(value) for (key, value) in dict_.items() if value is not UNSET} - - def _convert_value(self, value: Any) -> Any: - if isinstance(value, BaseModel): - return value.model_dump(by_alias=True, exclude_unset=True) - if isinstance(value, list): - return [self._convert_value(item) for item in value] - return value - - def _get_files_from_variables(self, variables: dict[str, Any]) -> tuple[dict[str, Any], dict[str, tuple[str, IO[bytes], str]], dict[str, list[str]]]: - files_map: dict[str, list[str]] = {} - files_list: list[Upload] = [] - - def separate_files(path: str, obj: Any) -> Any: - if isinstance(obj, list): - nulled_list = [] - for (index, value) in enumerate(obj): - value = separate_files(f'{path}.{index}', value) - nulled_list.append(value) - return nulled_list - if isinstance(obj, dict): - nulled_dict = {} - for (key, value) in obj.items(): - value = separate_files(f'{path}.{key}', value) - nulled_dict[key] = value - return nulled_dict - if isinstance(obj, Upload): - if obj in files_list: - file_index = files_list.index(obj) - files_map[str(file_index)].append(path) - else: - file_index = len(files_list) - files_list.append(obj) - files_map[str(file_index)] = [path] - return None - return obj - nulled_variables = separate_files('variables', variables) - files: dict[str, tuple[str, IO[bytes], str]] = {str(i): (file_.filename, cast(IO[bytes], file_.content), file_.content_type) for (i, file_) in enumerate(files_list)} - return (nulled_variables, files, files_map) - - async def _execute_multipart(self, query: str, operation_name: Optional[str], variables: dict[str, Any], files: dict[str, tuple[str, IO[bytes], str]], files_map: dict[str, list[str]], **kwargs: Any) -> httpx.Response: - data = {'operations': json.dumps({'query': query, 'operationName': operation_name, 'variables': variables}, default=to_jsonable_python), 'map': json.dumps(files_map, default=to_jsonable_python)} - return await self.http_client.post(url=self.url, data=data, files=files, **kwargs) - - async def _execute_json(self, query: str, operation_name: Optional[str], variables: dict[str, Any], **kwargs: Any) -> httpx.Response: - headers: dict[str, str] = {'Content-type': 'application/json'} - headers.update(kwargs.get('headers', {})) - merged_kwargs: dict[str, Any] = kwargs.copy() - merged_kwargs['headers'] = headers - return await self.http_client.post(url=self.url, content=json.dumps({'query': query, 'operationName': operation_name, 'variables': variables}, default=to_jsonable_python), **merged_kwargs) - - async def _send_connection_init(self, websocket: ClientConnection) -> None: - payload: dict[str, Any] = {'type': GraphQLTransportWSMessageType.CONNECTION_INIT.value} - if self.ws_connection_init_payload: - payload['payload'] = self.ws_connection_init_payload - await websocket.send(json.dumps(payload)) - - async def _wait_for_connection_ack(self, websocket: ClientConnection) -> None: - """Read messages until connection_ack; handle ping/pong in between.""" - async for message in websocket: - data = await self._handle_ws_message(message, websocket) - if data is not None and 'connection_ack' in data: - return - - async def _send_subscribe(self, websocket: ClientConnection, operation_id: str, query: str, operation_name: Optional[str]=None, variables: Optional[dict[str, Any]]=None) -> None: - payload_inner: dict[str, Any] = {'query': query, 'operationName': operation_name} - if variables: - payload_inner['variables'] = self._convert_dict_to_json_serializable(variables) - payload: dict[str, Any] = {'id': operation_id, 'type': GraphQLTransportWSMessageType.SUBSCRIBE.value, 'payload': payload_inner} - await websocket.send(json.dumps(payload)) - - async def _handle_ws_message(self, message: Data, websocket: ClientConnection, expected_type: Optional[GraphQLTransportWSMessageType]=None) -> Optional[dict[str, Any]]: - try: - message_dict = json.loads(message) - except json.JSONDecodeError as exc: - raise GraphQLClientInvalidMessageFormat(message=message) from exc - type_ = message_dict.get('type') - payload = message_dict.get('payload', {}) - if not type_ or type_ not in {t.value for t in GraphQLTransportWSMessageType}: - raise GraphQLClientInvalidMessageFormat(message=message) - if expected_type and expected_type != type_: - raise GraphQLClientInvalidMessageFormat(f'Invalid message received. Expected: {expected_type.value}') - if type_ == GraphQLTransportWSMessageType.NEXT: - if 'data' not in payload: - raise GraphQLClientInvalidMessageFormat(message=message) - return cast(dict[str, Any], payload['data']) - if type_ == GraphQLTransportWSMessageType.COMPLETE: - await websocket.close() - elif type_ == GraphQLTransportWSMessageType.PING: - await websocket.send(json.dumps({'type': GraphQLTransportWSMessageType.PONG.value})) - elif type_ == GraphQLTransportWSMessageType.ERROR: - raise GraphQLClientGraphQLMultiError.from_errors_dicts(errors_dicts=payload, data=message_dict) - elif type_ == GraphQLTransportWSMessageType.CONNECTION_ACK: - return {'connection_ack': True} - return None \ No newline at end of file diff --git a/src/zepben/eas/lib/generated_graphql_client/base_model.py b/src/zepben/eas/lib/generated_graphql_client/base_model.py deleted file mode 100644 index 9ede9d3..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/base_model.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from io import IOBase -from pydantic import BaseModel as PydanticBaseModel -from pydantic import ConfigDict - -class UnsetType: - - def __bool__(self) -> bool: - return False -UNSET = UnsetType() - -class BaseModel(PydanticBaseModel): - model_config = ConfigDict(populate_by_name=True, validate_assignment=True, arbitrary_types_allowed=True, protected_namespaces=()) - -class Upload: - - def __init__(self, filename: str, content: IOBase, content_type: str): - self.filename = filename - self.content = content - self.content_type = content_type \ No newline at end of file diff --git a/src/zepben/eas/lib/generated_graphql_client/base_operation.py b/src/zepben/eas/lib/generated_graphql_client/base_operation.py deleted file mode 100644 index a18020e..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/base_operation.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional, Union -from graphql import ArgumentNode, FieldNode, InlineFragmentNode, NamedTypeNode, NameNode, SelectionSetNode, VariableNode - -class GraphQLArgument: - """ - Represents a GraphQL argument and allows conversion to an AST structure. - """ - - def __init__(self, argument_name: str, argument_value: Any) -> None: - self._name = argument_name - self._value = argument_value - - def to_ast(self) -> ArgumentNode: - """Converts the argument to an ArgumentNode AST object.""" - return ArgumentNode(name=NameNode(value=self._name), value=VariableNode(name=NameNode(value=self._value))) - -class GraphQLField: - """ - Represents a GraphQL field with its name, arguments, subfields, alias, - and inline fragments. - - Attributes: - formatted_variables (dict[str, dict[str, Any]]): The formatted arguments - of the GraphQL field. - """ - - def __init__(self, field_name: str, arguments: Optional[dict[str, dict[str, Any]]]=None) -> None: - self._field_name = field_name - self._variables = arguments or {} - self.formatted_variables: dict[str, dict[str, Any]] = {} - self._subfields: list[GraphQLField] = [] - self._alias: Optional[str] = None - self._inline_fragments: dict[str, tuple[GraphQLField, ...]] = {} - - def alias(self, alias: str) -> 'GraphQLField': - """Sets an alias for the GraphQL field and returns the instance.""" - self._alias = alias - return self - - def _build_field_name(self) -> str: - """Builds the field name, including the alias if present.""" - return f'{self._alias}: {self._field_name}' if self._alias else self._field_name - - def _build_selections(self, idx: int, used_names: set[str]) -> list[Union[FieldNode, InlineFragmentNode]]: - """Builds the selection set for the current GraphQL field, - including subfields and inline fragments.""" - selections: list[Union[FieldNode, InlineFragmentNode]] = [subfield.to_ast(idx, used_names) for subfield in self._subfields] - for (name, subfields) in self._inline_fragments.items(): - selections.append(InlineFragmentNode(type_condition=NamedTypeNode(name=NameNode(value=name)), selection_set=SelectionSetNode(selections=[subfield.to_ast(idx, used_names) for subfield in subfields]))) - return selections - - def _format_variable_name(self, idx: int, var_name: str, used_names: set[str]) -> str: - """Generates a unique variable name by appending an index and, - if necessary, an additional counter to avoid duplicates.""" - base_name = f'{var_name}_{idx}' - unique_name = base_name - counter = 1 - while unique_name in used_names: - unique_name = f'{base_name}_{counter}' - counter += 1 - used_names.add(unique_name) - return unique_name - - def _collect_all_variables(self, idx: int, used_names: set[str]) -> None: - """ - Collects and formats all variables for the current GraphQL field, - ensuring unique names. - """ - self.formatted_variables = {} - for (k, v) in self._variables.items(): - unique_name = self._format_variable_name(idx, k, used_names) - self.formatted_variables[unique_name] = {'name': k, 'type': v['type'], 'value': v['value']} - - def to_ast(self, idx: int, used_names: Optional[set[str]]=None) -> FieldNode: - """Converts the current GraphQL field to an AST (Abstract Syntax Tree) node.""" - if used_names is None: - used_names = set() - self._collect_all_variables(idx, used_names) - return FieldNode(name=NameNode(value=self._build_field_name()), arguments=[GraphQLArgument(v['name'], k).to_ast() for (k, v) in self.formatted_variables.items()], selection_set=SelectionSetNode(selections=self._build_selections(idx, used_names)) if self._subfields or self._inline_fragments else None) - - def get_formatted_variables(self) -> dict[str, dict[str, Any]]: - """ - Retrieves all formatted variables for the current GraphQL field, - including those from subfields and inline fragments. - """ - formatted_variables = self.formatted_variables.copy() - for subfield in self._subfields: - formatted_variables.update(subfield.get_formatted_variables()) - for subfields in self._inline_fragments.values(): - for subfield in subfields: - formatted_variables.update(subfield.get_formatted_variables()) - return formatted_variables - - @classmethod - def all_fields(cls) -> 'Generator[GraphQLField | MethodType, None, None]': - """ - returns a generator over all ``GraphQLField``s that a given class returns - - :param cls: class to check - :return: generator over all GraphQLField's in a given class - """ - import inspect - for k in dir(cls): - if k.startswith('_'): - continue - if k == 'all_fields': - continue - v = getattr(cls, k) - if isinstance(v, GraphQLField): - yield v - elif inspect.ismethod(v): - yield v().fields(*v().all_fields()) \ No newline at end of file diff --git a/src/zepben/eas/lib/generated_graphql_client/client.py b/src/zepben/eas/lib/generated_graphql_client/client.py deleted file mode 100644 index c6c3710..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/client.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any - -from graphql import ( - DocumentNode, - NamedTypeNode, - NameNode, - OperationDefinitionNode, - OperationType, - SelectionNode, - SelectionSetNode, - VariableDefinitionNode, - VariableNode, - print_ast, -) - -from .async_base_client import AsyncBaseClient -from .base_operation import GraphQLField - - -def gql(q: str) -> str: - return q - - -class Client(AsyncBaseClient): - async def execute_custom_operation( - self, *fields: GraphQLField, operation_type: OperationType, operation_name: str - ) -> dict[str, Any]: - selections = self._build_selection_set(fields) - combined_variables = self._combine_variables(fields) - variable_definitions = self._build_variable_definitions( - combined_variables["types"] - ) - operation_ast = self._build_operation_ast( - selections, operation_type, operation_name, variable_definitions - ) - response = await self.execute( - print_ast(operation_ast), - variables=combined_variables["values"], - operation_name=operation_name, - ) - return self.get_data(response) - - def _combine_variables( - self, fields: tuple[GraphQLField, ...] - ) -> dict[str, dict[str, Any]]: - variables_types_combined = {} - processed_variables_combined = {} - for field in fields: - formatted_variables = field.get_formatted_variables() - variables_types_combined.update( - {k: v["type"] for k, v in formatted_variables.items()} - ) - processed_variables_combined.update( - {k: v["value"] for k, v in formatted_variables.items()} - ) - return { - "types": variables_types_combined, - "values": processed_variables_combined, - } - - def _build_variable_definitions( - self, variables_types_combined: dict[str, str] - ) -> list[VariableDefinitionNode]: - return [ - VariableDefinitionNode( - variable=VariableNode(name=NameNode(value=var_name)), - type=NamedTypeNode(name=NameNode(value=var_value)), - ) - for var_name, var_value in variables_types_combined.items() - ] - - def _build_operation_ast( - self, - selections: list[SelectionNode], - operation_type: OperationType, - operation_name: str, - variable_definitions: list[VariableDefinitionNode], - ) -> DocumentNode: - return DocumentNode( - definitions=[ - OperationDefinitionNode( - operation=operation_type, - name=NameNode(value=operation_name), - variable_definitions=variable_definitions, - selection_set=SelectionSetNode(selections=selections), - ) - ] - ) - - def _build_selection_set( - self, fields: tuple[GraphQLField, ...] - ) -> list[SelectionNode]: - return [field.to_ast(idx) for idx, field in enumerate(fields)] - - async def query(self, *fields: GraphQLField, operation_name: str) -> dict[str, Any]: - return await self.execute_custom_operation( - *fields, operation_type=OperationType.QUERY, operation_name=operation_name - ) - - async def mutation( - self, *fields: GraphQLField, operation_name: str - ) -> dict[str, Any]: - return await self.execute_custom_operation( - *fields, - operation_type=OperationType.MUTATION, - operation_name=operation_name, - ) diff --git a/src/zepben/eas/lib/generated_graphql_client/custom_fields.py b/src/zepben/eas/lib/generated_graphql_client/custom_fields.py deleted file mode 100644 index 6e6ef27..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/custom_fields.py +++ /dev/null @@ -1,1966 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional, Union - -from .base_operation import GraphQLField -from .custom_typing_fields import ( - AppOptionsGraphQLField, - ColumnGraphQLField, - CoordinateGraphQLField, - CustomerDetailsGraphQLField, - CustomerDetailsResponseGraphQLField, - CustomerListColumnConfigGraphQLField, - DiffResultGraphQLField, - DurationCurveByTerminalGraphQLField, - DurationCurveGraphQLField, - DurationCurvePointGraphQLField, - EquipmentGraphQLField, - FeederLoadAnalysisReportGraphQLField, - FeederLoadAnalysisSpecGraphQLField, - GeoJsonFeatureGraphQLField, - GeoJsonGeometryGraphQLField, - GeoJsonOverlayGraphQLField, - GeoJsonPropertiesGraphQLField, - GqlDistributionTransformerConfigGraphQLField, - GqlLoadConfigGraphQLField, - GqlScenarioConfigGraphQLField, - GqlTxTapRecordGraphQLField, - GqlUserGraphQLField, - GqlUserResponseGraphQLField, - HcCalibrationGraphQLField, - HcModelGraphQLField, - HcScenarioConfigsPageGraphQLField, - HcWorkPackageGraphQLField, - HcWorkPackagePageGraphQLField, - IngestionJobGraphQLField, - IngestionRunGraphQLField, - IngestorRunPageGraphQLField, - JobSourceGraphQLField, - MachineUserGraphQLField, - MetricGraphQLField, - NetworkModelGraphQLField, - NetworkModelsGraphQLField, - OpenDssModelGraphQLField, - OpenDssModelPageGraphQLField, - OpportunitiesByYearGraphQLField, - OpportunityGraphQLField, - OpportunityLocationGraphQLField, - PowerFactoryModelGenerationSpecGraphQLField, - PowerFactoryModelGraphQLField, - PowerFactoryModelPageGraphQLField, - PowerFactoryModelTemplateGraphQLField, - PowerFactoryModelTemplatePageGraphQLField, - ProcessedDiffGraphQLField, - ProcessedDiffPageGraphQLField, - RemoveAppOptionResultGraphQLField, - ResultSectionGraphQLField, - ScenarioConfigurationGraphQLField, - SincalConfigFileGraphQLField, - SincalGlobalInputsConfigGraphQLField, - SincalModelGenerationSpecGraphQLField, - SincalModelGraphQLField, - SincalModelPageGraphQLField, - SincalModelPresetGraphQLField, - SincalModelPresetPageGraphQLField, - StateOverlayGraphQLField, - StudyGraphQLField, - StudyPageGraphQLField, - StudyResultGraphQLField, - TableSectionGraphQLField, - UploadUrlResponseGraphQLField, - UserCustomerListColumnConfigGraphQLField, - VariantGraphQLField, - VariantWorkPackageGraphQLField, - WorkPackageModelGroupingsGraphQLField, - WorkPackageModelTotalsGraphQLField, - WorkPackageProgressDetailsGraphQLField, - WorkPackageTreeGraphQLField, -) -from .enums import SerializationType - - -class AppOptionsFields(GraphQLField): - """Application configuration option.""" - - asset_name_format: "AppOptionsGraphQLField" = AppOptionsGraphQLField( - "assetNameFormat" - ) - pole_string_format: "AppOptionsGraphQLField" = AppOptionsGraphQLField( - "poleStringFormat" - ) - - def fields(self, *subfields: AppOptionsGraphQLField) -> "AppOptionsFields": - """Subfields should come from the AppOptionsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "AppOptionsFields": - self._alias = alias - return self - - -class ColumnFields(GraphQLField): - key: "ColumnGraphQLField" = ColumnGraphQLField("key") - name: "ColumnGraphQLField" = ColumnGraphQLField("name") - - def fields(self, *subfields: ColumnGraphQLField) -> "ColumnFields": - """Subfields should come from the ColumnFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "ColumnFields": - self._alias = alias - return self - - -class CoordinateFields(GraphQLField): - latitude: "CoordinateGraphQLField" = CoordinateGraphQLField("latitude") - longitude: "CoordinateGraphQLField" = CoordinateGraphQLField("longitude") - - def fields(self, *subfields: CoordinateGraphQLField) -> "CoordinateFields": - """Subfields should come from the CoordinateFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "CoordinateFields": - self._alias = alias - return self - - -class CustomerDetailsFields(GraphQLField): - """Detailed customer information including both customer-specific and network-specific fields.""" - - customer_mrid: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "customerMrid" - ) - customer_type: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "customerType" - ) - distributor: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "distributor" - ) - dlf: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("dlf") - feeder: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("feeder") - first_name: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("firstName") - is_embedded_network: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "isEmbeddedNetwork" - ) - is_energy_feedback: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "isEnergyFeedback" - ) - last_name: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("lastName") - lv_feeder: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("lvFeeder") - meter_number: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "meterNumber" - ) - mobile_number: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "mobileNumber" - ) - move_in_date: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "moveInDate" - ) - nmi: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("nmi") - nmi_class: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("nmiClass") - phone_number: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "phoneNumber" - ) - postal_address: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "postalAddress" - ) - sensitivity_category: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "sensitivityCategory" - ) - service_address: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "serviceAddress" - ) - service_provision_status: "CustomerDetailsGraphQLField" = ( - CustomerDetailsGraphQLField("serviceProvisionStatus") - ) - supply_point_id: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "supplyPointId" - ) - tariff: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("tariff") - tni: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField("tni") - transformer_description: "CustomerDetailsGraphQLField" = ( - CustomerDetailsGraphQLField("transformerDescription") - ) - transformer_id: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "transformerId" - ) - zone_substation: "CustomerDetailsGraphQLField" = CustomerDetailsGraphQLField( - "zoneSubstation" - ) - - def fields( - self, *subfields: CustomerDetailsGraphQLField - ) -> "CustomerDetailsFields": - """Subfields should come from the CustomerDetailsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "CustomerDetailsFields": - self._alias = alias - return self - - -class CustomerDetailsResponseFields(GraphQLField): - @classmethod - def customer_details(cls) -> "CustomerDetailsFields": - return CustomerDetailsFields("customerDetails") - - def fields( - self, - *subfields: Union[CustomerDetailsResponseGraphQLField, "CustomerDetailsFields"], - ) -> "CustomerDetailsResponseFields": - """Subfields should come from the CustomerDetailsResponseFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "CustomerDetailsResponseFields": - self._alias = alias - return self - - -class CustomerListColumnConfigFields(GraphQLField): - """Defines a column available for configuration in the customer list table.""" - - column_name: "CustomerListColumnConfigGraphQLField" = ( - CustomerListColumnConfigGraphQLField("columnName") - ) - "The unique name of the column." - group: "CustomerListColumnConfigGraphQLField" = ( - CustomerListColumnConfigGraphQLField("group") - ) - "The group this column belongs to (e.g., PII, NON_PII)." - - def fields( - self, *subfields: CustomerListColumnConfigGraphQLField - ) -> "CustomerListColumnConfigFields": - """Subfields should come from the CustomerListColumnConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "CustomerListColumnConfigFields": - self._alias = alias - return self - - -class DiffResultFields(GraphQLField): - entries: "DiffResultGraphQLField" = DiffResultGraphQLField("entries") - id: "DiffResultGraphQLField" = DiffResultGraphQLField("id") - - def fields(self, *subfields: DiffResultGraphQLField) -> "DiffResultFields": - """Subfields should come from the DiffResultFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "DiffResultFields": - self._alias = alias - return self - - -class DurationCurveFields(GraphQLField): - @classmethod - def points(cls) -> "DurationCurvePointFields": - return DurationCurvePointFields("points") - - def fields( - self, *subfields: Union[DurationCurveGraphQLField, "DurationCurvePointFields"] - ) -> "DurationCurveFields": - """Subfields should come from the DurationCurveFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "DurationCurveFields": - self._alias = alias - return self - - -class DurationCurveByTerminalFields(GraphQLField): - """The duration curve for a terminal of a conducting equipment.""" - - @classmethod - def duration_curve(cls) -> "DurationCurveFields": - return DurationCurveFields("durationCurve") - - terminal_sequence_number: "DurationCurveByTerminalGraphQLField" = ( - DurationCurveByTerminalGraphQLField("terminalSequenceNumber") - ) - - def fields( - self, - *subfields: Union[DurationCurveByTerminalGraphQLField, "DurationCurveFields"], - ) -> "DurationCurveByTerminalFields": - """Subfields should come from the DurationCurveByTerminalFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "DurationCurveByTerminalFields": - self._alias = alias - return self - - -class DurationCurvePointFields(GraphQLField): - conducting_equipment: "DurationCurvePointGraphQLField" = ( - DurationCurvePointGraphQLField("conductingEquipment") - ) - feeder: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField("feeder") - kw: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField("kw") - measurement_zone_type: "DurationCurvePointGraphQLField" = ( - DurationCurvePointGraphQLField("measurementZoneType") - ) - percentage_of_time: "DurationCurvePointGraphQLField" = ( - DurationCurvePointGraphQLField("percentageOfTime") - ) - scenario: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField( - "scenario" - ) - terminal_sequence_number: "DurationCurvePointGraphQLField" = ( - DurationCurvePointGraphQLField("terminalSequenceNumber") - ) - timestamp: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField( - "timestamp" - ) - v_base: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField("vBase") - work_package_id: "DurationCurvePointGraphQLField" = DurationCurvePointGraphQLField( - "workPackageId" - ) - - def fields( - self, *subfields: DurationCurvePointGraphQLField - ) -> "DurationCurvePointFields": - """Subfields should come from the DurationCurvePointFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "DurationCurvePointFields": - self._alias = alias - return self - - -class EquipmentFields(GraphQLField): - m_rid: "EquipmentGraphQLField" = EquipmentGraphQLField("mRID") - - @classmethod - def location(cls) -> "CoordinateFields": - return CoordinateFields("location") - - def fields( - self, *subfields: Union[EquipmentGraphQLField, "CoordinateFields"] - ) -> "EquipmentFields": - """Subfields should come from the EquipmentFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "EquipmentFields": - self._alias = alias - return self - - -class FeederLoadAnalysisReportFields(GraphQLField): - completed_at: "FeederLoadAnalysisReportGraphQLField" = ( - FeederLoadAnalysisReportGraphQLField("completedAt") - ) - created_at: "FeederLoadAnalysisReportGraphQLField" = ( - FeederLoadAnalysisReportGraphQLField("createdAt") - ) - created_by: "FeederLoadAnalysisReportGraphQLField" = ( - FeederLoadAnalysisReportGraphQLField("createdBy") - ) - errors: "FeederLoadAnalysisReportGraphQLField" = ( - FeederLoadAnalysisReportGraphQLField("errors") - ) - - @classmethod - def generation_spec(cls) -> "FeederLoadAnalysisSpecFields": - return FeederLoadAnalysisSpecFields("generationSpec") - - id: "FeederLoadAnalysisReportGraphQLField" = FeederLoadAnalysisReportGraphQLField( - "id" - ) - name: "FeederLoadAnalysisReportGraphQLField" = FeederLoadAnalysisReportGraphQLField( - "name" - ) - state: "FeederLoadAnalysisReportGraphQLField" = ( - FeederLoadAnalysisReportGraphQLField("state") - ) - - def fields( - self, - *subfields: Union[ - FeederLoadAnalysisReportGraphQLField, "FeederLoadAnalysisSpecFields" - ], - ) -> "FeederLoadAnalysisReportFields": - """Subfields should come from the FeederLoadAnalysisReportFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "FeederLoadAnalysisReportFields": - self._alias = alias - return self - - -class FeederLoadAnalysisSpecFields(GraphQLField): - aggregate_at_feeder_level: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("aggregateAtFeederLevel") - ) - "Request for a report which aggregate all downstream load at the feeder level" - end_date: "FeederLoadAnalysisSpecGraphQLField" = FeederLoadAnalysisSpecGraphQLField( - "endDate" - ) - "End date for this analysis" - feeders: "FeederLoadAnalysisSpecGraphQLField" = FeederLoadAnalysisSpecGraphQLField( - "feeders" - ) - "The mRIDs of feeders to solve for feeder load analysis." - fetch_lv_network: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("fetchLvNetwork") - ) - "Whether to stop analysis at distribution transformer" - geographical_regions: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("geographicalRegions") - ) - "The mRIDs of Geographical Region to solve for feeder load analysis." - output: "FeederLoadAnalysisSpecGraphQLField" = FeederLoadAnalysisSpecGraphQLField( - "output" - ) - "The file name of the resulting study" - process_coincident_loads: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("processCoincidentLoads") - ) - "Whether to include values corresponding to conductor event time points in the report" - process_feeder_loads: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("processFeederLoads") - ) - "Whether to include values corresponding to feeder event time points in the report" - produce_basic_report: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("produceBasicReport") - ) - "Request for a basic report" - produce_conductor_report: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("produceConductorReport") - ) - "Request for an extensive report" - start_date: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("startDate") - ) - "Start date for this analysis" - sub_geographical_regions: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("subGeographicalRegions") - ) - "The mRIDs of sub-Geographical Region to solve for feeder load analysis." - substations: "FeederLoadAnalysisSpecGraphQLField" = ( - FeederLoadAnalysisSpecGraphQLField("substations") - ) - "The mRIDs of substations to solve for feeder load analysis." - - def fields( - self, *subfields: FeederLoadAnalysisSpecGraphQLField - ) -> "FeederLoadAnalysisSpecFields": - """Subfields should come from the FeederLoadAnalysisSpecFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "FeederLoadAnalysisSpecFields": - self._alias = alias - return self - - -class GeoJsonFeatureFields(GraphQLField): - @classmethod - def geometry(cls) -> "GeoJsonGeometryFields": - return GeoJsonGeometryFields("geometry") - - @classmethod - def properties(cls) -> "GeoJsonPropertiesFields": - return GeoJsonPropertiesFields("properties") - - type_: "GeoJsonFeatureGraphQLField" = GeoJsonFeatureGraphQLField("type") - - def fields( - self, - *subfields: Union[ - GeoJsonFeatureGraphQLField, - "GeoJsonGeometryFields", - "GeoJsonPropertiesFields", - ], - ) -> "GeoJsonFeatureFields": - """Subfields should come from the GeoJsonFeatureFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GeoJsonFeatureFields": - self._alias = alias - return self - - -class GeoJsonGeometryFields(GraphQLField): - @classmethod - def coordinates(cls) -> "CoordinateFields": - return CoordinateFields("coordinates") - - type_: "GeoJsonGeometryGraphQLField" = GeoJsonGeometryGraphQLField("type") - - def fields( - self, *subfields: Union[GeoJsonGeometryGraphQLField, "CoordinateFields"] - ) -> "GeoJsonGeometryFields": - """Subfields should come from the GeoJsonGeometryFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GeoJsonGeometryFields": - self._alias = alias - return self - - -class GeoJsonOverlayFields(GraphQLField): - styles: "GeoJsonOverlayGraphQLField" = GeoJsonOverlayGraphQLField("styles") - id: "GeoJsonOverlayGraphQLField" = GeoJsonOverlayGraphQLField("id") - data: "GeoJsonOverlayGraphQLField" = GeoJsonOverlayGraphQLField("data") - source_properties: "GeoJsonOverlayGraphQLField" = GeoJsonOverlayGraphQLField( - "sourceProperties" - ) - - def fields(self, *subfields: GeoJsonOverlayGraphQLField) -> "GeoJsonOverlayFields": - """Subfields should come from the GeoJsonOverlayFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GeoJsonOverlayFields": - self._alias = alias - return self - - -class GeoJsonPropertiesFields(GraphQLField): - detail: "GeoJsonPropertiesGraphQLField" = GeoJsonPropertiesGraphQLField("detail") - properties: "GeoJsonPropertiesGraphQLField" = GeoJsonPropertiesGraphQLField( - "properties" - ) - - def fields( - self, *subfields: GeoJsonPropertiesGraphQLField - ) -> "GeoJsonPropertiesFields": - """Subfields should come from the GeoJsonPropertiesFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GeoJsonPropertiesFields": - self._alias = alias - return self - - -class GqlDistributionTransformerConfigFields(GraphQLField): - r_ground: "GqlDistributionTransformerConfigGraphQLField" = ( - GqlDistributionTransformerConfigGraphQLField("rGround") - ) - x_ground: "GqlDistributionTransformerConfigGraphQLField" = ( - GqlDistributionTransformerConfigGraphQLField("xGround") - ) - - def fields( - self, *subfields: GqlDistributionTransformerConfigGraphQLField - ) -> "GqlDistributionTransformerConfigFields": - """Subfields should come from the GqlDistributionTransformerConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlDistributionTransformerConfigFields": - self._alias = alias - return self - - -class GqlLoadConfigFields(GraphQLField): - spread_max_demand: "GqlLoadConfigGraphQLField" = GqlLoadConfigGraphQLField( - "spreadMaxDemand" - ) - - def fields(self, *subfields: GqlLoadConfigGraphQLField) -> "GqlLoadConfigFields": - """Subfields should come from the GqlLoadConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlLoadConfigFields": - self._alias = alias - return self - - -class GqlScenarioConfigFields(GraphQLField): - bess_upgrade_threshold: "GqlScenarioConfigGraphQLField" = ( - GqlScenarioConfigGraphQLField("bessUpgradeThreshold") - ) - pv_upgrade_threshold: "GqlScenarioConfigGraphQLField" = ( - GqlScenarioConfigGraphQLField("pvUpgradeThreshold") - ) - scenario_id: "GqlScenarioConfigGraphQLField" = GqlScenarioConfigGraphQLField( - "scenarioID" - ) - years: "GqlScenarioConfigGraphQLField" = GqlScenarioConfigGraphQLField("years") - - def fields( - self, *subfields: GqlScenarioConfigGraphQLField - ) -> "GqlScenarioConfigFields": - """Subfields should come from the GqlScenarioConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlScenarioConfigFields": - self._alias = alias - return self - - -class GqlTxTapRecordFields(GraphQLField): - control_enabled: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField( - "controlEnabled" - ) - high_step: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField("highStep") - id: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField("id") - low_step: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField("lowStep") - nominal_tap_num: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField( - "nominalTapNum" - ) - step_voltage_increment: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField( - "stepVoltageIncrement" - ) - tap_position: "GqlTxTapRecordGraphQLField" = GqlTxTapRecordGraphQLField( - "tapPosition" - ) - - def fields(self, *subfields: GqlTxTapRecordGraphQLField) -> "GqlTxTapRecordFields": - """Subfields should come from the GqlTxTapRecordFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlTxTapRecordFields": - self._alias = alias - return self - - -class GqlUserFields(GraphQLField): - email: "GqlUserGraphQLField" = GqlUserGraphQLField("email") - identity_provider: "GqlUserGraphQLField" = GqlUserGraphQLField("identityProvider") - username: "GqlUserGraphQLField" = GqlUserGraphQLField("username") - id: "GqlUserGraphQLField" = GqlUserGraphQLField("id") - - def fields(self, *subfields: GqlUserGraphQLField) -> "GqlUserFields": - """Subfields should come from the GqlUserFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlUserFields": - self._alias = alias - return self - - -class GqlUserResponseFields(GraphQLField): - email: "GqlUserResponseGraphQLField" = GqlUserResponseGraphQLField("email") - id: "GqlUserResponseGraphQLField" = GqlUserResponseGraphQLField("id") - identity_provider: "GqlUserResponseGraphQLField" = GqlUserResponseGraphQLField( - "identityProvider" - ) - permissions: "GqlUserResponseGraphQLField" = GqlUserResponseGraphQLField( - "permissions" - ) - username: "GqlUserResponseGraphQLField" = GqlUserResponseGraphQLField("username") - - def fields( - self, *subfields: GqlUserResponseGraphQLField - ) -> "GqlUserResponseFields": - """Subfields should come from the GqlUserResponseFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "GqlUserResponseFields": - self._alias = alias - return self - - -class HcCalibrationFields(GraphQLField): - calibration_time_local: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField( - "calibrationTimeLocal" - ) - calibration_work_package_config: "HcCalibrationGraphQLField" = ( - HcCalibrationGraphQLField("calibrationWorkPackageConfig") - ) - completed_at: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("completedAt") - feeders: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("feeders") - name: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("name") - run_id: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("runId") - run_info: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("runInfo") - start_at: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("startAt") - status: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("status") - workflow_id: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("workflowId") - id: "HcCalibrationGraphQLField" = HcCalibrationGraphQLField("id") - - def fields(self, *subfields: HcCalibrationGraphQLField) -> "HcCalibrationFields": - """Subfields should come from the HcCalibrationFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "HcCalibrationFields": - self._alias = alias - return self - - -class HcModelFields(GraphQLField): - """HC model representation""" - - feeder: "HcModelGraphQLField" = HcModelGraphQLField("feeder") - scenario: "HcModelGraphQLField" = HcModelGraphQLField("scenario") - year: "HcModelGraphQLField" = HcModelGraphQLField("year") - - def fields(self, *subfields: HcModelGraphQLField) -> "HcModelFields": - """Subfields should come from the HcModelFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "HcModelFields": - self._alias = alias - return self - - -class HcScenarioConfigsPageFields(GraphQLField): - offset: "HcScenarioConfigsPageGraphQLField" = HcScenarioConfigsPageGraphQLField( - "offset" - ) - - @classmethod - def scenario_configs(cls) -> "ScenarioConfigurationFields": - return ScenarioConfigurationFields("scenarioConfigs") - - total_count: "HcScenarioConfigsPageGraphQLField" = ( - HcScenarioConfigsPageGraphQLField("totalCount") - ) - - def fields( - self, - *subfields: Union[ - HcScenarioConfigsPageGraphQLField, "ScenarioConfigurationFields" - ], - ) -> "HcScenarioConfigsPageFields": - """Subfields should come from the HcScenarioConfigsPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "HcScenarioConfigsPageFields": - self._alias = alias - return self - - -class HcWorkPackageFields(GraphQLField): - completed_at: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("completedAt") - created_at: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("createdAt") - - @classmethod - def created_by(cls) -> "GqlUserFields": - return GqlUserFields("createdBy") - - feeders: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("feeders") - is_deleted: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("isDeleted") - load_type: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("loadType") - name: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("name") - parent_id: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("parentId") - - @classmethod - def progress_details(cls) -> "WorkPackageProgressDetailsFields": - return WorkPackageProgressDetailsFields("progressDetails") - - scenarios: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("scenarios") - status: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("status") - time_period_end: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField( - "timePeriodEnd" - ) - time_period_start: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField( - "timePeriodStart" - ) - years: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("years") - id: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("id") - config: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("config") - description: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("description") - updated_at: "HcWorkPackageGraphQLField" = HcWorkPackageGraphQLField("updatedAt") - - def fields( - self, - *subfields: Union[ - HcWorkPackageGraphQLField, - "GqlUserFields", - "WorkPackageProgressDetailsFields", - ], - ) -> "HcWorkPackageFields": - """Subfields should come from the HcWorkPackageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "HcWorkPackageFields": - self._alias = alias - return self - - -class HcWorkPackagePageFields(GraphQLField): - all_users: "HcWorkPackagePageGraphQLField" = HcWorkPackagePageGraphQLField( - "allUsers" - ) - offset: "HcWorkPackagePageGraphQLField" = HcWorkPackagePageGraphQLField("offset") - total_count: "HcWorkPackagePageGraphQLField" = HcWorkPackagePageGraphQLField( - "totalCount" - ) - - @classmethod - def work_packages(cls) -> "HcWorkPackageFields": - return HcWorkPackageFields("workPackages") - - def fields( - self, *subfields: Union[HcWorkPackagePageGraphQLField, "HcWorkPackageFields"] - ) -> "HcWorkPackagePageFields": - """Subfields should come from the HcWorkPackagePageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "HcWorkPackagePageFields": - self._alias = alias - return self - - -class IngestionJobFields(GraphQLField): - application: "IngestionJobGraphQLField" = IngestionJobGraphQLField("application") - application_version: "IngestionJobGraphQLField" = IngestionJobGraphQLField( - "applicationVersion" - ) - id: "IngestionJobGraphQLField" = IngestionJobGraphQLField("id") - source: "IngestionJobGraphQLField" = IngestionJobGraphQLField("source") - start_time: "IngestionJobGraphQLField" = IngestionJobGraphQLField("startTime") - - def fields(self, *subfields: IngestionJobGraphQLField) -> "IngestionJobFields": - """Subfields should come from the IngestionJobFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "IngestionJobFields": - self._alias = alias - return self - - -class IngestionRunFields(GraphQLField): - completed_at: "IngestionRunGraphQLField" = IngestionRunGraphQLField("completedAt") - container_runtime_type: "IngestionRunGraphQLField" = IngestionRunGraphQLField( - "containerRuntimeType" - ) - payload: "IngestionRunGraphQLField" = IngestionRunGraphQLField("payload") - started_at: "IngestionRunGraphQLField" = IngestionRunGraphQLField("startedAt") - status: "IngestionRunGraphQLField" = IngestionRunGraphQLField("status") - status_last_updated_at: "IngestionRunGraphQLField" = IngestionRunGraphQLField( - "statusLastUpdatedAt" - ) - token: "IngestionRunGraphQLField" = IngestionRunGraphQLField("token") - id: "IngestionRunGraphQLField" = IngestionRunGraphQLField("id") - - def fields(self, *subfields: IngestionRunGraphQLField) -> "IngestionRunFields": - """Subfields should come from the IngestionRunFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "IngestionRunFields": - self._alias = alias - return self - - -class IngestorRunPageFields(GraphQLField): - @classmethod - def ingestor_runs(cls) -> "IngestionRunFields": - return IngestionRunFields("ingestorRuns") - - offset: "IngestorRunPageGraphQLField" = IngestorRunPageGraphQLField("offset") - total_count: "IngestorRunPageGraphQLField" = IngestorRunPageGraphQLField( - "totalCount" - ) - - def fields( - self, *subfields: Union[IngestorRunPageGraphQLField, "IngestionRunFields"] - ) -> "IngestorRunPageFields": - """Subfields should come from the IngestorRunPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "IngestorRunPageFields": - self._alias = alias - return self - - -class JobSourceFields(GraphQLField): - file_hash: "JobSourceGraphQLField" = JobSourceGraphQLField("fileHash") - name: "JobSourceGraphQLField" = JobSourceGraphQLField("name") - timestamp: "JobSourceGraphQLField" = JobSourceGraphQLField("timestamp") - - def fields(self, *subfields: JobSourceGraphQLField) -> "JobSourceFields": - """Subfields should come from the JobSourceFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "JobSourceFields": - self._alias = alias - return self - - -class MachineUserFields(GraphQLField): - display_name: "MachineUserGraphQLField" = MachineUserGraphQLField("displayName") - username: "MachineUserGraphQLField" = MachineUserGraphQLField("username") - - def fields(self, *subfields: MachineUserGraphQLField) -> "MachineUserFields": - """Subfields should come from the MachineUserFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "MachineUserFields": - self._alias = alias - return self - - -class MetricFields(GraphQLField): - name: "MetricGraphQLField" = MetricGraphQLField("name") - value: "MetricGraphQLField" = MetricGraphQLField("value") - - def fields(self, *subfields: MetricGraphQLField) -> "MetricFields": - """Subfields should come from the MetricFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "MetricFields": - self._alias = alias - return self - - -class NetworkModelFields(GraphQLField): - database_name: "NetworkModelGraphQLField" = NetworkModelGraphQLField("databaseName") - source_data_date: "NetworkModelGraphQLField" = NetworkModelGraphQLField( - "sourceDataDate" - ) - - def fields(self, *subfields: NetworkModelGraphQLField) -> "NetworkModelFields": - """Subfields should come from the NetworkModelFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "NetworkModelFields": - self._alias = alias - return self - - -class NetworkModelsFields(GraphQLField): - @classmethod - def available_network_models(cls) -> "NetworkModelFields": - return NetworkModelFields("availableNetworkModels") - - currently_loaded_network_model: "NetworkModelsGraphQLField" = ( - NetworkModelsGraphQLField("currentlyLoadedNetworkModel") - ) - network_date_locked: "NetworkModelsGraphQLField" = NetworkModelsGraphQLField( - "networkDateLocked" - ) - - def fields( - self, *subfields: Union[NetworkModelsGraphQLField, "NetworkModelFields"] - ) -> "NetworkModelsFields": - """Subfields should come from the NetworkModelsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "NetworkModelsFields": - self._alias = alias - return self - - -class OpenDssModelFields(GraphQLField): - created_at: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("createdAt") - created_by: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("createdBy") - download_url: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("downloadUrl") - errors: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("errors") - generation_spec: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField( - "generationSpec" - ) - id: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("id") - is_public: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("isPublic") - name: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("name") - state: "OpenDssModelGraphQLField" = OpenDssModelGraphQLField("state") - - def fields(self, *subfields: OpenDssModelGraphQLField) -> "OpenDssModelFields": - """Subfields should come from the OpenDssModelFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "OpenDssModelFields": - self._alias = alias - return self - - -class OpenDssModelPageFields(GraphQLField): - @classmethod - def models(cls) -> "OpenDssModelFields": - return OpenDssModelFields("models") - - offset: "OpenDssModelPageGraphQLField" = OpenDssModelPageGraphQLField("offset") - total_count: "OpenDssModelPageGraphQLField" = OpenDssModelPageGraphQLField( - "totalCount" - ) - - def fields( - self, *subfields: Union[OpenDssModelPageGraphQLField, "OpenDssModelFields"] - ) -> "OpenDssModelPageFields": - """Subfields should come from the OpenDssModelPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "OpenDssModelPageFields": - self._alias = alias - return self - - -class OpportunitiesByYearFields(GraphQLField): - """Opportunities available for a specific year.""" - - @classmethod - def available_opportunities(cls) -> "OpportunityFields": - return OpportunityFields("availableOpportunities") - - year: "OpportunitiesByYearGraphQLField" = OpportunitiesByYearGraphQLField("year") - - def fields( - self, *subfields: Union[OpportunitiesByYearGraphQLField, "OpportunityFields"] - ) -> "OpportunitiesByYearFields": - """Subfields should come from the OpportunitiesByYearFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "OpportunitiesByYearFields": - self._alias = alias - return self - - -class OpportunityFields(GraphQLField): - annual_deferral_value: "OpportunityGraphQLField" = OpportunityGraphQLField( - "annualDeferralValue" - ) - - @classmethod - def conducting_equipment(cls) -> "EquipmentFields": - return EquipmentFields("conductingEquipment") - - connection_voltage_level: "OpportunityGraphQLField" = OpportunityGraphQLField( - "connectionVoltageLevel" - ) - constraint_primary_driver: "OpportunityGraphQLField" = OpportunityGraphQLField( - "constraintPrimaryDriver" - ) - days_required: "OpportunityGraphQLField" = OpportunityGraphQLField("daysRequired") - downstream_customers: "OpportunityGraphQLField" = OpportunityGraphQLField( - "downstreamCustomers" - ) - est_annual_hours: "OpportunityGraphQLField" = OpportunityGraphQLField( - "estAnnualHours" - ) - est_duration_per_event: "OpportunityGraphQLField" = OpportunityGraphQLField( - "estDurationPerEvent" - ) - est_number_of_events: "OpportunityGraphQLField" = OpportunityGraphQLField( - "estNumberOfEvents" - ) - id: "OpportunityGraphQLField" = OpportunityGraphQLField("id") - min_capacity: "OpportunityGraphQLField" = OpportunityGraphQLField("minCapacity") - need_direction: "OpportunityGraphQLField" = OpportunityGraphQLField("needDirection") - peak_demand: "OpportunityGraphQLField" = OpportunityGraphQLField("peakDemand") - time_required: "OpportunityGraphQLField" = OpportunityGraphQLField("timeRequired") - title: "OpportunityGraphQLField" = OpportunityGraphQLField("title") - year: "OpportunityGraphQLField" = OpportunityGraphQLField("year") - - @classmethod - def polygon(cls) -> "GeoJsonFeatureFields": - return GeoJsonFeatureFields("polygon") - - def fields( - self, - *subfields: Union[ - OpportunityGraphQLField, "EquipmentFields", "GeoJsonFeatureFields" - ], - ) -> "OpportunityFields": - """Subfields should come from the OpportunityFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "OpportunityFields": - self._alias = alias - return self - - -class OpportunityLocationFields(GraphQLField): - @classmethod - def coordinates(cls) -> "CoordinateFields": - return CoordinateFields("coordinates") - - m_rid: "OpportunityLocationGraphQLField" = OpportunityLocationGraphQLField("mRID") - - def fields( - self, *subfields: Union[OpportunityLocationGraphQLField, "CoordinateFields"] - ) -> "OpportunityLocationFields": - """Subfields should come from the OpportunityLocationFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "OpportunityLocationFields": - self._alias = alias - return self - - -class PowerFactoryModelFields(GraphQLField): - created_at: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField( - "createdAt" - ) - errors: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField("errors") - - @classmethod - def generation_spec(cls) -> "PowerFactoryModelGenerationSpecFields": - return PowerFactoryModelGenerationSpecFields("generationSpec") - - id: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField("id") - is_public: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField( - "isPublic" - ) - name: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField("name") - state: "PowerFactoryModelGraphQLField" = PowerFactoryModelGraphQLField("state") - - def fields( - self, - *subfields: Union[ - PowerFactoryModelGraphQLField, "PowerFactoryModelGenerationSpecFields" - ], - ) -> "PowerFactoryModelFields": - """Subfields should come from the PowerFactoryModelFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "PowerFactoryModelFields": - self._alias = alias - return self - - -class PowerFactoryModelGenerationSpecFields(GraphQLField): - @classmethod - def distribution_transformer_config( - cls, - ) -> "GqlDistributionTransformerConfigFields": - return GqlDistributionTransformerConfigFields("distributionTransformerConfig") - - equipment_container_mrids: "PowerFactoryModelGenerationSpecGraphQLField" = ( - PowerFactoryModelGenerationSpecGraphQLField("equipmentContainerMrids") - ) - - @classmethod - def load_config(cls) -> "GqlLoadConfigFields": - return GqlLoadConfigFields("loadConfig") - - @classmethod - def scenario_config(cls) -> "GqlScenarioConfigFields": - return GqlScenarioConfigFields("scenarioConfig") - - def fields( - self, - *subfields: Union[ - PowerFactoryModelGenerationSpecGraphQLField, - "GqlDistributionTransformerConfigFields", - "GqlLoadConfigFields", - "GqlScenarioConfigFields", - ], - ) -> "PowerFactoryModelGenerationSpecFields": - """Subfields should come from the PowerFactoryModelGenerationSpecFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "PowerFactoryModelGenerationSpecFields": - self._alias = alias - return self - - -class PowerFactoryModelPageFields(GraphQLField): - offset: "PowerFactoryModelPageGraphQLField" = PowerFactoryModelPageGraphQLField( - "offset" - ) - - @classmethod - def power_factory_models(cls) -> "PowerFactoryModelFields": - return PowerFactoryModelFields("powerFactoryModels") - - total_count: "PowerFactoryModelPageGraphQLField" = ( - PowerFactoryModelPageGraphQLField("totalCount") - ) - - def fields( - self, - *subfields: Union[PowerFactoryModelPageGraphQLField, "PowerFactoryModelFields"], - ) -> "PowerFactoryModelPageFields": - """Subfields should come from the PowerFactoryModelPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "PowerFactoryModelPageFields": - self._alias = alias - return self - - -class PowerFactoryModelTemplateFields(GraphQLField): - created_at: "PowerFactoryModelTemplateGraphQLField" = ( - PowerFactoryModelTemplateGraphQLField("createdAt") - ) - - @classmethod - def generation_spec(cls) -> "PowerFactoryModelGenerationSpecFields": - return PowerFactoryModelGenerationSpecFields("generationSpec") - - id: "PowerFactoryModelTemplateGraphQLField" = PowerFactoryModelTemplateGraphQLField( - "id" - ) - is_public: "PowerFactoryModelTemplateGraphQLField" = ( - PowerFactoryModelTemplateGraphQLField("isPublic") - ) - name: "PowerFactoryModelTemplateGraphQLField" = ( - PowerFactoryModelTemplateGraphQLField("name") - ) - - def fields( - self, - *subfields: Union[ - PowerFactoryModelTemplateGraphQLField, - "PowerFactoryModelGenerationSpecFields", - ], - ) -> "PowerFactoryModelTemplateFields": - """Subfields should come from the PowerFactoryModelTemplateFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "PowerFactoryModelTemplateFields": - self._alias = alias - return self - - -class PowerFactoryModelTemplatePageFields(GraphQLField): - offset: "PowerFactoryModelTemplatePageGraphQLField" = ( - PowerFactoryModelTemplatePageGraphQLField("offset") - ) - - @classmethod - def templates(cls) -> "PowerFactoryModelTemplateFields": - return PowerFactoryModelTemplateFields("templates") - - total_count: "PowerFactoryModelTemplatePageGraphQLField" = ( - PowerFactoryModelTemplatePageGraphQLField("totalCount") - ) - - def fields( - self, - *subfields: Union[ - PowerFactoryModelTemplatePageGraphQLField, "PowerFactoryModelTemplateFields" - ], - ) -> "PowerFactoryModelTemplatePageFields": - """Subfields should come from the PowerFactoryModelTemplatePageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "PowerFactoryModelTemplatePageFields": - self._alias = alias - return self - - -class ProcessedDiffFields(GraphQLField): - description: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("description") - diff_id: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("diffId") - feeder: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("feeder") - name: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("name") - scenario: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("scenario") - type_: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("type") - - @classmethod - def w_p_id_1(cls) -> "HcWorkPackageFields": - return HcWorkPackageFields("wPId1") - - @classmethod - def w_p_id_2(cls) -> "HcWorkPackageFields": - return HcWorkPackageFields("wPId2") - - year: "ProcessedDiffGraphQLField" = ProcessedDiffGraphQLField("year") - - def fields( - self, *subfields: Union[ProcessedDiffGraphQLField, "HcWorkPackageFields"] - ) -> "ProcessedDiffFields": - """Subfields should come from the ProcessedDiffFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "ProcessedDiffFields": - self._alias = alias - return self - - -class ProcessedDiffPageFields(GraphQLField): - offset: "ProcessedDiffPageGraphQLField" = ProcessedDiffPageGraphQLField("offset") - - @classmethod - def processed_diff(cls) -> "ProcessedDiffFields": - return ProcessedDiffFields("processedDiff") - - total_count: "ProcessedDiffPageGraphQLField" = ProcessedDiffPageGraphQLField( - "totalCount" - ) - - def fields( - self, *subfields: Union[ProcessedDiffPageGraphQLField, "ProcessedDiffFields"] - ) -> "ProcessedDiffPageFields": - """Subfields should come from the ProcessedDiffPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "ProcessedDiffPageFields": - self._alias = alias - return self - - -class RemoveAppOptionResultFields(GraphQLField): - """Result of removing an application option""" - - name: "RemoveAppOptionResultGraphQLField" = RemoveAppOptionResultGraphQLField( - "name" - ) - removed: "RemoveAppOptionResultGraphQLField" = RemoveAppOptionResultGraphQLField( - "removed" - ) - - def fields( - self, *subfields: RemoveAppOptionResultGraphQLField - ) -> "RemoveAppOptionResultFields": - """Subfields should come from the RemoveAppOptionResultFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "RemoveAppOptionResultFields": - self._alias = alias - return self - - -class ResultSectionInterface(GraphQLField): - name: "ResultSectionGraphQLField" = ResultSectionGraphQLField("name") - type_: "ResultSectionGraphQLField" = ResultSectionGraphQLField("type") - id: "ResultSectionGraphQLField" = ResultSectionGraphQLField("id") - description: "ResultSectionGraphQLField" = ResultSectionGraphQLField("description") - - def fields(self, *subfields: ResultSectionGraphQLField) -> "ResultSectionInterface": - """Subfields should come from the ResultSectionInterface class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "ResultSectionInterface": - self._alias = alias - return self - - def on(self, type_name: str, *subfields: GraphQLField) -> "ResultSectionInterface": - self._inline_fragments[type_name] = subfields - return self - - -class ScenarioConfigurationFields(GraphQLField): - bess_allocation_id: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("bessAllocationId") - ) - bess_forecast_level: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("bessForecastLevel") - ) - bess_forecasts_scenario: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("bessForecastsScenario") - ) - demand_forecast_level: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("demandForecastLevel") - ) - demand_forecast_poe: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("demandForecastPoe") - ) - demand_forecasts_scenario: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("demandForecastsScenario") - ) - ev_allocation_id: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("evAllocationId") - ) - ev_forecast_level: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("evForecastLevel") - ) - ev_forecasts_scenario: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("evForecastsScenario") - ) - pv_allocation_id: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("pvAllocationId") - ) - pv_forecast_level: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("pvForecastLevel") - ) - pv_forecasts_scenario: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("pvForecastsScenario") - ) - scenario_name: "ScenarioConfigurationGraphQLField" = ( - ScenarioConfigurationGraphQLField("scenarioName") - ) - id: "ScenarioConfigurationGraphQLField" = ScenarioConfigurationGraphQLField("id") - - def fields( - self, *subfields: ScenarioConfigurationGraphQLField - ) -> "ScenarioConfigurationFields": - """Subfields should come from the ScenarioConfigurationFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "ScenarioConfigurationFields": - self._alias = alias - return self - - -class SincalConfigFileFields(GraphQLField): - file_type: "SincalConfigFileGraphQLField" = SincalConfigFileGraphQLField("fileType") - original_filename: "SincalConfigFileGraphQLField" = SincalConfigFileGraphQLField( - "originalFilename" - ) - raw_filename: "SincalConfigFileGraphQLField" = SincalConfigFileGraphQLField( - "rawFilename" - ) - standard_name: "SincalConfigFileGraphQLField" = SincalConfigFileGraphQLField( - "standardName" - ) - - def fields( - self, *subfields: SincalConfigFileGraphQLField - ) -> "SincalConfigFileFields": - """Subfields should come from the SincalConfigFileFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalConfigFileFields": - self._alias = alias - return self - - -class SincalGlobalInputsConfigFields(GraphQLField): - @classmethod - def backend_config(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("backendConfig") - - @classmethod - def frontend_config(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("frontendConfig") - - @classmethod - def in_feeder_mapping_database(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("inFeederMappingDatabase") - - @classmethod - def local_standard_database(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("localStandardDatabase") - - @classmethod - def protection_standard_database(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("protectionStandardDatabase") - - @classmethod - def template(cls) -> "SincalConfigFileFields": - return SincalConfigFileFields("template") - - def fields( - self, - *subfields: Union[ - SincalGlobalInputsConfigGraphQLField, "SincalConfigFileFields" - ], - ) -> "SincalGlobalInputsConfigFields": - """Subfields should come from the SincalGlobalInputsConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalGlobalInputsConfigFields": - self._alias = alias - return self - - -class SincalModelFields(GraphQLField): - created_at: "SincalModelGraphQLField" = SincalModelGraphQLField("createdAt") - created_by: "SincalModelGraphQLField" = SincalModelGraphQLField("createdBy") - errors: "SincalModelGraphQLField" = SincalModelGraphQLField("errors") - - @classmethod - def generation_spec(cls) -> "SincalModelGenerationSpecFields": - """JSON exporter generation spec (auth tokens withheld)""" - return SincalModelGenerationSpecFields("generationSpec") - - id: "SincalModelGraphQLField" = SincalModelGraphQLField("id") - is_public: "SincalModelGraphQLField" = SincalModelGraphQLField("isPublic") - name: "SincalModelGraphQLField" = SincalModelGraphQLField("name") - state: "SincalModelGraphQLField" = SincalModelGraphQLField("state") - - def fields( - self, - *subfields: Union[SincalModelGraphQLField, "SincalModelGenerationSpecFields"], - ) -> "SincalModelFields": - """Subfields should come from the SincalModelFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalModelFields": - self._alias = alias - return self - - -class SincalModelGenerationSpecFields(GraphQLField): - config: "SincalModelGenerationSpecGraphQLField" = ( - SincalModelGenerationSpecGraphQLField("config") - ) - "JSON export config." - equipment_container_mrids: "SincalModelGenerationSpecGraphQLField" = ( - SincalModelGenerationSpecGraphQLField("equipmentContainerMrids") - ) - - def fields( - self, *subfields: SincalModelGenerationSpecGraphQLField - ) -> "SincalModelGenerationSpecFields": - """Subfields should come from the SincalModelGenerationSpecFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalModelGenerationSpecFields": - self._alias = alias - return self - - -class SincalModelPageFields(GraphQLField): - offset: "SincalModelPageGraphQLField" = SincalModelPageGraphQLField("offset") - - @classmethod - def sincal_models(cls) -> "SincalModelFields": - return SincalModelFields("sincalModels") - - total_count: "SincalModelPageGraphQLField" = SincalModelPageGraphQLField( - "totalCount" - ) - - def fields( - self, *subfields: Union[SincalModelPageGraphQLField, "SincalModelFields"] - ) -> "SincalModelPageFields": - """Subfields should come from the SincalModelPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalModelPageFields": - self._alias = alias - return self - - -class SincalModelPresetFields(GraphQLField): - created_at: "SincalModelPresetGraphQLField" = SincalModelPresetGraphQLField( - "createdAt" - ) - created_by: "SincalModelPresetGraphQLField" = SincalModelPresetGraphQLField( - "createdBy" - ) - - @classmethod - def generation_spec(cls) -> "SincalModelGenerationSpecFields": - return SincalModelGenerationSpecFields("generationSpec") - - id: "SincalModelPresetGraphQLField" = SincalModelPresetGraphQLField("id") - is_public: "SincalModelPresetGraphQLField" = SincalModelPresetGraphQLField( - "isPublic" - ) - name: "SincalModelPresetGraphQLField" = SincalModelPresetGraphQLField("name") - - def fields( - self, - *subfields: Union[ - SincalModelPresetGraphQLField, "SincalModelGenerationSpecFields" - ], - ) -> "SincalModelPresetFields": - """Subfields should come from the SincalModelPresetFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalModelPresetFields": - self._alias = alias - return self - - -class SincalModelPresetPageFields(GraphQLField): - offset: "SincalModelPresetPageGraphQLField" = SincalModelPresetPageGraphQLField( - "offset" - ) - - @classmethod - def presets(cls) -> "SincalModelPresetFields": - return SincalModelPresetFields("presets") - - total_count: "SincalModelPresetPageGraphQLField" = ( - SincalModelPresetPageGraphQLField("totalCount") - ) - - def fields( - self, - *subfields: Union[SincalModelPresetPageGraphQLField, "SincalModelPresetFields"], - ) -> "SincalModelPresetPageFields": - """Subfields should come from the SincalModelPresetPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "SincalModelPresetPageFields": - self._alias = alias - return self - - -class StateOverlayFields(GraphQLField): - styles: "StateOverlayGraphQLField" = StateOverlayGraphQLField("styles") - id: "StateOverlayGraphQLField" = StateOverlayGraphQLField("id") - data: "StateOverlayGraphQLField" = StateOverlayGraphQLField("data") - - def fields(self, *subfields: StateOverlayGraphQLField) -> "StateOverlayFields": - """Subfields should come from the StateOverlayFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "StateOverlayFields": - self._alias = alias - return self - - -class StudyFields(GraphQLField): - created_at: "StudyGraphQLField" = StudyGraphQLField("createdAt") - name: "StudyGraphQLField" = StudyGraphQLField("name") - tags: "StudyGraphQLField" = StudyGraphQLField("tags") - id: "StudyGraphQLField" = StudyGraphQLField("id") - - @classmethod - def created_by(cls) -> "GqlUserFields": - return GqlUserFields("createdBy") - - description: "StudyGraphQLField" = StudyGraphQLField("description") - - @classmethod - def results(cls) -> "StudyResultFields": - return StudyResultFields("results") - - styles: "StudyGraphQLField" = StudyGraphQLField("styles") - - def fields( - self, *subfields: Union[StudyGraphQLField, "GqlUserFields", "StudyResultFields"] - ) -> "StudyFields": - """Subfields should come from the StudyFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "StudyFields": - self._alias = alias - return self - - -class StudyPageFields(GraphQLField): - all_tags: "StudyPageGraphQLField" = StudyPageGraphQLField("allTags") - all_users: "StudyPageGraphQLField" = StudyPageGraphQLField("allUsers") - offset: "StudyPageGraphQLField" = StudyPageGraphQLField("offset") - - @classmethod - def studies(cls) -> "StudyFields": - return StudyFields("studies") - - total_count: "StudyPageGraphQLField" = StudyPageGraphQLField("totalCount") - - def fields( - self, *subfields: Union[StudyPageGraphQLField, "StudyFields"] - ) -> "StudyPageFields": - """Subfields should come from the StudyPageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "StudyPageFields": - self._alias = alias - return self - - -class StudyResultFields(GraphQLField): - name: "StudyResultGraphQLField" = StudyResultGraphQLField("name") - id: "StudyResultGraphQLField" = StudyResultGraphQLField("id") - - @classmethod - def geo_json_overlay(cls) -> "GeoJsonOverlayFields": - return GeoJsonOverlayFields("geoJsonOverlay") - - @classmethod - def sections(cls) -> "ResultSectionInterface": - return ResultSectionInterface("sections") - - @classmethod - def state_overlay(cls) -> "StateOverlayFields": - return StateOverlayFields("stateOverlay") - - def fields( - self, - *subfields: Union[ - StudyResultGraphQLField, - "GeoJsonOverlayFields", - "ResultSectionInterface", - "StateOverlayFields", - ], - ) -> "StudyResultFields": - """Subfields should come from the StudyResultFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "StudyResultFields": - self._alias = alias - return self - - -class TableSectionFields(GraphQLField): - id: "TableSectionGraphQLField" = TableSectionGraphQLField("id") - name: "TableSectionGraphQLField" = TableSectionGraphQLField("name") - type_: "TableSectionGraphQLField" = TableSectionGraphQLField("type") - - @classmethod - def columns(cls) -> "ColumnFields": - return ColumnFields("columns") - - @classmethod - def data( - cls, *, serialization: Optional[SerializationType] = None - ) -> "TableSectionGraphQLField": - arguments: dict[str, dict[str, Any]] = { - "serialization": {"type": "SerializationType", "value": serialization} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return TableSectionGraphQLField("data", arguments=cleared_arguments) - - description: "TableSectionGraphQLField" = TableSectionGraphQLField("description") - - def fields( - self, *subfields: Union[TableSectionGraphQLField, "ColumnFields"] - ) -> "TableSectionFields": - """Subfields should come from the TableSectionFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "TableSectionFields": - self._alias = alias - return self - - -class UploadUrlResponseFields(GraphQLField): - file_path: "UploadUrlResponseGraphQLField" = UploadUrlResponseGraphQLField( - "filePath" - ) - upload_url: "UploadUrlResponseGraphQLField" = UploadUrlResponseGraphQLField( - "uploadUrl" - ) - - def fields( - self, *subfields: UploadUrlResponseGraphQLField - ) -> "UploadUrlResponseFields": - """Subfields should come from the UploadUrlResponseFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "UploadUrlResponseFields": - self._alias = alias - return self - - -class UserCustomerListColumnConfigFields(GraphQLField): - """User-specific column configuration for the customer list table.""" - - @classmethod - def columns(cls) -> "CustomerListColumnConfigFields": - """List of columns configured by the user to display in the customer list table.""" - return CustomerListColumnConfigFields("columns") - - def fields( - self, - *subfields: Union[ - UserCustomerListColumnConfigGraphQLField, "CustomerListColumnConfigFields" - ], - ) -> "UserCustomerListColumnConfigFields": - """Subfields should come from the UserCustomerListColumnConfigFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "UserCustomerListColumnConfigFields": - self._alias = alias - return self - - -class VariantFields(GraphQLField): - conducting_equipment_count: "VariantGraphQLField" = VariantGraphQLField( - "conductingEquipmentCount" - ) - m_rid: "VariantGraphQLField" = VariantGraphQLField("mRID") - name: "VariantGraphQLField" = VariantGraphQLField("name") - network_database_location: "VariantGraphQLField" = VariantGraphQLField( - "networkDatabaseLocation" - ) - new_parent: "VariantGraphQLField" = VariantGraphQLField("newParent") - new_variant: "VariantGraphQLField" = VariantGraphQLField("newVariant") - parent: "VariantGraphQLField" = VariantGraphQLField("parent") - parent_mrid: "VariantGraphQLField" = VariantGraphQLField("parentMRID") - status: "VariantGraphQLField" = VariantGraphQLField("status") - - def fields(self, *subfields: VariantGraphQLField) -> "VariantFields": - """Subfields should come from the VariantFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "VariantFields": - self._alias = alias - return self - - -class VariantWorkPackageFields(GraphQLField): - status: "VariantWorkPackageGraphQLField" = VariantWorkPackageGraphQLField("status") - - @classmethod - def variants(cls) -> "VariantFields": - return VariantFields("variants") - - def fields( - self, *subfields: Union[VariantWorkPackageGraphQLField, "VariantFields"] - ) -> "VariantWorkPackageFields": - """Subfields should come from the VariantWorkPackageFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "VariantWorkPackageFields": - self._alias = alias - return self - - -class WorkPackageModelGroupingsFields(GraphQLField): - @classmethod - def cancelled(cls) -> "HcModelFields": - return HcModelFields("cancelled") - - @classmethod - def execution(cls) -> "HcModelFields": - return HcModelFields("execution") - - @classmethod - def failed(cls) -> "HcModelFields": - return HcModelFields("failed") - - @classmethod - def generation(cls) -> "HcModelFields": - return HcModelFields("generation") - - @classmethod - def pending(cls) -> "HcModelFields": - return HcModelFields("pending") - - @classmethod - def result_processing(cls) -> "HcModelFields": - return HcModelFields("resultProcessing") - - @classmethod - def succeeded(cls) -> "HcModelFields": - return HcModelFields("succeeded") - - @classmethod - def timed_out(cls) -> "HcModelFields": - return HcModelFields("timedOut") - - def fields( - self, *subfields: Union[WorkPackageModelGroupingsGraphQLField, "HcModelFields"] - ) -> "WorkPackageModelGroupingsFields": - """Subfields should come from the WorkPackageModelGroupingsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "WorkPackageModelGroupingsFields": - self._alias = alias - return self - - -class WorkPackageModelTotalsFields(GraphQLField): - total_cancelled: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalCancelled") - ) - total_failed: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalFailed") - ) - total_models: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalModels") - ) - total_pending: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalPending") - ) - total_running: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalRunning") - ) - total_succeeded: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalSucceeded") - ) - total_timed_out: "WorkPackageModelTotalsGraphQLField" = ( - WorkPackageModelTotalsGraphQLField("totalTimedOut") - ) - - def fields( - self, *subfields: WorkPackageModelTotalsGraphQLField - ) -> "WorkPackageModelTotalsFields": - """Subfields should come from the WorkPackageModelTotalsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "WorkPackageModelTotalsFields": - self._alias = alias - return self - - -class WorkPackageProgressDetailsFields(GraphQLField): - @classmethod - def model_groupings(cls) -> "WorkPackageModelGroupingsFields": - return WorkPackageModelGroupingsFields("modelGroupings") - - @classmethod - def model_totals(cls) -> "WorkPackageModelTotalsFields": - return WorkPackageModelTotalsFields("modelTotals") - - def fields( - self, - *subfields: Union[ - WorkPackageProgressDetailsGraphQLField, - "WorkPackageModelGroupingsFields", - "WorkPackageModelTotalsFields", - ], - ) -> "WorkPackageProgressDetailsFields": - """Subfields should come from the WorkPackageProgressDetailsFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "WorkPackageProgressDetailsFields": - self._alias = alias - return self - - -class WorkPackageTreeFields(GraphQLField): - @classmethod - def ancestors(cls) -> "HcWorkPackageFields": - return HcWorkPackageFields("ancestors") - - @classmethod - def children(cls) -> "HcWorkPackageFields": - return HcWorkPackageFields("children") - - def fields( - self, *subfields: Union[WorkPackageTreeGraphQLField, "HcWorkPackageFields"] - ) -> "WorkPackageTreeFields": - """Subfields should come from the WorkPackageTreeFields class""" - self._subfields.extend(subfields) - return self - - def alias(self, alias: str) -> "WorkPackageTreeFields": - self._alias = alias - return self diff --git a/src/zepben/eas/lib/generated_graphql_client/custom_mutations.py b/src/zepben/eas/lib/generated_graphql_client/custom_mutations.py deleted file mode 100644 index 9bf4a5c..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/custom_mutations.py +++ /dev/null @@ -1,530 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional - -from .custom_fields import ( - DiffResultFields, - RemoveAppOptionResultFields, - UserCustomerListColumnConfigFields, -) -from .custom_typing_fields import GraphQLField -from .enums import SincalFileType, VariantFileType -from .input_types import ( - AppOptionsInput, - FeederLoadAnalysisInput, - HcGeneratorConfigInput, - IngestorConfigInput, - OpenDssModelInput, - PowerFactoryModelGenerationSpecInput, - PowerFactoryModelInput, - SincalModelGenerationSpecInput, - SincalModelInput, - StudyInput, - WorkPackageInput, -) - - -class Mutation: - @classmethod - def add_studies(cls, studies: list[StudyInput]) -> GraphQLField: - """Add new studies to the database and return their IDs""" - arguments: dict[str, dict[str, Any]] = { - "studies": {"type": "[StudyInput!]!", "value": studies} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="addStudies", arguments=cleared_arguments) - - @classmethod - def delete_studies(cls, ids: list[str]) -> GraphQLField: - """Delete studies by their IDs and return the IDs of deleted studies""" - arguments: dict[str, dict[str, Any]] = {"ids": {"type": "[ID!]!", "value": ids}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="deleteStudies", arguments=cleared_arguments) - - @classmethod - def create_power_factory_model(cls, input: PowerFactoryModelInput) -> GraphQLField: - """Creates a new powerFactoryModel and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "PowerFactoryModelInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="createPowerFactoryModel", arguments=cleared_arguments - ) - - @classmethod - def create_power_factory_model_template( - cls, input: PowerFactoryModelInput - ) -> GraphQLField: - """Creates a new powerFactoryModel template and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "PowerFactoryModelInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="createPowerFactoryModelTemplate", arguments=cleared_arguments - ) - - @classmethod - def delete_power_factory_model(cls, model_id: str) -> GraphQLField: - """Deletes powerFactoryModel with ID and returns said ID""" - arguments: dict[str, dict[str, Any]] = { - "modelId": {"type": "ID!", "value": model_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="deletePowerFactoryModel", arguments=cleared_arguments - ) - - @classmethod - def delete_power_factory_model_template(cls, template_id: str) -> GraphQLField: - """Deletes powerFactoryModel template with ID and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "templateId": {"type": "ID!", "value": template_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="deletePowerFactoryModelTemplate", arguments=cleared_arguments - ) - - @classmethod - def update_power_factory_model_template( - cls, template_id: str, generation_spec: PowerFactoryModelGenerationSpecInput - ) -> GraphQLField: - """Updates powerFactoryModel template with ID and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "templateId": {"type": "ID!", "value": template_id}, - "generationSpec": { - "type": "PowerFactoryModelGenerationSpecInput!", - "value": generation_spec, - }, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="updatePowerFactoryModelTemplate", arguments=cleared_arguments - ) - - @classmethod - def cancel_work_package(cls, work_package_id: str) -> GraphQLField: - """Cancels a hosting capacity work package and returns its ID.""" - arguments: dict[str, dict[str, Any]] = { - "workPackageId": {"type": "ID!", "value": work_package_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="cancelWorkPackage", arguments=cleared_arguments) - - @classmethod - def delete_work_package(cls, work_package_ids: list[str]) -> GraphQLField: - """Delete one or more hosting capacity work package(s). Returns the list of successfully deleted work package IDs, throws if none can be deleted.""" - arguments: dict[str, dict[str, Any]] = { - "workPackageIds": {"type": "[String!]!", "value": work_package_ids} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="deleteWorkPackage", arguments=cleared_arguments) - - @classmethod - def edit_diff_package( - cls, - diff_id: str, - *, - name: Optional[str] = None, - description: Optional[str] = None, - ) -> GraphQLField: - """Edits a hosting capacity diff package and return boolean. Returns "true" on successful update""" - arguments: dict[str, dict[str, Any]] = { - "diffId": {"type": "ID!", "value": diff_id}, - "name": {"type": "String", "value": name}, - "description": {"type": "String", "value": description}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="editDiffPackage", arguments=cleared_arguments) - - @classmethod - def edit_work_package( - cls, - work_package_id: str, - *, - name: Optional[str] = None, - description: Optional[str] = None, - ) -> GraphQLField: - """Edits a hosting capacity work package and return boolean. Returns "true" on successful update""" - arguments: dict[str, dict[str, Any]] = { - "workPackageId": {"type": "ID!", "value": work_package_id}, - "name": {"type": "String", "value": name}, - "description": {"type": "String", "value": description}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="editWorkPackage", arguments=cleared_arguments) - - @classmethod - def generate_enhanced_network_performance_diff( - cls, - diff_id: str, - work_package_id_1: str, - work_package_id_2: str, - *, - diff_name: Optional[str] = None, - scenario: Optional[str] = None, - feeder: Optional[str] = None, - year: Optional[int] = None, - season: Optional[str] = None, - time_of_day: Optional[str] = None, - ) -> DiffResultFields: - """Generate and store the differences of enhanced network performance metrics between two work packages and returns the number of entries generated with the ID of this diff package.""" - arguments: dict[str, dict[str, Any]] = { - "diffId": {"type": "ID!", "value": diff_id}, - "diffName": {"type": "String", "value": diff_name}, - "workPackageId1": {"type": "ID!", "value": work_package_id_1}, - "workPackageId2": {"type": "ID!", "value": work_package_id_2}, - "scenario": {"type": "String", "value": scenario}, - "feeder": {"type": "String", "value": feeder}, - "year": {"type": "Int", "value": year}, - "season": {"type": "String", "value": season}, - "timeOfDay": {"type": "String", "value": time_of_day}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return DiffResultFields( - field_name="generateEnhancedNetworkPerformanceDiff", - arguments=cleared_arguments, - ) - - @classmethod - def generate_network_performance_diff( - cls, - diff_id: str, - work_package_id_1: str, - work_package_id_2: str, - *, - diff_name: Optional[str] = None, - scenario: Optional[str] = None, - feeder: Optional[str] = None, - year: Optional[int] = None, - ) -> DiffResultFields: - """Generate and store the differences of network performance metrics between two work packages and returns the number of entries generated with the ID of this diff package.""" - arguments: dict[str, dict[str, Any]] = { - "diffId": {"type": "ID!", "value": diff_id}, - "diffName": {"type": "String", "value": diff_name}, - "workPackageId1": {"type": "ID!", "value": work_package_id_1}, - "workPackageId2": {"type": "ID!", "value": work_package_id_2}, - "scenario": {"type": "String", "value": scenario}, - "feeder": {"type": "String", "value": feeder}, - "year": {"type": "Int", "value": year}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return DiffResultFields( - field_name="generateNetworkPerformanceDiff", arguments=cleared_arguments - ) - - @classmethod - def process_input_database(cls, file_path: str) -> GraphQLField: - """Processes the input database specified by the given filepath.""" - arguments: dict[str, dict[str, Any]] = { - "filePath": {"type": "String!", "value": file_path} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="processInputDatabase", arguments=cleared_arguments - ) - - @classmethod - def run_calibration( - cls, - calibration_name: str, - *, - calibration_time_local: Optional[Any] = None, - feeders: Optional[list[str]] = None, - generator_config: Optional[HcGeneratorConfigInput] = None, - ) -> GraphQLField: - """Runs a calibration and returns a run ID.""" - arguments: dict[str, dict[str, Any]] = { - "calibrationName": {"type": "String!", "value": calibration_name}, - "calibrationTimeLocal": { - "type": "LocalDateTime", - "value": calibration_time_local, - }, - "feeders": {"type": "[String!]", "value": feeders}, - "generatorConfig": { - "type": "HcGeneratorConfigInput", - "value": generator_config, - }, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="runCalibration", arguments=cleared_arguments) - - @classmethod - def run_work_package( - cls, input: WorkPackageInput, work_package_name: str - ) -> GraphQLField: - """Runs a hosting capacity work package and returns its ID.""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "WorkPackageInput!", "value": input}, - "workPackageName": {"type": "String!", "value": work_package_name}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="runWorkPackage", arguments=cleared_arguments) - - @classmethod - def lock_network_model_database(cls) -> GraphQLField: - """Lock EWB to the currently loaded network-model date.""" - return GraphQLField(field_name="lockNetworkModelDatabase") - - @classmethod - def switch_network_model_database(cls, date: str) -> GraphQLField: - """Lock EWB to the provided network-model date and reload the EWB server.""" - arguments: dict[str, dict[str, Any]] = { - "date": {"type": "String!", "value": date} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="switchNetworkModelDatabase", arguments=cleared_arguments - ) - - @classmethod - def unlock_network_model_database(cls) -> GraphQLField: - """Unlock EWB network-model date (Note: This does not reload the EWB server).""" - return GraphQLField(field_name="unlockNetworkModelDatabase") - - @classmethod - def create_sincal_model(cls, input: SincalModelInput) -> GraphQLField: - """Launches Sincal Exporter with specified config. Returns ID of model.""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "SincalModelInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="createSincalModel", arguments=cleared_arguments) - - @classmethod - def create_sincal_model_preset(cls, input: SincalModelInput) -> GraphQLField: - """Creates a new sincalModel preset and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "SincalModelInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="createSincalModelPreset", arguments=cleared_arguments - ) - - @classmethod - def delete_sincal_model(cls, model_id: str) -> GraphQLField: - """Deletes sincalModel with ID and returns said ID""" - arguments: dict[str, dict[str, Any]] = { - "modelId": {"type": "ID!", "value": model_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="deleteSincalModel", arguments=cleared_arguments) - - @classmethod - def delete_sincal_model_preset(cls, preset_id: str) -> GraphQLField: - """Deletes sincalModel preset with ID and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "presetId": {"type": "ID!", "value": preset_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="deleteSincalModelPreset", arguments=cleared_arguments - ) - - @classmethod - def update_sincal_model_config_file_path( - cls, file_path: str, file_type: SincalFileType - ) -> GraphQLField: - """Updates the file path of one of the sincalModel input files. Returns true on success.""" - arguments: dict[str, dict[str, Any]] = { - "filePath": {"type": "String!", "value": file_path}, - "fileType": {"type": "SincalFileType!", "value": file_type}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="updateSincalModelConfigFilePath", arguments=cleared_arguments - ) - - @classmethod - def update_sincal_model_preset( - cls, preset_id: str, generation_spec: SincalModelGenerationSpecInput - ) -> GraphQLField: - """Updates sincalModel preset with ID and returns its ID""" - arguments: dict[str, dict[str, Any]] = { - "presetId": {"type": "ID!", "value": preset_id}, - "generationSpec": { - "type": "SincalModelGenerationSpecInput!", - "value": generation_spec, - }, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="updateSincalModelPreset", arguments=cleared_arguments - ) - - @classmethod - def execute_ingestor( - cls, *, run_config: Optional[list[IngestorConfigInput]] = None - ) -> GraphQLField: - """Start ingestor job.""" - arguments: dict[str, dict[str, Any]] = { - "runConfig": {"type": "[IngestorConfigInput!]", "value": run_config} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="executeIngestor", arguments=cleared_arguments) - - @classmethod - def run_feeder_load_analysis(cls, input: FeederLoadAnalysisInput) -> GraphQLField: - """Runs a feeder load analysis job.""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "FeederLoadAnalysisInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="runFeederLoadAnalysis", arguments=cleared_arguments - ) - - @classmethod - def create_open_dss_model(cls, input: OpenDssModelInput) -> GraphQLField: - """Launches OpenDSS Exporter with specified config. Returns ID of model.""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "OpenDssModelInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="createOpenDssModel", arguments=cleared_arguments - ) - - @classmethod - def delete_open_dss_model(cls, model_id: str) -> GraphQLField: - """Deletes openDSS model with ID and returns said ID""" - arguments: dict[str, dict[str, Any]] = { - "modelId": {"type": "ID!", "value": model_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="deleteOpenDssModel", arguments=cleared_arguments - ) - - @classmethod - def save_user_customer_list_column_config( - cls, columns: list[str] - ) -> UserCustomerListColumnConfigFields: - """Update user's column configuration for the customer list to customize displayed columns.""" - arguments: dict[str, dict[str, Any]] = { - "columns": {"type": "[String!]!", "value": columns} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return UserCustomerListColumnConfigFields( - field_name="saveUserCustomerListColumnConfig", arguments=cleared_arguments - ) - - @classmethod - def clear_app_option(cls, name: str) -> RemoveAppOptionResultFields: - """Reset an application option to its default value""" - arguments: dict[str, dict[str, Any]] = { - "name": {"type": "String!", "value": name} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return RemoveAppOptionResultFields( - field_name="clearAppOption", arguments=cleared_arguments - ) - - @classmethod - def set_app_option(cls, app_options: AppOptionsInput) -> GraphQLField: - """Set an application option""" - arguments: dict[str, dict[str, Any]] = { - "appOptions": {"type": "AppOptionsInput!", "value": app_options} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="setAppOption", arguments=cleared_arguments) - - @classmethod - def finalize_variant_processing( - cls, variant_upload_id: str, submitted_variants: list[str] - ) -> GraphQLField: - """Finalize variant processing with the specified file by supplying a list of finalized variants""" - arguments: dict[str, dict[str, Any]] = { - "variantUploadId": {"type": "String!", "value": variant_upload_id}, - "submittedVariants": {"type": "[String!]!", "value": submitted_variants}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="finalizeVariantProcessing", arguments=cleared_arguments - ) - - @classmethod - def start_variant_processing( - cls, prefix: str, file_type: VariantFileType - ) -> GraphQLField: - """Start variant processing with the specified file. Returns an ID which can be used to track progress of the processing""" - arguments: dict[str, dict[str, Any]] = { - "prefix": {"type": "String!", "value": prefix}, - "fileType": {"type": "VariantFileType!", "value": file_type}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="startVariantProcessing", arguments=cleared_arguments - ) diff --git a/src/zepben/eas/lib/generated_graphql_client/custom_queries.py b/src/zepben/eas/lib/generated_graphql_client/custom_queries.py deleted file mode 100644 index 1559f68..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/custom_queries.py +++ /dev/null @@ -1,1031 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional - -from .custom_fields import ( - AppOptionsFields, - CustomerDetailsResponseFields, - DurationCurveByTerminalFields, - FeederLoadAnalysisReportFields, - GqlTxTapRecordFields, - GqlUserFields, - GqlUserResponseFields, - HcCalibrationFields, - HcScenarioConfigsPageFields, - HcWorkPackageFields, - HcWorkPackagePageFields, - IngestionJobFields, - IngestionRunFields, - IngestorRunPageFields, - JobSourceFields, - MachineUserFields, - MetricFields, - NetworkModelsFields, - OpenDssModelPageFields, - OpportunitiesByYearFields, - OpportunityFields, - OpportunityLocationFields, - PowerFactoryModelFields, - PowerFactoryModelPageFields, - PowerFactoryModelTemplateFields, - PowerFactoryModelTemplatePageFields, - ProcessedDiffFields, - ProcessedDiffPageFields, - SincalGlobalInputsConfigFields, - SincalModelFields, - SincalModelPageFields, - SincalModelPresetFields, - SincalModelPresetPageFields, - StudyFields, - StudyPageFields, - StudyResultFields, - UploadUrlResponseFields, - UserCustomerListColumnConfigFields, - VariantWorkPackageFields, - WorkPackageTreeFields, -) -from .custom_typing_fields import GraphQLField -from .enums import ( - ContainerType, - HostingCapacityFileType, - SincalFileType, - VariantFileType, - WorkflowStatus, -) -from .input_types import ( - GetOpenDssModelsFilterInput, - GetOpenDssModelsSortCriteriaInput, - GetPowerFactoryModelsFilterInput, - GetPowerFactoryModelsSortCriteriaInput, - GetPowerFactoryModelTemplatesFilterInput, - GetPowerFactoryModelTemplatesSortCriteriaInput, - GetSincalModelPresetsFilterInput, - GetSincalModelPresetsSortCriteriaInput, - GetSincalModelsFilterInput, - GetSincalModelsSortCriteriaInput, - GetStudiesFilterInput, - GetStudiesSortCriteriaInput, - HcScenarioConfigsFilterInput, - HcWorkPackagesFilterInput, - HcWorkPackagesSortCriteriaInput, - IngestorRunsFilterInput, - IngestorRunsSortCriteriaInput, - ProcessedDiffFilterInput, - ProcessedDiffSortCriteriaInput, - WorkPackageInput, -) - - -class Query: - @classmethod - def paged_studies( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetStudiesFilterInput] = None, - sort: Optional[GetStudiesSortCriteriaInput] = None, - ) -> "GraphQLQuery[StudyPageFields, StudyPageGraphQLField]": - """Retrieve a page of studies, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "GetStudiesFilterInput", "value": filter_}, - "sort": {"type": "GetStudiesSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return StudyPageFields(field_name="pagedStudies", arguments=cleared_arguments) - - @classmethod - def results_by_id( - cls, ids: list[str] - ) -> "GraphQLQuery[StudyResultFields, StudyResultGraphQLField]": - """Retrieve a list of results by IDs""" - arguments: dict[str, dict[str, Any]] = {"ids": {"type": "[ID!]!", "value": ids}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return StudyResultFields(field_name="resultsById", arguments=cleared_arguments) - - @classmethod - def studies( - cls, *, filter_: Optional[GetStudiesFilterInput] = None - ) -> "GraphQLQuery[StudyFields, StudyGraphQLField]": - """Retrieve a list of studies, with optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "filter": {"type": "GetStudiesFilterInput", "value": filter_} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return StudyFields(field_name="studies", arguments=cleared_arguments) - - @classmethod - def studies_by_id( - cls, ids: list[str] - ) -> "GraphQLQuery[StudyFields, StudyGraphQLField]": - """Retrieve a list of studies by IDs""" - arguments: dict[str, dict[str, Any]] = {"ids": {"type": "[ID!]!", "value": ids}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return StudyFields(field_name="studiesById", arguments=cleared_arguments) - - @classmethod - def styles_by_id(cls, ids: list[str]) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Retrieve a list of style layers by IDs""" - arguments: dict[str, dict[str, Any]] = {"ids": {"type": "[ID!]!", "value": ids}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="stylesById", arguments=cleared_arguments) - - @classmethod - def current_user( - cls, - ) -> "GraphQLQuery[GqlUserResponseFields, GqlUserResponseGraphQLField]": - """Get information about the current user""" - return GqlUserResponseFields(field_name="currentUser") - - @classmethod - def paged_power_factory_model_templates( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetPowerFactoryModelTemplatesFilterInput] = None, - sort: Optional[GetPowerFactoryModelTemplatesSortCriteriaInput] = None, - ) -> "GraphQLQuery[PowerFactoryModelTemplatePageFields, PowerFactoryModelTemplatePageGraphQLField]": - """Retrieve a page of powerFactoryModel templates, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": { - "type": "GetPowerFactoryModelTemplatesFilterInput", - "value": filter_, - }, - "sort": { - "type": "GetPowerFactoryModelTemplatesSortCriteriaInput", - "value": sort, - }, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelTemplatePageFields( - field_name="pagedPowerFactoryModelTemplates", arguments=cleared_arguments - ) - - @classmethod - def paged_power_factory_models( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetPowerFactoryModelsFilterInput] = None, - sort: Optional[GetPowerFactoryModelsSortCriteriaInput] = None, - ) -> "GraphQLQuery[PowerFactoryModelPageFields, PowerFactoryModelPageGraphQLField]": - """Retrieve a page of powerFactoryModels, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "GetPowerFactoryModelsFilterInput", "value": filter_}, - "sort": {"type": "GetPowerFactoryModelsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelPageFields( - field_name="pagedPowerFactoryModels", arguments=cleared_arguments - ) - - @classmethod - def power_factory_model_by_id( - cls, model_id: str - ) -> "GraphQLQuery[PowerFactoryModelFields, PowerFactoryModelGraphQLField]": - """Retrieve a powerFactoryModel by ID""" - arguments: dict[str, dict[str, Any]] = { - "modelId": {"type": "ID!", "value": model_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelFields( - field_name="powerFactoryModelById", arguments=cleared_arguments - ) - - @classmethod - def power_factory_model_template_by_id( - cls, template_id: str - ) -> "GraphQLQuery[PowerFactoryModelTemplateFields, PowerFactoryModelTemplateGraphQLField]": - """Retrieve a powerFactoryModel template by ID""" - arguments: dict[str, dict[str, Any]] = { - "templateId": {"type": "ID!", "value": template_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelTemplateFields( - field_name="powerFactoryModelTemplateById", arguments=cleared_arguments - ) - - @classmethod - def power_factory_model_templates_by_ids( - cls, template_ids: list[str] - ) -> "GraphQLQuery[PowerFactoryModelTemplateFields, PowerFactoryModelTemplateGraphQLField]": - """Retrieve a list of powerFactoryModel templates by IDs""" - arguments: dict[str, dict[str, Any]] = { - "templateIds": {"type": "[ID!]!", "value": template_ids} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelTemplateFields( - field_name="powerFactoryModelTemplatesByIds", arguments=cleared_arguments - ) - - @classmethod - def power_factory_models_by_ids( - cls, model_ids: list[str] - ) -> "GraphQLQuery[PowerFactoryModelFields, PowerFactoryModelGraphQLField]": - """Retrieve a list of powerFactoryModels by IDs""" - arguments: dict[str, dict[str, Any]] = { - "modelIds": {"type": "[ID!]!", "value": model_ids} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return PowerFactoryModelFields( - field_name="powerFactoryModelsByIds", arguments=cleared_arguments - ) - - @classmethod - def get_active_work_packages(cls) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Retrieve a list of currently active (running, scheduled, pending) work packages""" - return GraphQLField(field_name="getActiveWorkPackages") - - @classmethod - def get_all_work_packages_authors( - cls, - ) -> "GraphQLQuery[GqlUserFields, GqlUserGraphQLField]": - """Retrieve all users that have created work packages.""" - return GqlUserFields(field_name="getAllWorkPackagesAuthors") - - @classmethod - def get_calibration_run( - cls, id: str - ) -> "GraphQLQuery[HcCalibrationFields, HcCalibrationGraphQLField]": - """Retrieve calibration run details by ID""" - arguments: dict[str, dict[str, Any]] = {"id": {"type": "ID!", "value": id}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return HcCalibrationFields( - field_name="getCalibrationRun", arguments=cleared_arguments - ) - - @classmethod - def get_calibration_sets(cls) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Retrieve available distribution transformer tap calibration sets.""" - return GraphQLField(field_name="getCalibrationSets") - - @classmethod - def get_duration_curves( - cls, - work_package_id: str, - scenario: str, - feeder: str, - year: int, - conducting_equipment_mrid: str, - ) -> "GraphQLQuery[DurationCurveByTerminalFields, DurationCurveByTerminalGraphQLField]": - """Retrieve duration curves for a single piece of equipment in a specific SYF.""" - arguments: dict[str, dict[str, Any]] = { - "workPackageId": {"type": "String!", "value": work_package_id}, - "scenario": {"type": "String!", "value": scenario}, - "feeder": {"type": "String!", "value": feeder}, - "year": {"type": "Int!", "value": year}, - "conductingEquipmentMrid": { - "type": "String!", - "value": conducting_equipment_mrid, - }, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return DurationCurveByTerminalFields( - field_name="getDurationCurves", arguments=cleared_arguments - ) - - @classmethod - def get_opportunities( - cls, *, year: Optional[int] = None - ) -> "GraphQLQuery[OpportunitiesByYearFields, OpportunitiesByYearGraphQLField]": - """Retrieve all Opportunities available for a specific year.""" - arguments: dict[str, dict[str, Any]] = {"year": {"type": "Int", "value": year}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return OpportunitiesByYearFields( - field_name="getOpportunities", arguments=cleared_arguments - ) - - @classmethod - def get_opportunities_for_equipment( - cls, m_rid: str - ) -> "GraphQLQuery[OpportunityFields, OpportunityGraphQLField]": - """Retrieve Opportunities by attached conducting equipment mRID.""" - arguments: dict[str, dict[str, Any]] = { - "mRID": {"type": "String!", "value": m_rid} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return OpportunityFields( - field_name="getOpportunitiesForEquipment", arguments=cleared_arguments - ) - - @classmethod - def get_opportunity( - cls, id: str - ) -> "GraphQLQuery[OpportunityFields, OpportunityGraphQLField]": - """Retrieve Opportunities by id.""" - arguments: dict[str, dict[str, Any]] = {"id": {"type": "String!", "value": id}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return OpportunityFields( - field_name="getOpportunity", arguments=cleared_arguments - ) - - @classmethod - def get_opportunity_locations( - cls, *, year: Optional[int] = None - ) -> "GraphQLQuery[OpportunityLocationFields, OpportunityLocationGraphQLField]": - """Retrieve all opportunity locations available for a specific year.""" - arguments: dict[str, dict[str, Any]] = {"year": {"type": "Int", "value": year}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return OpportunityLocationFields( - field_name="getOpportunityLocations", arguments=cleared_arguments - ) - - @classmethod - def get_scenario_configurations( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[HcScenarioConfigsFilterInput] = None, - ) -> "GraphQLQuery[HcScenarioConfigsPageFields, HcScenarioConfigsPageGraphQLField]": - """Retrieve a page scenario configurations from the hosting capacity input database.""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "HcScenarioConfigsFilterInput", "value": filter_}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return HcScenarioConfigsPageFields( - field_name="getScenarioConfigurations", arguments=cleared_arguments - ) - - @classmethod - def get_transformer_tap_settings( - cls, - calibration_name: str, - *, - feeder: Optional[str] = None, - transformer_mrid: Optional[str] = None, - ) -> "GraphQLQuery[GqlTxTapRecordFields, GqlTxTapRecordGraphQLField]": - """Retrieve distribution transformer tap settings from a calibration set in the hosting capacity input database.""" - arguments: dict[str, dict[str, Any]] = { - "calibrationName": {"type": "String!", "value": calibration_name}, - "feeder": {"type": "String", "value": feeder}, - "transformerMrid": {"type": "String", "value": transformer_mrid}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GqlTxTapRecordFields( - field_name="getTransformerTapSettings", arguments=cleared_arguments - ) - - @classmethod - def get_work_package_by_id( - cls, id: str, *, with_groupings: Optional[bool] = None - ) -> "GraphQLQuery[HcWorkPackageFields, HcWorkPackageGraphQLField]": - """Retrieve a hosting capacity work package by ID, withGroupings: Whether to include model groupings in the work package progress details, default value is false""" - arguments: dict[str, dict[str, Any]] = { - "id": {"type": "ID!", "value": id}, - "withGroupings": {"type": "Boolean", "value": with_groupings}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return HcWorkPackageFields( - field_name="getWorkPackageById", arguments=cleared_arguments - ) - - @classmethod - def get_work_package_cost_estimation( - cls, input: WorkPackageInput - ) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Returns an estimated cost of the submitted hosting capacity work package.""" - arguments: dict[str, dict[str, Any]] = { - "input": {"type": "WorkPackageInput!", "value": input} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="getWorkPackageCostEstimation", arguments=cleared_arguments - ) - - @classmethod - def get_work_package_tree( - cls, id: str - ) -> "GraphQLQuery[WorkPackageTreeFields, WorkPackageTreeGraphQLField]": - """Retrieve a work package tree with its ancestors and immediate children.""" - arguments: dict[str, dict[str, Any]] = {"id": {"type": "ID!", "value": id}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return WorkPackageTreeFields( - field_name="getWorkPackageTree", arguments=cleared_arguments - ) - - @classmethod - def get_work_packages( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[HcWorkPackagesFilterInput] = None, - sort: Optional[HcWorkPackagesSortCriteriaInput] = None, - with_groupings: Optional[bool] = None, - ) -> "GraphQLQuery[HcWorkPackagePageFields, HcWorkPackagePageGraphQLField]": - """Retrieve a page of hosting capacity work packages, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "HcWorkPackagesFilterInput", "value": filter_}, - "sort": {"type": "HcWorkPackagesSortCriteriaInput", "value": sort}, - "withGroupings": {"type": "Boolean", "value": with_groupings}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return HcWorkPackagePageFields( - field_name="getWorkPackages", arguments=cleared_arguments - ) - - @classmethod - def hosting_capacity_file_upload_url( - cls, filename: str, file_type: HostingCapacityFileType - ) -> "GraphQLQuery[UploadUrlResponseFields, UploadUrlResponseGraphQLField]": - """Generate a pre-signed URL to upload hosting capacity file to the storage location. Returns the pre-signed URL along with the final file path as it will be referenced by EAS""" - arguments: dict[str, dict[str, Any]] = { - "filename": {"type": "String!", "value": filename}, - "fileType": {"type": "HostingCapacityFileType!", "value": file_type}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return UploadUrlResponseFields( - field_name="hostingCapacityFileUploadUrl", arguments=cleared_arguments - ) - - @classmethod - def list_calibration_runs( - cls, - *, - name: Optional[str] = None, - calibration_time: Optional[Any] = None, - status: Optional[WorkflowStatus] = None, - ) -> "GraphQLQuery[HcCalibrationFields, HcCalibrationGraphQLField]": - """Retrieve all calibration runs initiated through EAS""" - arguments: dict[str, dict[str, Any]] = { - "name": {"type": "String", "value": name}, - "calibrationTime": {"type": "LocalDateTime", "value": calibration_time}, - "status": {"type": "WorkflowStatus", "value": status}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return HcCalibrationFields( - field_name="listCalibrationRuns", arguments=cleared_arguments - ) - - @classmethod - def get_processed_diff( - cls, diff_id: str - ) -> "GraphQLQuery[ProcessedDiffFields, ProcessedDiffGraphQLField]": - """Retrieve processed diff of hosting capacity work packages with diffId""" - arguments: dict[str, dict[str, Any]] = { - "diffId": {"type": "ID!", "value": diff_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return ProcessedDiffFields( - field_name="getProcessedDiff", arguments=cleared_arguments - ) - - @classmethod - def get_processed_diffs( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[ProcessedDiffFilterInput] = None, - sort: Optional[ProcessedDiffSortCriteriaInput] = None, - ) -> "GraphQLQuery[ProcessedDiffPageFields, ProcessedDiffPageGraphQLField]": - """Retrieve a page of processed diffs, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "ProcessedDiffFilterInput", "value": filter_}, - "sort": {"type": "ProcessedDiffSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return ProcessedDiffPageFields( - field_name="getProcessedDiffs", arguments=cleared_arguments - ) - - @classmethod - def get_all_jobs( - cls, - ) -> "GraphQLQuery[IngestionJobFields, IngestionJobGraphQLField]": - """Gets the ID and metadata of all ingestion jobs in reverse chronological order.""" - return IngestionJobFields(field_name="getAllJobs") - - @classmethod - def get_distinct_metric_names( - cls, job_id: str - ) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Gets all possible values of metricName for a specific job.""" - arguments: dict[str, dict[str, Any]] = { - "jobId": {"type": "String!", "value": job_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="getDistinctMetricNames", arguments=cleared_arguments - ) - - @classmethod - def get_metrics( - cls, job_id: str, container_type: ContainerType, container_id: str - ) -> "GraphQLQuery[MetricFields, MetricGraphQLField]": - """Gets the metrics for a network container emitted in an ingestion job.""" - arguments: dict[str, dict[str, Any]] = { - "jobId": {"type": "String!", "value": job_id}, - "containerType": {"type": "ContainerType!", "value": container_type}, - "containerId": {"type": "String!", "value": container_id}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return MetricFields(field_name="getMetrics", arguments=cleared_arguments) - - @classmethod - def get_newest_job( - cls, - ) -> "GraphQLQuery[IngestionJobFields, IngestionJobGraphQLField]": - """Gets the ID and metadata of the newest ingestion job. If no job exists, this returns null.""" - return IngestionJobFields(field_name="getNewestJob") - - @classmethod - def get_sources( - cls, job_id: str - ) -> "GraphQLQuery[JobSourceFields, JobSourceGraphQLField]": - """Gets the data sources used in an ingestion job.""" - arguments: dict[str, dict[str, Any]] = { - "jobId": {"type": "String!", "value": job_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return JobSourceFields(field_name="getSources", arguments=cleared_arguments) - - @classmethod - def paged_sincal_model_presets( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetSincalModelPresetsFilterInput] = None, - sort: Optional[GetSincalModelPresetsSortCriteriaInput] = None, - ) -> "GraphQLQuery[SincalModelPresetPageFields, SincalModelPresetPageGraphQLField]": - """Retrieve a page of sincalModel presets, with optional limit and offset, and optional filtering. A default preset with null ID will also be included in the response, which may result in the number of presets returned exceeding the desired page size (limit).""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "GetSincalModelPresetsFilterInput", "value": filter_}, - "sort": {"type": "GetSincalModelPresetsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelPresetPageFields( - field_name="pagedSincalModelPresets", arguments=cleared_arguments - ) - - @classmethod - def paged_sincal_models( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetSincalModelsFilterInput] = None, - sort: Optional[GetSincalModelsSortCriteriaInput] = None, - ) -> "GraphQLQuery[SincalModelPageFields, SincalModelPageGraphQLField]": - """Retrieve a page of sincalModels, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "GetSincalModelsFilterInput", "value": filter_}, - "sort": {"type": "GetSincalModelsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelPageFields( - field_name="pagedSincalModels", arguments=cleared_arguments - ) - - @classmethod - def sincal_model_by_id( - cls, model_id: str - ) -> "GraphQLQuery[SincalModelFields, SincalModelGraphQLField]": - """Retrieve a sincalModel by ID""" - arguments: dict[str, dict[str, Any]] = { - "modelId": {"type": "ID!", "value": model_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelFields( - field_name="sincalModelById", arguments=cleared_arguments - ) - - @classmethod - def sincal_model_config_upload_url( - cls, filename: str, file_type: SincalFileType - ) -> "GraphQLQuery[UploadUrlResponseFields, UploadUrlResponseGraphQLField]": - """Generate a pre-signed URL to upload a sincal configuration file to the input storage location. Returns the pre-signed URL along with the final file path as it will be referenced by EAS. This does not update the sincal configuration. To make use of a newly uploaded configuration file, pass the `filePath` returned by this query to the `updateSincalModelConfigFilePath()` mutation.""" - arguments: dict[str, dict[str, Any]] = { - "filename": {"type": "String!", "value": filename}, - "fileType": {"type": "SincalFileType!", "value": file_type}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return UploadUrlResponseFields( - field_name="sincalModelConfigUploadUrl", arguments=cleared_arguments - ) - - @classmethod - def sincal_model_global_config( - cls, - ) -> "GraphQLQuery[SincalGlobalInputsConfigFields, SincalGlobalInputsConfigGraphQLField]": - """Retrieve the current sincalModel input file paths.""" - return SincalGlobalInputsConfigFields(field_name="sincalModelGlobalConfig") - - @classmethod - def sincal_model_preset_by_id( - cls, preset_id: str - ) -> "GraphQLQuery[SincalModelPresetFields, SincalModelPresetGraphQLField]": - """Retrieve a sincalModel preset by ID""" - arguments: dict[str, dict[str, Any]] = { - "presetId": {"type": "ID!", "value": preset_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelPresetFields( - field_name="sincalModelPresetById", arguments=cleared_arguments - ) - - @classmethod - def sincal_model_presets_by_ids( - cls, preset_ids: list[str] - ) -> "GraphQLQuery[SincalModelPresetFields, SincalModelPresetGraphQLField]": - """Retrieve a list of sincalModel presets by IDs""" - arguments: dict[str, dict[str, Any]] = { - "presetIds": {"type": "[ID!]!", "value": preset_ids} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelPresetFields( - field_name="sincalModelPresetsByIds", arguments=cleared_arguments - ) - - @classmethod - def sincal_models_by_ids( - cls, model_ids: list[str] - ) -> "GraphQLQuery[SincalModelFields, SincalModelGraphQLField]": - """Retrieve a list of sincalModels by IDs""" - arguments: dict[str, dict[str, Any]] = { - "modelIds": {"type": "[ID!]!", "value": model_ids} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return SincalModelFields( - field_name="sincalModelsByIds", arguments=cleared_arguments - ) - - @classmethod - def create_machine_api_key( - cls, roles: list[str], token_name: str - ) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Create a new JWT auth token for a machine with the specified roles.""" - arguments: dict[str, dict[str, Any]] = { - "roles": {"type": "[String!]!", "value": roles}, - "tokenName": {"type": "String!", "value": token_name}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField( - field_name="createMachineApiKey", arguments=cleared_arguments - ) - - @classmethod - def create_user_api_key( - cls, roles: list[str], token_name: str - ) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Create the JWT auth token for the current user with specified roles.""" - arguments: dict[str, dict[str, Any]] = { - "roles": {"type": "[String!]!", "value": roles}, - "tokenName": {"type": "String!", "value": token_name}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return GraphQLField(field_name="createUserApiKey", arguments=cleared_arguments) - - @classmethod - def get_machine_tokens( - cls, - ) -> "GraphQLQuery[MachineUserFields, MachineUserGraphQLField]": - """Gets all machine token users with their username and display name.""" - return MachineUserFields(field_name="getMachineTokens") - - @classmethod - def get_public_geo_view_config(cls) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Retrieve the GeoViewConfig used to config the EWB public map tile endpoint. Returns NUll if not enabled.""" - return GraphQLField(field_name="getPublicGeoViewConfig") - - @classmethod - def get_all_external_roles(cls) -> "GraphQLQuery[GraphQLField, GraphQLField]": - """Get all external roles from EAS.""" - return GraphQLField(field_name="getAllExternalRoles") - - @classmethod - def get_network_models( - cls, - ) -> "GraphQLQuery[NetworkModelsFields, NetworkModelsGraphQLField]": - """Get all EWB network models""" - return NetworkModelsFields(field_name="getNetworkModels") - - @classmethod - def get_feeder_load_analysis_report_status( - cls, report_id: str, full_spec: bool - ) -> "GraphQLQuery[FeederLoadAnalysisReportFields, FeederLoadAnalysisReportGraphQLField]": - """Retrieve the status of a feeder load analysis job.""" - arguments: dict[str, dict[str, Any]] = { - "reportId": {"type": "ID!", "value": report_id}, - "fullSpec": {"type": "Boolean!", "value": full_spec}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return FeederLoadAnalysisReportFields( - field_name="getFeederLoadAnalysisReportStatus", arguments=cleared_arguments - ) - - @classmethod - def get_ingestor_run( - cls, id: int - ) -> "GraphQLQuery[IngestionRunFields, IngestionRunGraphQLField]": - """Retrieve ingestor run details by ID""" - arguments: dict[str, dict[str, Any]] = {"id": {"type": "Int!", "value": id}} - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return IngestionRunFields( - field_name="getIngestorRun", arguments=cleared_arguments - ) - - @classmethod - def list_ingestor_runs( - cls, - *, - filter_: Optional[IngestorRunsFilterInput] = None, - sort: Optional[IngestorRunsSortCriteriaInput] = None, - ) -> "GraphQLQuery[IngestionRunFields, IngestionRunGraphQLField]": - """Retrieve all ingestor runs initiated through EAS""" - arguments: dict[str, dict[str, Any]] = { - "filter": {"type": "IngestorRunsFilterInput", "value": filter_}, - "sort": {"type": "IngestorRunsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return IngestionRunFields( - field_name="listIngestorRuns", arguments=cleared_arguments - ) - - @classmethod - def list_ingestor_runs_paged( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[IngestorRunsFilterInput] = None, - sort: Optional[IngestorRunsSortCriteriaInput] = None, - ) -> "GraphQLQuery[IngestorRunPageFields, IngestorRunPageGraphQLField]": - """Retrieve all ingestor runs initiated through EAS""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "IngestorRunsFilterInput", "value": filter_}, - "sort": {"type": "IngestorRunsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return IngestorRunPageFields( - field_name="listIngestorRunsPaged", arguments=cleared_arguments - ) - - @classmethod - def paged_open_dss_models( - cls, - *, - limit: Optional[int] = None, - offset: Optional[Any] = None, - filter_: Optional[GetOpenDssModelsFilterInput] = None, - sort: Optional[GetOpenDssModelsSortCriteriaInput] = None, - ) -> "GraphQLQuery[OpenDssModelPageFields, OpenDssModelPageGraphQLField]": - """Retrieve a page of OpenDSS models, with optional limit and offset, and optional filtering""" - arguments: dict[str, dict[str, Any]] = { - "limit": {"type": "Int", "value": limit}, - "offset": {"type": "Long", "value": offset}, - "filter": {"type": "GetOpenDssModelsFilterInput", "value": filter_}, - "sort": {"type": "GetOpenDssModelsSortCriteriaInput", "value": sort}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return OpenDssModelPageFields( - field_name="pagedOpenDssModels", arguments=cleared_arguments - ) - - @classmethod - def get_user_permitted_customer_list_column_config( - cls, - ) -> "GraphQLQuery[UserCustomerListColumnConfigFields, UserCustomerListColumnConfigGraphQLField]": - """Fetches the user permitted column configuration for the customer list view.""" - return UserCustomerListColumnConfigFields( - field_name="getUserPermittedCustomerListColumnConfig" - ) - - @classmethod - def get_user_saved_customer_list_column_config( - cls, - ) -> "GraphQLQuery[UserCustomerListColumnConfigFields, UserCustomerListColumnConfigGraphQLField]": - """Fetches the user's column configuration for the customer list view.""" - return UserCustomerListColumnConfigFields( - field_name="getUserSavedCustomerListColumnConfig" - ) - - @classmethod - def get_customer_list( - cls, m_ri_ds: list[str] - ) -> "GraphQLQuery[CustomerDetailsResponseFields, CustomerDetailsResponseGraphQLField]": - """Retrieve the list of customers and their details.""" - arguments: dict[str, dict[str, Any]] = { - "mRIDs": {"type": "[String!]!", "value": m_ri_ds} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return CustomerDetailsResponseFields( - field_name="getCustomerList", arguments=cleared_arguments - ) - - @classmethod - def get_customer_list_by_nmis( - cls, nmis: list[str] - ) -> "GraphQLQuery[CustomerDetailsResponseFields, CustomerDetailsResponseGraphQLField]": - """Retrieve customer details using NMIs as input.""" - arguments: dict[str, dict[str, Any]] = { - "nmis": {"type": "[String!]!", "value": nmis} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return CustomerDetailsResponseFields( - field_name="getCustomerListByNmis", arguments=cleared_arguments - ) - - @classmethod - def get_app_options( - cls, - ) -> "GraphQLQuery[AppOptionsFields, AppOptionsGraphQLField]": - """Get App Options""" - return AppOptionsFields(field_name="getAppOptions") - - @classmethod - def get_presigned_upload_url_for_variant( - cls, filename: str, file_type: VariantFileType - ) -> "GraphQLQuery[UploadUrlResponseFields, UploadUrlResponseGraphQLField]": - """Generate a pre-signed URL to upload variant files to the cloud storage. Returns the pre-signed URL along with the final file path as it will be referenced by EAS""" - arguments: dict[str, dict[str, Any]] = { - "filename": {"type": "String!", "value": filename}, - "fileType": {"type": "VariantFileType!", "value": file_type}, - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return UploadUrlResponseFields( - field_name="getPresignedUploadUrlForVariant", arguments=cleared_arguments - ) - - @classmethod - def get_variant_upload_info( - cls, job_id: str - ) -> "GraphQLQuery[VariantWorkPackageFields, VariantWorkPackageGraphQLField]": - """Retrieves status of a variant ingestion workflow""" - arguments: dict[str, dict[str, Any]] = { - "jobID": {"type": "String!", "value": job_id} - } - cleared_arguments = { - key: value for key, value in arguments.items() if value["value"] is not None - } - return VariantWorkPackageFields( - field_name="getVariantUploadInfo", arguments=cleared_arguments - ) - - -from zepben.eas.lib.ariadne_plugins.types import GraphQLQuery - -from .custom_typing_fields import ( - AppOptionsGraphQLField, - CustomerDetailsResponseGraphQLField, - DurationCurveByTerminalGraphQLField, - FeederLoadAnalysisReportGraphQLField, - GqlTxTapRecordGraphQLField, - GqlUserGraphQLField, - GqlUserResponseGraphQLField, - GraphQLField, - HcCalibrationGraphQLField, - HcScenarioConfigsPageGraphQLField, - HcWorkPackageGraphQLField, - HcWorkPackagePageGraphQLField, - IngestionJobGraphQLField, - IngestionRunGraphQLField, - IngestorRunPageGraphQLField, - JobSourceGraphQLField, - MachineUserGraphQLField, - MetricGraphQLField, - NetworkModelsGraphQLField, - OpenDssModelPageGraphQLField, - OpportunitiesByYearGraphQLField, - OpportunityGraphQLField, - OpportunityLocationGraphQLField, - PowerFactoryModelGraphQLField, - PowerFactoryModelPageGraphQLField, - PowerFactoryModelTemplateGraphQLField, - PowerFactoryModelTemplatePageGraphQLField, - ProcessedDiffGraphQLField, - ProcessedDiffPageGraphQLField, - SincalGlobalInputsConfigGraphQLField, - SincalModelGraphQLField, - SincalModelPageGraphQLField, - SincalModelPresetGraphQLField, - SincalModelPresetPageGraphQLField, - StudyGraphQLField, - StudyPageGraphQLField, - StudyResultGraphQLField, - UploadUrlResponseGraphQLField, - UserCustomerListColumnConfigGraphQLField, - VariantWorkPackageGraphQLField, - WorkPackageTreeGraphQLField, -) diff --git a/src/zepben/eas/lib/generated_graphql_client/custom_typing_fields.py b/src/zepben/eas/lib/generated_graphql_client/custom_typing_fields.py deleted file mode 100644 index e80403e..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/custom_typing_fields.py +++ /dev/null @@ -1,434 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from .base_operation import GraphQLField - - -class AppOptionsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "AppOptionsGraphQLField": - self._alias = alias - return self - - -class ColumnGraphQLField(GraphQLField): - def alias(self, alias: str) -> "ColumnGraphQLField": - self._alias = alias - return self - - -class CoordinateGraphQLField(GraphQLField): - def alias(self, alias: str) -> "CoordinateGraphQLField": - self._alias = alias - return self - - -class CustomerDetailsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "CustomerDetailsGraphQLField": - self._alias = alias - return self - - -class CustomerDetailsResponseGraphQLField(GraphQLField): - def alias(self, alias: str) -> "CustomerDetailsResponseGraphQLField": - self._alias = alias - return self - - -class CustomerListColumnConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "CustomerListColumnConfigGraphQLField": - self._alias = alias - return self - - -class DiffResultGraphQLField(GraphQLField): - def alias(self, alias: str) -> "DiffResultGraphQLField": - self._alias = alias - return self - - -class DurationCurveGraphQLField(GraphQLField): - def alias(self, alias: str) -> "DurationCurveGraphQLField": - self._alias = alias - return self - - -class DurationCurveByTerminalGraphQLField(GraphQLField): - def alias(self, alias: str) -> "DurationCurveByTerminalGraphQLField": - self._alias = alias - return self - - -class DurationCurvePointGraphQLField(GraphQLField): - def alias(self, alias: str) -> "DurationCurvePointGraphQLField": - self._alias = alias - return self - - -class EquipmentGraphQLField(GraphQLField): - def alias(self, alias: str) -> "EquipmentGraphQLField": - self._alias = alias - return self - - -class FeederLoadAnalysisReportGraphQLField(GraphQLField): - def alias(self, alias: str) -> "FeederLoadAnalysisReportGraphQLField": - self._alias = alias - return self - - -class FeederLoadAnalysisSpecGraphQLField(GraphQLField): - def alias(self, alias: str) -> "FeederLoadAnalysisSpecGraphQLField": - self._alias = alias - return self - - -class GeoJsonFeatureGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GeoJsonFeatureGraphQLField": - self._alias = alias - return self - - -class GeoJsonGeometryGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GeoJsonGeometryGraphQLField": - self._alias = alias - return self - - -class GeoJsonOverlayGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GeoJsonOverlayGraphQLField": - self._alias = alias - return self - - -class GeoJsonPropertiesGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GeoJsonPropertiesGraphQLField": - self._alias = alias - return self - - -class GqlDistributionTransformerConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlDistributionTransformerConfigGraphQLField": - self._alias = alias - return self - - -class GqlLoadConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlLoadConfigGraphQLField": - self._alias = alias - return self - - -class GqlScenarioConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlScenarioConfigGraphQLField": - self._alias = alias - return self - - -class GqlTxTapRecordGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlTxTapRecordGraphQLField": - self._alias = alias - return self - - -class GqlUserGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlUserGraphQLField": - self._alias = alias - return self - - -class GqlUserResponseGraphQLField(GraphQLField): - def alias(self, alias: str) -> "GqlUserResponseGraphQLField": - self._alias = alias - return self - - -class HcCalibrationGraphQLField(GraphQLField): - def alias(self, alias: str) -> "HcCalibrationGraphQLField": - self._alias = alias - return self - - -class HcModelGraphQLField(GraphQLField): - def alias(self, alias: str) -> "HcModelGraphQLField": - self._alias = alias - return self - - -class HcScenarioConfigsPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "HcScenarioConfigsPageGraphQLField": - self._alias = alias - return self - - -class HcWorkPackageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "HcWorkPackageGraphQLField": - self._alias = alias - return self - - -class HcWorkPackagePageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "HcWorkPackagePageGraphQLField": - self._alias = alias - return self - - -class IngestionJobGraphQLField(GraphQLField): - def alias(self, alias: str) -> "IngestionJobGraphQLField": - self._alias = alias - return self - - -class IngestionRunGraphQLField(GraphQLField): - def alias(self, alias: str) -> "IngestionRunGraphQLField": - self._alias = alias - return self - - -class IngestorRunPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "IngestorRunPageGraphQLField": - self._alias = alias - return self - - -class JobSourceGraphQLField(GraphQLField): - def alias(self, alias: str) -> "JobSourceGraphQLField": - self._alias = alias - return self - - -class MachineUserGraphQLField(GraphQLField): - def alias(self, alias: str) -> "MachineUserGraphQLField": - self._alias = alias - return self - - -class MetricGraphQLField(GraphQLField): - def alias(self, alias: str) -> "MetricGraphQLField": - self._alias = alias - return self - - -class NetworkModelGraphQLField(GraphQLField): - def alias(self, alias: str) -> "NetworkModelGraphQLField": - self._alias = alias - return self - - -class NetworkModelsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "NetworkModelsGraphQLField": - self._alias = alias - return self - - -class OpenDssModelGraphQLField(GraphQLField): - def alias(self, alias: str) -> "OpenDssModelGraphQLField": - self._alias = alias - return self - - -class OpenDssModelPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "OpenDssModelPageGraphQLField": - self._alias = alias - return self - - -class OpportunitiesByYearGraphQLField(GraphQLField): - def alias(self, alias: str) -> "OpportunitiesByYearGraphQLField": - self._alias = alias - return self - - -class OpportunityGraphQLField(GraphQLField): - def alias(self, alias: str) -> "OpportunityGraphQLField": - self._alias = alias - return self - - -class OpportunityLocationGraphQLField(GraphQLField): - def alias(self, alias: str) -> "OpportunityLocationGraphQLField": - self._alias = alias - return self - - -class PowerFactoryModelGraphQLField(GraphQLField): - def alias(self, alias: str) -> "PowerFactoryModelGraphQLField": - self._alias = alias - return self - - -class PowerFactoryModelGenerationSpecGraphQLField(GraphQLField): - def alias(self, alias: str) -> "PowerFactoryModelGenerationSpecGraphQLField": - self._alias = alias - return self - - -class PowerFactoryModelPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "PowerFactoryModelPageGraphQLField": - self._alias = alias - return self - - -class PowerFactoryModelTemplateGraphQLField(GraphQLField): - def alias(self, alias: str) -> "PowerFactoryModelTemplateGraphQLField": - self._alias = alias - return self - - -class PowerFactoryModelTemplatePageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "PowerFactoryModelTemplatePageGraphQLField": - self._alias = alias - return self - - -class ProcessedDiffGraphQLField(GraphQLField): - def alias(self, alias: str) -> "ProcessedDiffGraphQLField": - self._alias = alias - return self - - -class ProcessedDiffPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "ProcessedDiffPageGraphQLField": - self._alias = alias - return self - - -class RemoveAppOptionResultGraphQLField(GraphQLField): - def alias(self, alias: str) -> "RemoveAppOptionResultGraphQLField": - self._alias = alias - return self - - -class ResultSectionGraphQLField(GraphQLField): - def alias(self, alias: str) -> "ResultSectionGraphQLField": - self._alias = alias - return self - - -class ScenarioConfigurationGraphQLField(GraphQLField): - def alias(self, alias: str) -> "ScenarioConfigurationGraphQLField": - self._alias = alias - return self - - -class SincalConfigFileGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalConfigFileGraphQLField": - self._alias = alias - return self - - -class SincalGlobalInputsConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalGlobalInputsConfigGraphQLField": - self._alias = alias - return self - - -class SincalModelGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalModelGraphQLField": - self._alias = alias - return self - - -class SincalModelGenerationSpecGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalModelGenerationSpecGraphQLField": - self._alias = alias - return self - - -class SincalModelPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalModelPageGraphQLField": - self._alias = alias - return self - - -class SincalModelPresetGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalModelPresetGraphQLField": - self._alias = alias - return self - - -class SincalModelPresetPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "SincalModelPresetPageGraphQLField": - self._alias = alias - return self - - -class StateOverlayGraphQLField(GraphQLField): - def alias(self, alias: str) -> "StateOverlayGraphQLField": - self._alias = alias - return self - - -class StudyGraphQLField(GraphQLField): - def alias(self, alias: str) -> "StudyGraphQLField": - self._alias = alias - return self - - -class StudyPageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "StudyPageGraphQLField": - self._alias = alias - return self - - -class StudyResultGraphQLField(GraphQLField): - def alias(self, alias: str) -> "StudyResultGraphQLField": - self._alias = alias - return self - - -class TableSectionGraphQLField(GraphQLField): - def alias(self, alias: str) -> "TableSectionGraphQLField": - self._alias = alias - return self - - -class UploadUrlResponseGraphQLField(GraphQLField): - def alias(self, alias: str) -> "UploadUrlResponseGraphQLField": - self._alias = alias - return self - - -class UserCustomerListColumnConfigGraphQLField(GraphQLField): - def alias(self, alias: str) -> "UserCustomerListColumnConfigGraphQLField": - self._alias = alias - return self - - -class VariantGraphQLField(GraphQLField): - def alias(self, alias: str) -> "VariantGraphQLField": - self._alias = alias - return self - - -class VariantWorkPackageGraphQLField(GraphQLField): - def alias(self, alias: str) -> "VariantWorkPackageGraphQLField": - self._alias = alias - return self - - -class WorkPackageModelGroupingsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "WorkPackageModelGroupingsGraphQLField": - self._alias = alias - return self - - -class WorkPackageModelTotalsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "WorkPackageModelTotalsGraphQLField": - self._alias = alias - return self - - -class WorkPackageProgressDetailsGraphQLField(GraphQLField): - def alias(self, alias: str) -> "WorkPackageProgressDetailsGraphQLField": - self._alias = alias - return self - - -class WorkPackageTreeGraphQLField(GraphQLField): - def alias(self, alias: str) -> "WorkPackageTreeGraphQLField": - self._alias = alias - return self diff --git a/src/zepben/eas/lib/generated_graphql_client/enums.py b/src/zepben/eas/lib/generated_graphql_client/enums.py deleted file mode 100644 index c4e5a04..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/enums.py +++ /dev/null @@ -1,251 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from enum import Enum - - -class CandidateGenerationType(str, Enum): - CRITERIA = "CRITERIA" - TAP_OPTIMIZATION = "TAP_OPTIMIZATION" - - -class ColumnGroup(str, Enum): - PII = "PII" - NON_PII = "NON_PII" - - -class ColumnName(str, Enum): - ZONE_SUBSTATION = "ZONE_SUBSTATION" - FEEDER = "FEEDER" - TRANSFORMER_ID = "TRANSFORMER_ID" - TRANSFORMER_DESCRIPTION = "TRANSFORMER_DESCRIPTION" - METER_NUMBER = "METER_NUMBER" - SERVICE_ADDRESS = "SERVICE_ADDRESS" - SUPPLY_POINT_ID = "SUPPLY_POINT_ID" - NMI = "NMI" - LV_FEEDER = "LV_FEEDER" - MOBILE_NUMBER = "MOBILE_NUMBER" - PHONE_NUMBER = "PHONE_NUMBER" - POSTAL_ADDRESS = "POSTAL_ADDRESS" - TNI = "TNI" - DLF = "DLF" - FIRST_NAME = "FIRST_NAME" - LAST_NAME = "LAST_NAME" - CUSTOMER_TYPE = "CUSTOMER_TYPE" - IS_ENERGY_FEEDBACK = "IS_ENERGY_FEEDBACK" - IS_EMBEDDED_NETWORK = "IS_EMBEDDED_NETWORK" - DISTRIBUTOR = "DISTRIBUTOR" - SENSITIVITY_CATEGORY = "SENSITIVITY_CATEGORY" - MOVE_IN_DATE = "MOVE_IN_DATE" - NMI_CLASS = "NMI_CLASS" - SERVICE_PROVISION_STATUS = "SERVICE_PROVISION_STATUS" - TARIFF = "TARIFF" - - -class ContainerType(str, Enum): - TOTAL = "TOTAL" - GeographicalRegion = "GeographicalRegion" - SubGeographicalRegion = "SubGeographicalRegion" - SubstationTotal = "SubstationTotal" - Substation = "Substation" - FeederTotal = "FeederTotal" - Feeder = "Feeder" - LvFeeder = "LvFeeder" - - -class DaysRequired(str, Enum): - WEEKDAYS = "WEEKDAYS" - WEEKENDS = "WEEKENDS" - ANYDAYS = "ANYDAYS" - WEEKDAYSEXHOLIDAYS = "WEEKDAYSEXHOLIDAYS" - - -class DiffType(str, Enum): - NETWORK_PERFORMANCE_METRICS = "NETWORK_PERFORMANCE_METRICS" - NETWORK_PERFORMANCE_METRICS_ENHANCED = "NETWORK_PERFORMANCE_METRICS_ENHANCED" - - -class HcFeederScenarioAllocationStrategy(str, Enum): - RANDOM = "RANDOM" - ADDITIVE = "ADDITIVE" - - -class HcLoadPlacement(str, Enum): - PER_ENERGY_CONSUMER = "PER_ENERGY_CONSUMER" - PER_USAGE_POINT = "PER_USAGE_POINT" - - -class HcSolveMode(str, Enum): - YEARLY = "YEARLY" - DAILY = "DAILY" - - -class HcSwitchClass(str, Enum): - BREAKER = "BREAKER" - DISCONNECTOR = "DISCONNECTOR" - FUSE = "FUSE" - JUMPER = "JUMPER" - LOAD_BREAK_SWITCH = "LOAD_BREAK_SWITCH" - RECLOSER = "RECLOSER" - - -class HcWriterType(str, Enum): - POSTGRES = "POSTGRES" - PARQUET = "PARQUET" - - -class HostingCapacityFileType(str, Enum): - INPUT_DATABASE = "INPUT_DATABASE" - - -class IngestorRunState(str, Enum): - INITIALIZED = "INITIALIZED" - QUEUED = "QUEUED" - STARTED = "STARTED" - RUNNING = "RUNNING" - SUCCESS = "SUCCESS" - FAILURE = "FAILURE" - FAILED_TO_START = "FAILED_TO_START" - - -class IngestorRuntimeKind(str, Enum): - AZURE_CONTAINER_APP_JOB = "AZURE_CONTAINER_APP_JOB" - DOCKER = "DOCKER" - ECS = "ECS" - KUBERNETES = "KUBERNETES" - TEMPORAL_KUBERNETES = "TEMPORAL_KUBERNETES" - - -class InterventionClass(str, Enum): - TARIFF_REFORM = "TARIFF_REFORM" - CONTROLLED_LOAD_HOT_WATER = "CONTROLLED_LOAD_HOT_WATER" - COMMUNITY_BESS = "COMMUNITY_BESS" - DISTRIBUTION_TX_OLTC = "DISTRIBUTION_TX_OLTC" - LV_STATCOMS = "LV_STATCOMS" - DVMS = "DVMS" - PHASE_REBALANCING = "PHASE_REBALANCING" - DISTRIBUTION_TAP_OPTIMIZATION = "DISTRIBUTION_TAP_OPTIMIZATION" - UNKNOWN = "UNKNOWN" - - -class MeasurementZoneType(str, Enum): - UNKNOWN = "UNKNOWN" - TRANSFORMER = "TRANSFORMER" - BREAKER = "BREAKER" - DISCONNECTOR = "DISCONNECTOR" - FUSE = "FUSE" - JUMPER = "JUMPER" - LOAD_BREAK_SWITCH = "LOAD_BREAK_SWITCH" - RECLOSER = "RECLOSER" - ENERGY_CONSUMER = "ENERGY_CONSUMER" - FEEDER_HEAD = "FEEDER_HEAD" - CALIBRATION = "CALIBRATION" - - -class OpenDssModelState(str, Enum): - COULD_NOT_START = "COULD_NOT_START" - CREATION = "CREATION" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - - -class OpportunitiesNeed(str, Enum): - EXPORTDECREASE = "EXPORTDECREASE" - EXPORTINCREASE = "EXPORTINCREASE" - CONSUMPTIONDECREASE = "CONSUMPTIONDECREASE" - CONSUMPTIONINCREASE = "CONSUMPTIONINCREASE" - - -class OpportunitiesType(str, Enum): - CAPACITY = "CAPACITY" - VOLTAGESUPPORT = "VOLTAGESUPPORT" - - -class PowerFactoryModelState(str, Enum): - COULD_NOT_START = "COULD_NOT_START" - CREATION = "CREATION" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - - -class SectionType(str, Enum): - TABLE = "TABLE" - - -class SerializationType(str, Enum): - TABLE_JSON = "TABLE_JSON" - TABLE_CSV = "TABLE_CSV" - COMPRESSED_BYTES = "COMPRESSED_BYTES" - - -class SincalFileType(str, Enum): - TEMPLATE = "TEMPLATE" - IN_FEEDER_MAPPING_DATABASE = "IN_FEEDER_MAPPING_DATABASE" - LOCAL_STANDARD_DATABASE = "LOCAL_STANDARD_DATABASE" - PROTECTION_STANDARD_DATABASE = "PROTECTION_STANDARD_DATABASE" - FRONTEND_CONFIG = "FRONTEND_CONFIG" - BACKEND_CONFIG = "BACKEND_CONFIG" - - -class SincalModelState(str, Enum): - COULD_NOT_START = "COULD_NOT_START" - CREATION = "CREATION" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - PARTIAL = "PARTIAL" - - -class SortOrder(str, Enum): - ASC = "ASC" - DESC = "DESC" - ASC_NULLS_FIRST = "ASC_NULLS_FIRST" - DESC_NULLS_FIRST = "DESC_NULLS_FIRST" - ASC_NULLS_LAST = "ASC_NULLS_LAST" - DESC_NULLS_LAST = "DESC_NULLS_LAST" - - -class VariantFileType(str, Enum): - POWER_FACTORY_DGS = "POWER_FACTORY_DGS" - - -class VariantStatus(str, Enum): - Pending = "Pending" - Converting = "Converting" - AwaitingConflictDetection = "AwaitingConflictDetection" - ConflictDetection = "ConflictDetection" - ReadyForSubmission = "ReadyForSubmission" - Done = "Done" - Deleted = "Deleted" - Errored = "Errored" - - -class VariantWorkflowStatus(str, Enum): - Scheduled = "Scheduled" - Extracting = "Extracting" - Converting = "Converting" - ConflictDetection = "ConflictDetection" - WaitingForSubmission = "WaitingForSubmission" - Submitting = "Submitting" - Done = "Done" - Errored = "Errored" - - -class WorkPackageState(str, Enum): - SETUP = "SETUP" - PRRP = "PRRP" - RUNNING = "RUNNING" - SUCCEEDED = "SUCCEEDED" - FAILED = "FAILED" - CANCELLED = "CANCELLED" - TIMEDOUT = "TIMEDOUT" - - -class WorkflowStatus(str, Enum): - STARTED = "STARTED" - RUNNING = "RUNNING" - COMPLETED = "COMPLETED" - FAILED = "FAILED" diff --git a/src/zepben/eas/lib/generated_graphql_client/exceptions.py b/src/zepben/eas/lib/generated_graphql_client/exceptions.py deleted file mode 100644 index 1c24482..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/exceptions.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional, Union -import httpx - -class GraphQLClientError(Exception): - """Base exception.""" - -class GraphQLClientHttpError(GraphQLClientError): - - def __init__(self, status_code: int, response: httpx.Response) -> None: - self.status_code = status_code - self.response = response - - def __str__(self) -> str: - return f'HTTP status code: {self.status_code}' - -class GraphQLClientInvalidResponseError(GraphQLClientError): - - def __init__(self, response: httpx.Response) -> None: - self.response = response - - def __str__(self) -> str: - return 'Invalid response format.' - -class GraphQLClientGraphQLError(GraphQLClientError): - - def __init__(self, message: str, locations: Optional[list[dict[str, int]]]=None, path: Optional[list[str]]=None, extensions: Optional[dict[str, object]]=None, original: Optional[dict[str, object]]=None): - self.message = message - self.locations = locations - self.path = path - self.extensions = extensions - self.original = original - - def __str__(self) -> str: - return self.message - - @classmethod - def from_dict(cls, error: dict[str, Any]) -> 'GraphQLClientGraphQLError': - return cls(message=error['message'], locations=error.get('locations'), path=error.get('path'), extensions=error.get('extensions'), original=error) - -class GraphQLClientGraphQLMultiError(GraphQLClientError): - - def __init__(self, errors: list[GraphQLClientGraphQLError], data: Optional[dict[str, Any]]=None): - self.errors = errors - self.data = data - - def __str__(self) -> str: - return '; '.join((str(e) for e in self.errors)) - - @classmethod - def from_errors_dicts(cls, errors_dicts: list[dict[str, Any]], data: Optional[dict[str, Any]]=None) -> 'GraphQLClientGraphQLMultiError': - return cls(errors=[GraphQLClientGraphQLError.from_dict(e) for e in errors_dicts], data=data) - -class GraphQLClientInvalidMessageFormat(GraphQLClientError): - - def __init__(self, message: Union[str, bytes]) -> None: - self.message = message - - def __str__(self) -> str: - return 'Invalid message format.' \ No newline at end of file diff --git a/src/zepben/eas/lib/generated_graphql_client/input_types.py b/src/zepben/eas/lib/generated_graphql_client/input_types.py deleted file mode 100644 index 315159c..0000000 --- a/src/zepben/eas/lib/generated_graphql_client/input_types.py +++ /dev/null @@ -1,876 +0,0 @@ -# Copyright 2026 Zeppelin Bend Pty Ltd -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - - -from typing import Any, Optional - -from pydantic import Field - -from .base_model import BaseModel -from .enums import ( - CandidateGenerationType, - HcFeederScenarioAllocationStrategy, - HcLoadPlacement, - HcSolveMode, - HcSwitchClass, - HcWriterType, - IngestorRunState, - IngestorRuntimeKind, - InterventionClass, - OpenDssModelState, - PowerFactoryModelState, - SectionType, - SincalModelState, - SortOrder, -) - - -class AppOptionsInput(BaseModel): - """Input for updating application configuration options.""" - - asset_name_format: Optional[str] = Field(alias="assetNameFormat", default=None) - pole_string_format: Optional[str] = Field(alias="poleStringFormat", default=None) - - -class CandidateGenerationConfigInput(BaseModel): - average_voltage_spread_threshold: Optional[int] = Field( - alias="averageVoltageSpreadThreshold", default=None - ) - "The threshold for average line voltage spread under the transformer over the year, in volts. Voltage spread at each timestep is calculated by taking the difference between the maximum and minimum phase-to-phase voltage over the nodes under the transformer, for each phase, then taking the maximum of that difference across all phases. When the average voltage spread exceeds this threshold, it indicates that the transformer is experiencing a significant voltage swing that may impact system stability. Only used when `type` is `TAP_OPTIMIZATION`." - intervention_criteria_name: Optional[str] = Field( - alias="interventionCriteriaName", default=None - ) - "The ID of the set of criteria used to select intervention candidates from enhanced metrics of the base work package run. Only used when `type` is `CRITERIA`." - tap_weighting_factor_lower_threshold: Optional[float] = Field( - alias="tapWeightingFactorLowerThreshold", default=None - ) - "The minimum threshold for the tap weighting factor, used to determine when a positive tap adjustment (increasing voltage) is prioritized. If the tap weighting factor falls below this threshold, it indicates that the voltage is significantly under the desired range and requires corrective action. This setting is usually negative. Only used when `type` is `TAP_OPTIMIZATION`." - tap_weighting_factor_upper_threshold: Optional[float] = Field( - alias="tapWeightingFactorUpperThreshold", default=None - ) - "The maximum threshold for the tap weighting factor, used to determine when a negative tap adjustment (decreasing voltage) is prioritized. If the tap weighting factor exceeds this threshold, it indicates that the voltage is significantly over the desired range and requires corrective action. This setting is usually positive. Only used when `type` is `TAP_OPTIMIZATION`." - type_: CandidateGenerationType = Field(alias="type") - "The type of method for generating the intervention candidates." - voltage_over_limit_hours_threshold: Optional[int] = Field( - alias="voltageOverLimitHoursThreshold", default=None - ) - "The threshold for number of hours a transformer is above the nominal voltage range. Only used when `type` is `TAP_OPTIMIZATION`." - voltage_under_limit_hours_threshold: Optional[int] = Field( - alias="voltageUnderLimitHoursThreshold", default=None - ) - "The threshold for number of hours a transformer is below the nominal voltage range. Only used when `type` is `TAP_OPTIMIZATION`." - - -class DvmsConfigInput(BaseModel): - lower_limit: float = Field(alias="lowerLimit") - "The lower limit of voltage (p.u.) considered acceptable for the purposes of DVMS." - lower_percentile: float = Field(alias="lowerPercentile") - "The lowest percentile of customers' voltages to consider when applying DVMS." - max_iterations: int = Field(alias="maxIterations") - "The number of iterations to attempt DVMS for each timestep before moving on." - regulator_config: "DvmsRegulatorConfigInput" = Field(alias="regulatorConfig") - "Configures the voltage regulator to apply if the zone is already satisfactory according to the above limits." - upper_limit: float = Field(alias="upperLimit") - "The upper limit of voltage (p.u.) considered acceptable for the purposes of DVMS." - upper_percentile: float = Field(alias="upperPercentile") - "The highest percentile of customers' voltages to consider when applying DVMS." - - -class DvmsRegulatorConfigInput(BaseModel): - allow_push_to_limit: bool = Field(alias="allowPushToLimit") - "If this is true, we allow the regulator to push some number of customers outside the specified limits for DVMS, with the limit of customers given by lowerPercentile and upperPercentile in DvmsConfig." - max_tap_change_per_step: int = Field(alias="maxTapChangePerStep") - "The maximum number of tap steps to move (in either direction) for each timestep." - pu_deadband_percent: float = Field(alias="puDeadbandPercent") - "Width of window of voltages considered acceptable for the average customer voltage, in %p.u." - pu_target: float = Field(alias="puTarget") - "Voltage p.u. to move the average customer voltage towards." - - -class FeederConfigInput(BaseModel): - feeder: str - "The mRIDs of feeder to solve as part of this work package. Each feeder will be solved independently." - fixed_time: Optional["FixedTimeInput"] = Field(alias="fixedTime", default=None) - "Fixed Time setting for load retrieval, can not be set with time period setting." - scenarios: list[str] - "The IDs of scenarios to solve for." - time_period: Optional["TimePeriodInput"] = Field(alias="timePeriod", default=None) - "Time period setting for load retrieval, can not be set with fixed time setting." - years: list[int] - "The years to solve for. This is primarily used for fetching scenario data and calculating load growth." - - -class FeederConfigsInput(BaseModel): - configs: list["FeederConfigInput"] - "The mRIDs of feeders to solve for this work package. Each feeder will be solved independently." - - -class FeederLoadAnalysisInput(BaseModel): - aggregate_at_feeder_level: bool = Field(alias="aggregateAtFeederLevel") - "Request for a report which aggregate all downstream load at the feeder level" - end_date: str = Field(alias="endDate") - "End date for this analysis" - feeders: Optional[list[str]] = None - "The mRIDs of feeders to solve for feeder load analysis." - fetch_lv_network: bool = Field(alias="fetchLvNetwork") - "Whether to stop analysis at distribution transformer" - fla_forecast_config: Optional["FlaForecastConfigInput"] = Field( - alias="flaForecastConfig", default=None - ) - "Configuration for forecast FLA study" - geographical_regions: Optional[list[str]] = Field( - alias="geographicalRegions", default=None - ) - "The mRIDs of Geographical Region to solve for feeder load analysis." - output: Optional[str] = None - "The file name of the resulting study" - process_coincident_loads: bool = Field(alias="processCoincidentLoads") - "Whether to include values corresponding to conductor event time points in the report" - process_feeder_loads: bool = Field(alias="processFeederLoads") - "Whether to include values corresponding to feeder event time points in the report" - produce_conductor_report: bool = Field(alias="produceConductorReport") - "Request for an extensive report" - start_date: str = Field(alias="startDate") - "Start date for this analysis" - sub_geographical_regions: Optional[list[str]] = Field( - alias="subGeographicalRegions", default=None - ) - "The mRIDs of sub-Geographical Region to solve for feeder load analysis." - substations: Optional[list[str]] = None - "The mRIDs of substations to solve for feeder load analysis." - - -class FixedTimeInput(BaseModel): - load_time: Any = Field(alias="loadTime") - "The fixed time point to use for load retrieval." - overrides: Optional[list["FixedTimeLoadOverrideInput"]] = None - "The list of load override profiles." - - -class FixedTimeLoadOverrideInput(BaseModel): - gen_var_override: Optional[list[float]] = Field( - alias="genVarOverride", default=None - ) - gen_watts_override: Optional[list[float]] = Field( - alias="genWattsOverride", default=None - ) - load_id: str = Field(alias="loadId") - load_var_override: Optional[list[float]] = Field( - alias="loadVarOverride", default=None - ) - load_watts_override: Optional[list[float]] = Field( - alias="loadWattsOverride", default=None - ) - - -class FlaForecastConfigInput(BaseModel): - bess_upgrade_threshold: Optional[int] = Field( - alias="bessUpgradeThreshold", default=None - ) - "Watts threshold to indicate if a customer site will gain additional battery during scenario application" - pv_upgrade_threshold: Optional[int] = Field( - alias="pvUpgradeThreshold", default=None - ) - "Watts threshold to indicate if a customer site will gain additional pv during scenario application" - scenario_id: str = Field(alias="scenarioID") - "The id of forecast scenario" - seed: Optional[int] = None - "Seed for scenario application" - year: int - "The year for forecast model" - - -class ForecastConfigInput(BaseModel): - feeders: list[str] - "The mRIDs of feeders to solve for this work package. Each feeder will be solved independently." - fixed_time: Optional["FixedTimeInput"] = Field(alias="fixedTime", default=None) - "Fixed Time setting for load retrieval, can not be set with time period setting." - scenarios: list[str] - "The IDs of scenarios to solve for." - time_period: Optional["TimePeriodInput"] = Field(alias="timePeriod", default=None) - "Time period setting for load retrieval, can not be set with fixed time setting." - years: list[int] - "The years to solve for. This is primarily used for fetching scenario data and calculating load growth." - - -class GeoJsonOverlayInput(BaseModel): - data: Any - source_properties: Optional[Any] = Field(alias="sourceProperties", default=None) - styles: list[str] - - -class GetOpenDssModelsFilterInput(BaseModel): - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - state: Optional[list[OpenDssModelState]] = None - - -class GetOpenDssModelsSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - is_public: Optional[SortOrder] = Field(alias="isPublic", default=None) - name: Optional[SortOrder] = None - state: Optional[SortOrder] = None - - -class GetPowerFactoryModelTemplatesFilterInput(BaseModel): - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - - -class GetPowerFactoryModelTemplatesSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - is_public: Optional[SortOrder] = Field(alias="isPublic", default=None) - name: Optional[SortOrder] = None - - -class GetPowerFactoryModelsFilterInput(BaseModel): - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - state: Optional[list[PowerFactoryModelState]] = None - - -class GetPowerFactoryModelsSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - is_public: Optional[SortOrder] = Field(alias="isPublic", default=None) - name: Optional[SortOrder] = None - state: Optional[SortOrder] = None - - -class GetSincalModelPresetsFilterInput(BaseModel): - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - - -class GetSincalModelPresetsSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - is_public: Optional[SortOrder] = Field(alias="isPublic", default=None) - name: Optional[SortOrder] = None - - -class GetSincalModelsFilterInput(BaseModel): - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - state: Optional[list[SincalModelState]] = None - - -class GetSincalModelsSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - is_public: Optional[SortOrder] = Field(alias="isPublic", default=None) - name: Optional[SortOrder] = None - state: Optional[SortOrder] = None - - -class GetStudiesFilterInput(BaseModel): - created_after: Optional[Any] = Field(alias="createdAfter", default=None) - created_before: Optional[Any] = Field(alias="createdBefore", default=None) - created_by: Optional[list[str]] = Field(alias="createdBy", default=None) - id: Optional[str] = None - name: Optional[str] = None - tags: Optional[list[str]] = None - - -class GetStudiesSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - created_by: Optional[SortOrder] = Field(alias="createdBy", default=None) - description: Optional[SortOrder] = None - name: Optional[SortOrder] = None - - -class GqlDistributionTransformerConfigInput(BaseModel): - r_ground: float = Field(alias="rGround") - x_ground: float = Field(alias="xGround") - - -class GqlLoadConfigInput(BaseModel): - spread_max_demand: bool = Field(alias="spreadMaxDemand") - - -class GqlScenarioConfigInput(BaseModel): - bess_upgrade_threshold: int = Field(alias="bessUpgradeThreshold") - pv_upgrade_threshold: int = Field(alias="pvUpgradeThreshold") - scenario_id: str = Field(alias="scenarioID") - years: list[int] - - -class GqlSincalModelForecastSpecInput(BaseModel): - scenario_id: str = Field(alias="scenarioId") - year: int - - -class HcEnhancedMetricsConfigInput(BaseModel): - calculate_co_2: Optional[bool] = Field(alias="calculateCO2", default=None) - calculate_emerg_for_gen_thermal: Optional[bool] = Field( - alias="calculateEmergForGenThermal", default=None - ) - calculate_emerg_for_load_thermal: Optional[bool] = Field( - alias="calculateEmergForLoadThermal", default=None - ) - calculate_normal_for_gen_thermal: Optional[bool] = Field( - alias="calculateNormalForGenThermal", default=None - ) - calculate_normal_for_load_thermal: Optional[bool] = Field( - alias="calculateNormalForLoadThermal", default=None - ) - populate_constraints: Optional[bool] = Field( - alias="populateConstraints", default=None - ) - populate_duration_curves: Optional[bool] = Field( - alias="populateDurationCurves", default=None - ) - populate_enhanced_metrics: Optional[bool] = Field( - alias="populateEnhancedMetrics", default=None - ) - populate_enhanced_metrics_profile: Optional[bool] = Field( - alias="populateEnhancedMetricsProfile", default=None - ) - populate_weekly_reports: Optional[bool] = Field( - alias="populateWeeklyReports", default=None - ) - - -class HcExecutorConfigInput(BaseModel): - value: Optional[str] = None - "Placeholder parameter, currently ignored." - - -class HcGeneratorConfigInput(BaseModel): - model: Optional["HcModelConfigInput"] = None - node_level_results: Optional["HcNodeLevelResultsConfigInput"] = Field( - alias="nodeLevelResults", default=None - ) - raw_results: Optional["HcRawResultsConfigInput"] = Field( - alias="rawResults", default=None - ) - solve: Optional["HcSolveConfigInput"] = None - - -class HcInverterControlConfigInput(BaseModel): - after_cut_off_profile: Optional[str] = Field( - alias="afterCutOffProfile", default=None - ) - before_cut_off_profile: Optional[str] = Field( - alias="beforeCutOffProfile", default=None - ) - cut_off_date: Optional[Any] = Field(alias="cutOffDate", default=None) - - -class HcMeterPlacementConfigInput(BaseModel): - dist_transformers: Optional[bool] = Field(alias="distTransformers", default=None) - energy_consumer_meter_group: Optional[str] = Field( - alias="energyConsumerMeterGroup", default=None - ) - feeder_head: Optional[bool] = Field(alias="feederHead", default=None) - switch_meter_placement_configs: Optional[ - list["HcSwitchMeterPlacementConfigInput"] - ] = Field(alias="switchMeterPlacementConfigs", default=None) - - -class HcMetricsResultsConfigInput(BaseModel): - calculate_performance_metrics: Optional[bool] = Field( - alias="calculatePerformanceMetrics", default=None - ) - - -class HcModelConfigInput(BaseModel): - calibration: Optional[bool] = None - closed_loop_time_delay: Optional[int] = Field( - alias="closedLoopTimeDelay", default=None - ) - closed_loop_v_band: Optional[float] = Field(alias="closedLoopVBand", default=None) - closed_loop_v_limit: Optional[float] = Field(alias="closedLoopVLimit", default=None) - closed_loop_v_reg_enabled: Optional[bool] = Field( - alias="closedLoopVRegEnabled", default=None - ) - closed_loop_v_reg_replace_all: Optional[bool] = Field( - alias="closedLoopVRegReplaceAll", default=None - ) - closed_loop_v_reg_set_point: Optional[float] = Field( - alias="closedLoopVRegSetPoint", default=None - ) - collapse_lv_networks: Optional[bool] = Field( - alias="collapseLvNetworks", default=None - ) - collapse_negligible_impedances: Optional[bool] = Field( - alias="collapseNegligibleImpedances", default=None - ) - negligible_impedance_min_hv_threshold: Optional[float] = Field( - alias="negligibleImpedanceMinHvThreshold", default=None - ) - negligible_impedance_min_lv_threshold: Optional[float] = Field( - alias="negligibleImpedanceMinLvThreshold", default=None - ) - collapse_swer: Optional[bool] = Field(alias="collapseSWER", default=None) - combine_common_impedances: Optional[bool] = Field( - alias="combineCommonImpedances", default=None - ) - ct_prim_scaling_factor: Optional[float] = Field( - alias="ctPrimScalingFactor", default=None - ) - default_gen_var: Optional[list[float]] = Field(alias="defaultGenVar", default=None) - default_gen_watts: Optional[list[float]] = Field( - alias="defaultGenWatts", default=None - ) - default_load_var: Optional[list[float]] = Field( - alias="defaultLoadVar", default=None - ) - default_load_watts: Optional[list[float]] = Field( - alias="defaultLoadWatts", default=None - ) - default_tap_changer_band: Optional[float] = Field( - alias="defaultTapChangerBand", default=None - ) - default_tap_changer_set_point_pu: Optional[float] = Field( - alias="defaultTapChangerSetPointPu", default=None - ) - default_tap_changer_time_delay: Optional[int] = Field( - alias="defaultTapChangerTimeDelay", default=None - ) - emerg_amp_scaling: Optional[float] = Field(alias="emergAmpScaling", default=None) - feeder_scenario_allocation_strategy: Optional[ - HcFeederScenarioAllocationStrategy - ] = Field(alias="feederScenarioAllocationStrategy", default=None) - fix_overloading_consumers: Optional[bool] = Field( - alias="fixOverloadingConsumers", default=None - ) - fix_single_phase_loads: Optional[bool] = Field( - alias="fixSinglePhaseLoads", default=None - ) - fix_undersized_service_lines: Optional[bool] = Field( - alias="fixUndersizedServiceLines", default=None - ) - gen_v_max_pu: Optional[float] = Field(alias="genVMaxPu", default=None) - gen_v_min_pu: Optional[float] = Field(alias="genVMinPu", default=None) - inverter_control_config: Optional["HcInverterControlConfigInput"] = Field( - alias="inverterControlConfig", default=None - ) - load_interval_length_hours: Optional[float] = Field( - alias="loadIntervalLengthHours", default=None - ) - load_model: Optional[int] = Field(alias="loadModel", default=None) - load_placement: Optional[HcLoadPlacement] = Field( - alias="loadPlacement", default=None - ) - load_v_max_pu: Optional[float] = Field(alias="loadVMaxPu", default=None) - load_v_min_pu: Optional[float] = Field(alias="loadVMinPu", default=None) - max_gen_tx_ratio: Optional[float] = Field(alias="maxGenTxRatio", default=None) - max_load_lv_line_ratio: Optional[float] = Field( - alias="maxLoadLvLineRatio", default=None - ) - max_load_service_line_ratio: Optional[float] = Field( - alias="maxLoadServiceLineRatio", default=None - ) - max_load_tx_ratio: Optional[float] = Field(alias="maxLoadTxRatio", default=None) - max_single_phase_load: Optional[float] = Field( - alias="maxSinglePhaseLoad", default=None - ) - meter_placement_config: Optional["HcMeterPlacementConfigInput"] = Field( - alias="meterPlacementConfig", default=None - ) - p_factor_base_exports: Optional[float] = Field( - alias="pFactorBaseExports", default=None - ) - p_factor_base_imports: Optional[float] = Field( - alias="pFactorBaseImports", default=None - ) - p_factor_forecast_pv: Optional[float] = Field( - alias="pFactorForecastPv", default=None - ) - rating_threshold: Optional[float] = Field(alias="ratingThreshold", default=None) - seed: Optional[int] = None - simplify_network: Optional[bool] = Field(alias="simplifyNetwork", default=None) - simplify_plsi_threshold: Optional[float] = Field( - alias="simplifyPLSIThreshold", default=None - ) - split_phase_default_load_loss_percentage: Optional[float] = Field( - alias="splitPhaseDefaultLoadLossPercentage", default=None - ) - split_phase_lvkv: Optional[float] = Field(alias="splitPhaseLVKV", default=None) - swer_voltage_to_line_voltage: Optional[list[list[int]]] = Field( - alias="swerVoltageToLineVoltage", default=None - ) - transformer_tap_settings: Optional[str] = Field( - alias="transformerTapSettings", default=None - ) - use_span_level_threshold: Optional[bool] = Field( - alias="useSpanLevelThreshold", default=None - ) - vm_pu: Optional[float] = Field(alias="vmPu", default=None) - - -class HcNodeLevelResultsConfigInput(BaseModel): - collect_all_conductors: Optional[bool] = Field( - alias="collectAllConductors", default=None - ) - collect_all_energy_consumers: Optional[bool] = Field( - alias="collectAllEnergyConsumers", default=None - ) - collect_all_switches: Optional[bool] = Field( - alias="collectAllSwitches", default=None - ) - collect_all_transformers: Optional[bool] = Field( - alias="collectAllTransformers", default=None - ) - collect_current: Optional[bool] = Field(alias="collectCurrent", default=None) - collect_power: Optional[bool] = Field(alias="collectPower", default=None) - collect_voltage: Optional[bool] = Field(alias="collectVoltage", default=None) - mrids_to_collect: Optional[list[str]] = Field(alias="mridsToCollect", default=None) - - -class HcRawResultsConfigInput(BaseModel): - energy_meter_voltages_raw: Optional[bool] = Field( - alias="energyMeterVoltagesRaw", default=None - ) - energy_meters_raw: Optional[bool] = Field(alias="energyMetersRaw", default=None) - overloads_raw: Optional[bool] = Field(alias="overloadsRaw", default=None) - results_per_meter: Optional[bool] = Field(alias="resultsPerMeter", default=None) - voltage_exceptions_raw: Optional[bool] = Field( - alias="voltageExceptionsRaw", default=None - ) - - -class HcResultProcessorConfigInput(BaseModel): - metrics: Optional["HcMetricsResultsConfigInput"] = None - stored_results: Optional["HcStoredResultsConfigInput"] = Field( - alias="storedResults", default=None - ) - writer_config: Optional["HcWriterConfigInput"] = Field( - alias="writerConfig", default=None - ) - - -class HcScenarioConfigsFilterInput(BaseModel): - id: Optional[str] = None - "Search for scenario configurations by Id. Returns partial matches." - name: Optional[str] = None - "Search for scenario configurations by name. Returns partial matches." - - -class HcSolveConfigInput(BaseModel): - base_frequency: Optional[int] = Field(alias="baseFrequency", default=None) - emerg_v_max_pu: Optional[float] = Field(alias="emergVMaxPu", default=None) - emerg_v_min_pu: Optional[float] = Field(alias="emergVMinPu", default=None) - max_control_iter: Optional[int] = Field(alias="maxControlIter", default=None) - max_iter: Optional[int] = Field(alias="maxIter", default=None) - mode: Optional[HcSolveMode] = None - norm_v_max_pu: Optional[float] = Field(alias="normVMaxPu", default=None) - norm_v_min_pu: Optional[float] = Field(alias="normVMinPu", default=None) - step_size_minutes: Optional[int] = Field(alias="stepSizeMinutes", default=None) - voltage_bases: Optional[list[float]] = Field(alias="voltageBases", default=None) - - -class HcStoredResultsConfigInput(BaseModel): - energy_meter_voltages_raw: Optional[bool] = Field( - alias="energyMeterVoltagesRaw", default=None - ) - energy_meters_raw: Optional[bool] = Field(alias="energyMetersRaw", default=None) - overloads_raw: Optional[bool] = Field(alias="overloadsRaw", default=None) - voltage_exceptions_raw: Optional[bool] = Field( - alias="voltageExceptionsRaw", default=None - ) - - -class HcSwitchMeterPlacementConfigInput(BaseModel): - meter_switch_class: HcSwitchClass = Field(alias="meterSwitchClass") - name_pattern: str = Field(alias="namePattern") - - -class HcWorkPackagesFilterInput(BaseModel): - created_by: Optional[list[str]] = Field(alias="createdBy", default=None) - "Search for work package by the username or email of the User that created the work package." - id: Optional[str] = None - "Search for work package by Id." - name: Optional[str] = None - "Search for work package by name. Returns partial matches." - search_text: Optional[str] = Field(alias="searchText", default=None) - "Search for work package by user input text. Returns partial matches." - - -class HcWorkPackagesSortCriteriaInput(BaseModel): - created_at: Optional[SortOrder] = Field(alias="createdAt", default=None) - name: Optional[SortOrder] = None - - -class HcWriterConfigInput(BaseModel): - output_writer_config: Optional["HcWriterOutputConfigInput"] = Field( - alias="outputWriterConfig", default=None - ) - writer_type: Optional[HcWriterType] = Field(alias="writerType", default=None) - - -class HcWriterOutputConfigInput(BaseModel): - enhanced_metrics_config: Optional["HcEnhancedMetricsConfigInput"] = Field( - alias="enhancedMetricsConfig", default=None - ) - - -class IngestorConfigInput(BaseModel): - key: str - value: str - - -class IngestorRunsFilterInput(BaseModel): - """Include results based on filters. A logical AND is applied between the supplied filters""" - - completed: Optional[bool] = None - "Filter results by whether they are in a completed state or not." - container_runtime_type: Optional[list[IngestorRuntimeKind]] = Field( - alias="containerRuntimeType", default=None - ) - "Filter results by containerRunTimeType." - id: Optional[str] = None - "Filter results by Id." - status: Optional[list[IngestorRunState]] = None - "Filter results by the current status of the ingestor run." - - -class IngestorRunsSortCriteriaInput(BaseModel): - completed_at: Optional[SortOrder] = Field(alias="completedAt", default=None) - container_runtime_type: Optional[SortOrder] = Field( - alias="containerRuntimeType", default=None - ) - started_at: Optional[SortOrder] = Field(alias="startedAt", default=None) - status: Optional[SortOrder] = None - status_last_updated_at: Optional[SortOrder] = Field( - alias="statusLastUpdatedAt", default=None - ) - - -class InterventionConfigInput(BaseModel): - allocation_criteria: Optional[str] = Field(alias="allocationCriteria", default=None) - "The ID of the set of criteria used to select an intervention instance for each candidate." - allocation_limit_per_year: Optional[int] = Field( - alias="allocationLimitPerYear", default=None - ) - "The maximum number of interventions that can be applied per year. Defaults to 1 million." - base_work_package_id: str = Field(alias="baseWorkPackageId") - "ID of the work package that this intervention is based on. The new work package should process a subset of its feeders, scenarios, and years." - candidate_generation: Optional["CandidateGenerationConfigInput"] = Field( - alias="candidateGeneration", default=None - ) - "The method of generating candidates for the intervention. This does not need to be specified for certain interventions, e.g. PHASE_REBALANCING." - dvms: Optional["DvmsConfigInput"] = None - "The config for DVMS. This must be specified if interventionType = DVMS." - intervention_type: InterventionClass = Field(alias="interventionType") - "The class of intervention to apply." - phase_rebalance_proportions: Optional["PhaseRebalanceProportionsInput"] = Field( - alias="phaseRebalanceProportions", default=None - ) - "The proportions to use for phase rebalancing. If this is unspecified and interventionType = PHASE_REBALANCING, phases will be rebalanced to equal proportions." - specific_allocation_instance: Optional[str] = Field( - alias="specificAllocationInstance", default=None - ) - "The specific instance of intervention to use for every allocation. If this is unspecified, all instances of the intervention class will be considered when choosing one for each candidate." - year_range: Optional["YearRangeInput"] = Field(alias="yearRange", default=None) - "The range of years to search for and apply interventions. All years within this range should be included in the work package. Defaults to 1AD to 9999AD." - - -class OpenDssCommonConfigInput(BaseModel): - fixed_time: Optional["FixedTimeInput"] = Field(alias="fixedTime", default=None) - time_period: Optional["TimePeriodInput"] = Field(alias="timePeriod", default=None) - - -class OpenDssModelGenerationSpecInput(BaseModel): - model_options: "OpenDssModelOptionsInput" = Field(alias="modelOptions") - modules_configuration: "OpenDssModulesConfigInput" = Field( - alias="modulesConfiguration" - ) - - -class OpenDssModelInput(BaseModel): - generation_spec: "OpenDssModelGenerationSpecInput" = Field(alias="generationSpec") - is_public: Optional[bool] = Field(alias="isPublic", default=None) - model_name: Optional[str] = Field(alias="modelName", default=None) - - -class OpenDssModelOptionsInput(BaseModel): - feeder: str - scenario: str - year: int - - -class OpenDssModulesConfigInput(BaseModel): - common: "OpenDssCommonConfigInput" - generator: Optional["HcGeneratorConfigInput"] = None - - -class PhaseRebalanceProportionsInput(BaseModel): - a: float - b: float - c: float - - -class PowerFactoryModelGenerationSpecInput(BaseModel): - distribution_transformer_config: Optional[ - "GqlDistributionTransformerConfigInput" - ] = Field(alias="distributionTransformerConfig", default=None) - equipment_container_mrids: list[str] = Field(alias="equipmentContainerMrids") - load_config: Optional["GqlLoadConfigInput"] = Field( - alias="loadConfig", default=None - ) - model_name: Optional[str] = Field(alias="modelName", default=None) - scenario_config: Optional["GqlScenarioConfigInput"] = Field( - alias="scenarioConfig", default=None - ) - - -class PowerFactoryModelInput(BaseModel): - generation_spec: "PowerFactoryModelGenerationSpecInput" = Field( - alias="generationSpec" - ) - is_public: Optional[bool] = Field(alias="isPublic", default=None) - name: Optional[str] = None - - -class ProcessedDiffFilterInput(BaseModel): - type_: Optional[str] = Field(alias="type", default=None) - "Search for processed diffs by whether its network metrics or network metrics enhanced." - w_p_id: Optional[str] = Field(alias="wPId", default=None) - "Search for processed diffs by work package Id." - - -class ProcessedDiffSortCriteriaInput(BaseModel): - type_: Optional[SortOrder] = Field(alias="type", default=None) - work_packaged_id_1: Optional[SortOrder] = Field( - alias="workPackagedId1", default=None - ) - - -class ResultSectionInput(BaseModel): - columns: Any - data: Any - description: str - name: str - type_: SectionType = Field(alias="type") - - -class SincalModelGenerationSpecInput(BaseModel): - equipment_container_mrids: Optional[list[str]] = Field( - alias="equipmentContainerMrids", default=None - ) - forecast_spec: Optional["GqlSincalModelForecastSpecInput"] = Field( - alias="forecastSpec", default=None - ) - "Configuration for forecast models" - frontend_config: str = Field(alias="frontendConfig") - "JSON frontend export config." - - -class SincalModelInput(BaseModel): - generation_spec: "SincalModelGenerationSpecInput" = Field(alias="generationSpec") - is_public: Optional[bool] = Field(alias="isPublic", default=None) - model_name: Optional[str] = Field(alias="modelName", default=None) - - -class StateOverlayInput(BaseModel): - data: Any - styles: list[str] - - -class StudyInput(BaseModel): - description: str - name: str - results: list["StudyResultInput"] - styles: list[Any] - tags: list[str] - - -class StudyResultInput(BaseModel): - geo_json_overlay: Optional["GeoJsonOverlayInput"] = Field( - alias="geoJsonOverlay", default=None - ) - name: str - sections: list["ResultSectionInput"] - state_overlay: Optional["StateOverlayInput"] = Field( - alias="stateOverlay", default=None - ) - - -class TimePeriodInput(BaseModel): - end_time: Any = Field(alias="endTime") - "The ending time for load data retrieval." - overrides: Optional[list["TimePeriodLoadOverrideInput"]] = None - "The list of load override profiles." - start_time: Any = Field(alias="startTime") - "The starting time for load data retrieval." - - -class TimePeriodLoadOverrideInput(BaseModel): - gen_var_override: Optional[list[float]] = Field( - alias="genVarOverride", default=None - ) - gen_watts_override: Optional[list[float]] = Field( - alias="genWattsOverride", default=None - ) - load_id: str = Field(alias="loadId") - load_var_override: Optional[list[float]] = Field( - alias="loadVarOverride", default=None - ) - load_watts_override: Optional[list[float]] = Field( - alias="loadWattsOverride", default=None - ) - - -class WorkPackageInput(BaseModel): - executor_config: Optional["HcExecutorConfigInput"] = Field( - alias="executorConfig", default=None - ) - "Config exclusive to the OpenDSS executor." - feeder_configs: Optional["FeederConfigsInput"] = Field( - alias="feederConfigs", default=None - ) - "The list of feeder configurations for this work package, can not be set if forecast configurations exists." - forecast_config: Optional["ForecastConfigInput"] = Field( - alias="forecastConfig", default=None - ) - "The forecast configurations for this work package, can not be set if feeder configurations exists." - generator_config: Optional["HcGeneratorConfigInput"] = Field( - alias="generatorConfig", default=None - ) - "Config exclusive to the OpenDSS model generator." - intervention: Optional["InterventionConfigInput"] = None - "An optional intervention to use for this work package. Interventions are applied per feeder-scenario." - quality_assurance_processing: Optional[bool] = Field( - alias="qualityAssuranceProcessing", default=None - ) - "Fetch load from a single timestamp. This will result in a single timestamp of results." - result_processor_config: Optional["HcResultProcessorConfigInput"] = Field( - alias="resultProcessorConfig", default=None - ) - "Config exclusive to the result processor." - - -class YearRangeInput(BaseModel): - max_year: int = Field(alias="maxYear") - "The maximum year in this range (inclusive)" - min_year: int = Field(alias="minYear") - "The minimum year in this range (inclusive)" - - -DvmsConfigInput.model_rebuild() -FeederConfigInput.model_rebuild() -FeederConfigsInput.model_rebuild() -FeederLoadAnalysisInput.model_rebuild() -FixedTimeInput.model_rebuild() -ForecastConfigInput.model_rebuild() -HcGeneratorConfigInput.model_rebuild() -HcMeterPlacementConfigInput.model_rebuild() -HcModelConfigInput.model_rebuild() -HcResultProcessorConfigInput.model_rebuild() -HcWriterConfigInput.model_rebuild() -HcWriterOutputConfigInput.model_rebuild() -InterventionConfigInput.model_rebuild() -OpenDssCommonConfigInput.model_rebuild() -OpenDssModelGenerationSpecInput.model_rebuild() -OpenDssModelInput.model_rebuild() -OpenDssModulesConfigInput.model_rebuild() -PowerFactoryModelGenerationSpecInput.model_rebuild() -PowerFactoryModelInput.model_rebuild() -SincalModelGenerationSpecInput.model_rebuild() -SincalModelInput.model_rebuild() -StudyInput.model_rebuild() -StudyResultInput.model_rebuild() -TimePeriodInput.model_rebuild() -WorkPackageInput.model_rebuild() diff --git a/test/test_client_generation.py b/test/test_client_generation.py index d663d6b..4f7d447 100644 --- a/test/test_client_generation.py +++ b/test/test_client_generation.py @@ -6,10 +6,12 @@ import ast import pytest + @pytest.mark.skip("deleteme") @pytest.mark.asyncio async def test_do_things(): - from zepben.eas.lib.generated_graphql_client import custom_queries + from zepben.eas.lib import custom_queries + with open(custom_queries.__file__) as f: orig_ast = ast.parse( f.read(), @@ -24,25 +26,33 @@ async def test_do_things(): for func in b.body: if isinstance(func, ast.FunctionDef): func.body = [ast.Pass()] - extra_imports.append(func.returns.id.replace("Fields", "GraphQLField")) - func.returns = ast.Name(f'\"GraphQLQuery[{func.returns.id}, {func.returns.id.replace("Fields", "GraphQLField")}]\"') + extra_imports.append( + func.returns.id.replace("Fields", "GraphQLField") + ) + func.returns = ast.Name( + f'"GraphQLQuery[{func.returns.id}, {func.returns.id.replace("Fields", "GraphQLField")}]"' + ) - orig_ast.body.insert(n, ast.parse( - """ + orig_ast.body.insert( + n, + ast.parse( + """ class GraphQLQuery(Generic[TGraphQLQueryField, TGraphQLField]): def fields(self, *fields: TGraphQLField): ... """ - ).body[0]) - orig_ast.body.insert(n, ast.parse( - 'TGraphQLField = TypeVar("TGraphQLField")' - ).body[0]) - orig_ast.body.insert(n, ast.parse( - 'TGraphQLQueryField = TypeVar("TGraphQLQueryField")' - ).body[0]) + ).body[0], + ) + orig_ast.body.insert( + n, ast.parse('TGraphQLField = TypeVar("TGraphQLField")').body[0] + ) + orig_ast.body.insert( + n, ast.parse('TGraphQLQueryField = TypeVar("TGraphQLQueryField")').body[0] + ) orig_ast.body.insert(n, ast.parse("from typing import Generic, TypeVar").body[0]) - orig_ast.body.insert(n, ast.parse(f"from zepben.eas import {', '.join(extra_imports)}").body[0]) + orig_ast.body.insert( + n, ast.parse(f"from zepben.eas import {', '.join(extra_imports)}").body[0] + ) - with open(custom_queries.__file__ + 'i', 'w') as f: + with open(custom_queries.__file__ + "i", "w") as f: f.write(ast.unparse(orig_ast)) - diff --git a/test/test_eas_client.py b/test/test_eas_client.py index 24c4833..e6142ae 100644 --- a/test/test_eas_client.py +++ b/test/test_eas_client.py @@ -16,27 +16,62 @@ from pytest_httpserver import HTTPServer from werkzeug import Response -from zepben.eas import EasClient, OpenDssModelState, WorkPackageInput, ForecastConfigInput, TimePeriodInput, \ - FeederConfigInput, FeederConfigsInput, FixedTimeInput, FixedTimeLoadOverrideInput, TimePeriodLoadOverrideInput, \ - StudyInput, StudyResultInput, InterventionConfigInput, YearRangeInput, InterventionClass, \ - CandidateGenerationConfigInput, CandidateGenerationType, HcGeneratorConfigInput, HcModelConfigInput, \ - HcSolveConfigInput, GetOpenDssModelsFilterInput, GetOpenDssModelsSortCriteriaInput, SortOrder, IngestorConfigInput, \ - IngestorRunsFilterInput, IngestorRunState, IngestorRuntimeKind, IngestorRunsSortCriteriaInput, OpenDssModelInput, \ - OpenDssModelGenerationSpecInput, OpenDssModelOptionsInput, OpenDssModulesConfigInput, OpenDssCommonConfigInput, \ - HcFeederScenarioAllocationStrategy, HcLoadPlacement, HcMeterPlacementConfigInput, HcSwitchMeterPlacementConfigInput, \ - HcSwitchClass, HcInverterControlConfigInput, HcSolveMode, HcRawResultsConfigInput, HcNodeLevelResultsConfigInput - -mock_host = ''.join(random.choices(string.ascii_lowercase, k=10)) +from zepben.eas import ( + EasClient, + OpenDssModelState, + WorkPackageInput, + ForecastConfigInput, + TimePeriodInput, + FeederConfigInput, + FeederConfigsInput, + FixedTimeInput, + FixedTimeLoadOverrideInput, + TimePeriodLoadOverrideInput, + StudyInput, + StudyResultInput, + InterventionConfigInput, + YearRangeInput, + InterventionClass, + CandidateGenerationConfigInput, + CandidateGenerationType, + HcGeneratorConfigInput, + HcModelConfigInput, + HcSolveConfigInput, + GetOpenDssModelsFilterInput, + GetOpenDssModelsSortCriteriaInput, + SortOrder, + IngestorConfigInput, + IngestorRunsFilterInput, + IngestorRunState, + IngestorRuntimeKind, + IngestorRunsSortCriteriaInput, + OpenDssModelInput, + OpenDssModelGenerationSpecInput, + OpenDssModelOptionsInput, + OpenDssModulesConfigInput, + OpenDssCommonConfigInput, + HcFeederScenarioAllocationStrategy, + HcLoadPlacement, + HcMeterPlacementConfigInput, + HcSwitchMeterPlacementConfigInput, + HcSwitchClass, + HcInverterControlConfigInput, + HcSolveMode, + HcRawResultsConfigInput, + HcNodeLevelResultsConfigInput, +) + +mock_host = "".join(random.choices(string.ascii_lowercase, k=10)) mock_port = random.randrange(1024) -mock_client_id = ''.join(random.choices(string.ascii_lowercase, k=10)) -mock_client_secret = ''.join(random.choices(string.ascii_lowercase, k=10)) -mock_username = ''.join(random.choices(string.ascii_lowercase, k=10)) -mock_password = ''.join(random.choices(string.ascii_lowercase, k=10)) -mock_protocol = ''.join(random.choices(string.ascii_lowercase, k=10)) -mock_access_token = ''.join(random.choices(string.ascii_lowercase, k=10)) +mock_client_id = "".join(random.choices(string.ascii_lowercase, k=10)) +mock_client_secret = "".join(random.choices(string.ascii_lowercase, k=10)) +mock_username = "".join(random.choices(string.ascii_lowercase, k=10)) +mock_password = "".join(random.choices(string.ascii_lowercase, k=10)) +mock_protocol = "".join(random.choices(string.ascii_lowercase, k=10)) +mock_access_token = "".join(random.choices(string.ascii_lowercase, k=10)) mock_verify_certificate = bool(random.getrandbits(1)) -mock_audience = ''.join(random.choices(string.ascii_lowercase, k=10)) +mock_audience = "".join(random.choices(string.ascii_lowercase, k=10)) LOCALHOST = "127.0.0.1" @@ -60,7 +95,7 @@ def test_create_eas_client_success(): host=mock_host, port=mock_port, protocol=mock_protocol, - verify_certificate=mock_verify_certificate + verify_certificate=mock_verify_certificate, ) assert eas_client is not None @@ -111,10 +146,11 @@ def test_get_work_package_cost_estimation_no_verify_success(httpserver: HTTPServ ) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"getWorkPackageCostEstimation": "123.45"}}) + {"data": {"getWorkPackageCostEstimation": "123.45"}} + ) res = eas_client.get_work_package_cost_estimation( WorkPackageInput( - #"wp_name", + # "wp_name", forecastConfig=ForecastConfigInput( feeders=["feeder"], years=[1], @@ -122,8 +158,8 @@ def test_get_work_package_cost_estimation_no_verify_success(httpserver: HTTPServ timePeriod=TimePeriodInput( startTime=datetime(2022, 1, 1, 10), endTime=datetime(2022, 1, 2, 12), - overrides=None - ) + overrides=None, + ), ) ) ) @@ -131,11 +167,14 @@ def test_get_work_package_cost_estimation_no_verify_success(httpserver: HTTPServ assert res == {"data": {"getWorkPackageCostEstimation": "123.45"}} -def test_get_work_package_cost_estimation_invalid_certificate_failure(httpserver: HTTPServer): +def test_get_work_package_cost_estimation_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"getWorkPackageCostEstimation": "123.45"}}) + {"data": {"getWorkPackageCostEstimation": "123.45"}} + ) with pytest.raises(httpx.ConnectError): eas_client.get_work_package_cost_estimation( WorkPackageInput( @@ -146,18 +185,21 @@ def test_get_work_package_cost_estimation_invalid_certificate_failure(httpserver timePeriod=TimePeriodInput( startTime=datetime(2022, 1, 1, 10), endTime=datetime(2022, 1, 2, 12), - overrides=None - ) + overrides=None, + ), ) ) ) -def test_get_work_package_cost_estimation_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_get_work_package_cost_estimation_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"getWorkPackageCostEstimation": "123.45"}}) + {"data": {"getWorkPackageCostEstimation": "123.45"}} + ) res = eas_client.get_work_package_cost_estimation( WorkPackageInput( feederConfigs=FeederConfigsInput( @@ -174,10 +216,10 @@ def test_get_work_package_cost_estimation_valid_certificate_success(httpserver: genVarOverride=[1], genWattsOverride=[2], loadVarOverride=[3], - loadWattsOverride=[4] + loadWattsOverride=[4], ) - ] - ) + ], + ), ) ] ) @@ -196,7 +238,9 @@ def test_run_hosting_capacity_work_package_no_verify_success(httpserver: HTTPSer enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"data": {"runWorkPackage": "workPackageId"}}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"data": {"runWorkPackage": "workPackageId"}} + ) res = eas_client.run_hosting_capacity_work_package( WorkPackageInput( forecastConfig=ForecastConfigInput( @@ -206,20 +250,24 @@ def test_run_hosting_capacity_work_package_no_verify_success(httpserver: HTTPSer timePeriod=TimePeriodInput( startTime=datetime(2022, 1, 1), endTime=datetime(2022, 1, 2), - overrides=None - ) + overrides=None, + ), ) - ), work_package_name="wp_name", + ), + work_package_name="wp_name", ) httpserver.check_assertions() assert res == {"data": {"runWorkPackage": "workPackageId"}} -def test_run_hosting_capacity_work_package_invalid_certificate_failure(httpserver: HTTPServer): +def test_run_hosting_capacity_work_package_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"runWorkPackage": "workPackageId"}}) + {"data": {"runWorkPackage": "workPackageId"}} + ) with pytest.raises(httpx.ConnectError): eas_client.run_hosting_capacity_work_package( WorkPackageInput( @@ -230,18 +278,22 @@ def test_run_hosting_capacity_work_package_invalid_certificate_failure(httpserve timePeriod=TimePeriodInput( startTime=datetime(2022, 1, 1), endTime=datetime(2022, 1, 2), - overrides=None - ) + overrides=None, + ), ) - ), work_package_name="wp_name", + ), + work_package_name="wp_name", ) -def test_run_hosting_capacity_work_package_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_run_hosting_capacity_work_package_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"runWorkPackage": "workPackageId"}}) + {"data": {"runWorkPackage": "workPackageId"}} + ) res = eas_client.run_hosting_capacity_work_package( WorkPackageInput( forecastConfig=ForecastConfigInput( @@ -257,12 +309,13 @@ def test_run_hosting_capacity_work_package_valid_certificate_success(httpserver: loadWattsOverride=[1.0], genWattsOverride=[2.0], loadVarOverride=[3.0], - genVarOverride=[4.0] + genVarOverride=[4.0], ) - ] - ) + ], + ), ) - ), work_package_name="wp_name", + ), + work_package_name="wp_name", ) httpserver.check_assertions() assert res == {"data": {"runWorkPackage": "workPackageId"}} @@ -279,31 +332,41 @@ def test_cancel_hosting_capacity_work_package_no_verify_success(httpserver: HTTP httpserver.expect_oneshot_request("/api/graphql").respond_with_json( {"data": {"cancelHostingCapacity": "workPackageId"}} ) - res = eas_client.cancel_hosting_capacity_work_package(work_package_id="workPackageId") + res = eas_client.cancel_hosting_capacity_work_package( + work_package_id="workPackageId" + ) httpserver.check_assertions() assert res == {"data": {"cancelHostingCapacity": "workPackageId"}} -def test_cancel_hosting_capacity_work_package_invalid_certificate_failure(httpserver: HTTPServer): +def test_cancel_hosting_capacity_work_package_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"cancelWorkPackage": "workPackageId"}}) + {"data": {"cancelWorkPackage": "workPackageId"}} + ) with pytest.raises(httpx.ConnectError): eas_client.cancel_hosting_capacity_work_package("workPackageId") -def test_cancel_hosting_capacity_work_package_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_cancel_hosting_capacity_work_package_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"cancelWorkPackage": "workPackageId"}}) + {"data": {"cancelWorkPackage": "workPackageId"}} + ) res = eas_client.cancel_hosting_capacity_work_package("workPackageId") httpserver.check_assertions() assert res == {"data": {"cancelWorkPackage": "workPackageId"}} -def test_get_hosting_capacity_work_package_progress_no_verify_success(httpserver: HTTPServer): +def test_get_hosting_capacity_work_package_progress_no_verify_success( + httpserver: HTTPServer, +): eas_client = EasClient( host=LOCALHOST, port=httpserver.port, @@ -319,20 +382,26 @@ def test_get_hosting_capacity_work_package_progress_no_verify_success(httpserver assert res == {"data": {"getWorkPackageProgress": {}}} -def test_get_hosting_capacity_work_package_progress_invalid_certificate_failure(httpserver: HTTPServer): +def test_get_hosting_capacity_work_package_progress_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"getWorkPackageProgress": {}}}) + {"data": {"getWorkPackageProgress": {}}} + ) with pytest.raises(httpx.ConnectError): eas_client.get_hosting_capacity_work_packages_progress() -def test_get_hosting_capacity_work_package_progress_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_get_hosting_capacity_work_package_progress_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_json( - {"data": {"getWorkPackageProgress": {}}}) + {"data": {"getWorkPackageProgress": {}}} + ) res = eas_client.get_hosting_capacity_work_packages_progress() httpserver.check_assertions() assert res == {"data": {"getWorkPackageProgress": {}}} @@ -346,14 +415,16 @@ def test_upload_study_no_verify_success(httpserver: HTTPServer): enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) res = eas_client.upload_study( StudyInput( name="Test study", description="description", tags=["tag"], results=[StudyResultInput(name="Huge success", sections=[])], - styles=[] + styles=[], ) ) httpserver.check_assertions() @@ -363,30 +434,56 @@ def test_upload_study_no_verify_success(httpserver: HTTPServer): def test_upload_study_invalid_certificate_failure(httpserver: HTTPServer): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) with pytest.raises(httpx.ConnectError): - eas_client.upload_study(StudyInput(name="Test study", description="description", tags=["tag"], results=[StudyResultInput(name="Huge success", sections=[])], styles=[])) + eas_client.upload_study( + StudyInput( + name="Test study", + description="description", + tags=["tag"], + results=[StudyResultInput(name="Huge success", sections=[])], + styles=[], + ) + ) def test_upload_study_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): eas_client = _valid_ca(httpserver.port, ca) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) - res = eas_client.upload_study(StudyInput(name="Test study", description="description", tags=["tag"], results=[StudyResultInput(name="Huge success", sections=[])], styles=[])) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) + res = eas_client.upload_study( + StudyInput( + name="Test study", + description="description", + tags=["tag"], + results=[StudyResultInput(name="Huge success", sections=[])], + styles=[], + ) + ) httpserver.check_assertions() assert res == {"result": "success"} def hosting_capacity_run_calibration_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 ) }" - assert actual_body['variables'] == {"calibrationName_0": "TEST CALIBRATION", - "calibrationTimeLocal_0": datetime(2025, month=7, day=12).isoformat(), - } + assert ( + query + == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 ) }" + ) + assert actual_body["variables"] == { + "calibrationName_0": "TEST CALIBRATION", + "calibrationTimeLocal_0": datetime(2025, month=7, day=12).isoformat(), + } - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_run_hosting_capacity_calibration_no_verify_success(httpserver: HTTPServer): @@ -398,40 +495,58 @@ def test_run_hosting_capacity_calibration_no_verify_success(httpserver: HTTPServ ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", datetime(2025, month=7, day=12)) + hosting_capacity_run_calibration_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", datetime(2025, month=7, day=12) + ) httpserver.check_assertions() assert res == {"result": "success"} -def test_run_hosting_capacity_calibration_invalid_certificate_failure(httpserver: HTTPServer): +def test_run_hosting_capacity_calibration_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) with pytest.raises(httpx.ConnectError): - eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", datetime(2025, month=7, day=12)) + eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", datetime(2025, month=7, day=12) + ) -def test_run_hosting_capacity_calibration_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_run_hosting_capacity_calibration_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", datetime(2025, month=7, day=12)) + hosting_capacity_run_calibration_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", datetime(2025, month=7, day=12) + ) httpserver.check_assertions() assert res == {"result": "success"} def get_hosting_capacity_run_calibration_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == ("query getCalibrationRun($id_0: ID!) { getCalibrationRun(id: $id_0) { id name " - "workflowId runId calibrationTimeLocal startAt completedAt status feeders " - "calibrationWorkPackageConfig } }") - assert actual_body['variables'] == {"id_0": "calibration-id"} + assert query == ( + "query getCalibrationRun($id_0: ID!) { getCalibrationRun(id: $id_0) { id name " + "workflowId runId calibrationTimeLocal startAt completedAt status feeders " + "calibrationWorkPackageConfig } }" + ) + assert actual_body["variables"] == {"id_0": "calibration-id"} - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_get_hosting_capacity_calibration_run_no_verify_success(httpserver: HTTPServer): @@ -443,25 +558,33 @@ def test_get_hosting_capacity_calibration_run_no_verify_success(httpserver: HTTP ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_hosting_capacity_run_calibration_request_handler) + get_hosting_capacity_run_calibration_request_handler + ) res = eas_client.get_hosting_capacity_calibration_run("calibration-id") httpserver.check_assertions() assert res == {"result": "success"} -def test_get_hosting_capacity_calibration_run_invalid_certificate_failure(httpserver: HTTPServer): +def test_get_hosting_capacity_calibration_run_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) with pytest.raises(httpx.ConnectError): eas_client.get_hosting_capacity_calibration_run("calibration-id") -def test_get_hosting_capacity_calibration_run_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_get_hosting_capacity_calibration_run_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_hosting_capacity_run_calibration_request_handler) + get_hosting_capacity_run_calibration_request_handler + ) res = eas_client.get_hosting_capacity_calibration_run("calibration-id") httpserver.check_assertions() assert res == {"result": "success"} @@ -469,24 +592,31 @@ def test_get_hosting_capacity_calibration_run_valid_certificate_success(httpserv def hosting_capacity_run_calibration_with_calibration_time_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) - - assert query == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" - assert actual_body['variables'] == {"calibrationName_0": "TEST CALIBRATION", - "calibrationTimeLocal_0": datetime(1902, month=1, day=28, hour=0, minute=0, - second=20).isoformat(), - "feeders_0": ["one", "two"], - "generatorConfig_0": { - 'model': { - 'transformerTapSettings': 'test_tap_settings' - }, - } - } + query = " ".join(actual_body["query"].split()) - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + assert ( + query + == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" + ) + assert actual_body["variables"] == { + "calibrationName_0": "TEST CALIBRATION", + "calibrationTimeLocal_0": datetime( + 1902, month=1, day=28, hour=0, minute=0, second=20 + ).isoformat(), + "feeders_0": ["one", "two"], + "generatorConfig_0": { + "model": {"transformerTapSettings": "test_tap_settings"}, + }, + } + + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) -def test_run_hosting_capacity_calibration_with_calibration_time_no_verify_success(httpserver: HTTPServer): +def test_run_hosting_capacity_calibration_with_calibration_time_no_verify_success( + httpserver: HTTPServer, +): eas_client = EasClient( host=LOCALHOST, port=httpserver.port, @@ -495,20 +625,22 @@ def test_run_hosting_capacity_calibration_with_calibration_time_no_verify_succes ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_with_calibration_time_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", - datetime(1902, month=1, day=28, hour=0, minute=0, second=20), - ["one", "two"], - generator_config=HcGeneratorConfigInput(model=HcModelConfigInput( - transformerTapSettings="test_tap_settings" - )) - ) + hosting_capacity_run_calibration_with_calibration_time_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", + datetime(1902, month=1, day=28, hour=0, minute=0, second=20), + ["one", "two"], + generator_config=HcGeneratorConfigInput( + model=HcModelConfigInput(transformerTapSettings="test_tap_settings") + ), + ) httpserver.check_assertions() assert res == {"result": "success"} def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings_no_generator_config( - httpserver: HTTPServer + httpserver: HTTPServer, ): eas_client = EasClient( host=LOCALHOST, @@ -518,40 +650,49 @@ def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_with_calibration_time_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", - datetime(1902, month=1, day=28, hour=0, minute=0, second=20), - ["one", "two"], - transformer_tap_settings="test_tap_settings" - ) + hosting_capacity_run_calibration_with_calibration_time_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", + datetime(1902, month=1, day=28, hour=0, minute=0, second=20), + ["one", "two"], + transformer_tap_settings="test_tap_settings", + ) httpserver.check_assertions() assert res == {"result": "success"} def hosting_capacity_run_calibration_with_generator_config_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) - - assert query == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" - assert actual_body['variables'] == {"calibrationName_0": "TEST CALIBRATION", - "calibrationTimeLocal_0": datetime(1902, month=1, day=28, hour=0, minute=0, - second=20).isoformat(), - "feeders_0": ["one", "two"], - "generatorConfig_0": { - 'model': { - 'transformerTapSettings': 'test_tap_settings', - }, - 'solve': { - 'normVMaxPu': 23.9, - } - } - } - - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + query = " ".join(actual_body["query"].split()) + + assert ( + query + == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" + ) + assert actual_body["variables"] == { + "calibrationName_0": "TEST CALIBRATION", + "calibrationTimeLocal_0": datetime( + 1902, month=1, day=28, hour=0, minute=0, second=20 + ).isoformat(), + "feeders_0": ["one", "two"], + "generatorConfig_0": { + "model": { + "transformerTapSettings": "test_tap_settings", + }, + "solve": { + "normVMaxPu": 23.9, + }, + }, + } + + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings_partial_generator_config( - httpserver: HTTPServer + httpserver: HTTPServer, ): eas_client = EasClient( host=LOCALHOST, @@ -561,40 +702,47 @@ def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_with_generator_config_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", - datetime(1902, month=1, day=28, hour=0, minute=0, second=20), - ["one", "two"], - transformer_tap_settings="test_tap_settings", - generator_config=HcGeneratorConfigInput( - solve=HcSolveConfigInput(normVMaxPu=23.9)) - ) + hosting_capacity_run_calibration_with_generator_config_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", + datetime(1902, month=1, day=28, hour=0, minute=0, second=20), + ["one", "two"], + transformer_tap_settings="test_tap_settings", + generator_config=HcGeneratorConfigInput( + solve=HcSolveConfigInput(normVMaxPu=23.9) + ), + ) httpserver.check_assertions() assert res == {"result": "success"} def hosting_capacity_run_calibration_with_partial_model_config_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" - assert actual_body['variables'] == {"calibrationName_0": "TEST CALIBRATION", - "calibrationTimeLocal_0": datetime(1902, month=1, day=28, hour=0, minute=0, - second=20).isoformat(), - "feeders_0": ["one", "two"], - "generatorConfig_0": { - 'model': { - 'transformerTapSettings': 'test_tap_settings', - 'vmPu': 123.4 - }, - } - } + assert ( + query + == "mutation runCalibration($calibrationName_0: String!, $calibrationTimeLocal_0: LocalDateTime, $feeders_0: [String!], $generatorConfig_0: HcGeneratorConfigInput) { runCalibration( calibrationName: $calibrationName_0 calibrationTimeLocal: $calibrationTimeLocal_0 feeders: $feeders_0 generatorConfig: $generatorConfig_0 ) }" + ) + assert actual_body["variables"] == { + "calibrationName_0": "TEST CALIBRATION", + "calibrationTimeLocal_0": datetime( + 1902, month=1, day=28, hour=0, minute=0, second=20 + ).isoformat(), + "feeders_0": ["one", "two"], + "generatorConfig_0": { + "model": {"transformerTapSettings": "test_tap_settings", "vmPu": 123.4}, + }, + } - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings_partial_model_config( - httpserver: HTTPServer + httpserver: HTTPServer, ): eas_client = EasClient( host=LOCALHOST, @@ -604,18 +752,22 @@ def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_with_partial_model_config_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", - datetime(1902, month=1, day=28, hour=0, minute=0, second=20), - ["one", "two"], - transformer_tap_settings="test_tap_settings", - generator_config=HcGeneratorConfigInput(model=HcModelConfigInput(vmPu=123.4)) - ) + hosting_capacity_run_calibration_with_partial_model_config_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", + datetime(1902, month=1, day=28, hour=0, minute=0, second=20), + ["one", "two"], + transformer_tap_settings="test_tap_settings", + generator_config=HcGeneratorConfigInput(model=HcModelConfigInput(vmPu=123.4)), + ) httpserver.check_assertions() assert res == {"result": "success"} -def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings(httpserver: HTTPServer): +def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings( + httpserver: HTTPServer, +): eas_client = EasClient( host=LOCALHOST, port=httpserver.port, @@ -624,29 +776,37 @@ def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - hosting_capacity_run_calibration_with_calibration_time_request_handler) - res = eas_client.run_hosting_capacity_calibration("TEST CALIBRATION", - datetime(1902, month=1, day=28, hour=0, minute=0, second=20), - ["one", "two"], - transformer_tap_settings="test_tap_settings", - generator_config=HcGeneratorConfigInput(model=HcModelConfigInput( - transformerTapSettings="this_should_be_over_written" - )) - ) + hosting_capacity_run_calibration_with_calibration_time_request_handler + ) + res = eas_client.run_hosting_capacity_calibration( + "TEST CALIBRATION", + datetime(1902, month=1, day=28, hour=0, minute=0, second=20), + ["one", "two"], + transformer_tap_settings="test_tap_settings", + generator_config=HcGeneratorConfigInput( + model=HcModelConfigInput( + transformerTapSettings="this_should_be_over_written" + ) + ), + ) httpserver.check_assertions() assert res == {"result": "success"} def get_hosting_capacity_calibration_sets_request_handler(request): actual_body = json.loads(request.data.decode()) - query = actual_body['query'].replace('\n', '') + query = actual_body["query"].replace("\n", "") assert query == "query getCalibrationSets { getCalibrationSets}" - return Response(json.dumps(["one", "two", "three"]), status=200, content_type="application/json") + return Response( + json.dumps(["one", "two", "three"]), status=200, content_type="application/json" + ) -def test_get_hosting_capacity_calibration_sets_no_verify_success(httpserver: HTTPServer): +def test_get_hosting_capacity_calibration_sets_no_verify_success( + httpserver: HTTPServer, +): eas_client = EasClient( host=LOCALHOST, port=httpserver.port, @@ -655,7 +815,8 @@ def test_get_hosting_capacity_calibration_sets_no_verify_success(httpserver: HTT ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_hosting_capacity_calibration_sets_request_handler) + get_hosting_capacity_calibration_sets_request_handler + ) res = eas_client.get_hosting_capacity_calibration_sets() httpserver.check_assertions() assert res == ["one", "two", "three"] @@ -663,10 +824,13 @@ def test_get_hosting_capacity_calibration_sets_no_verify_success(httpserver: HTT def run_opendss_export_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == "mutation createOpenDssModel($input_0: OpenDssModelInput!) { createOpenDssModel(input: $input_0) }" - assert actual_body['variables'] == { + assert ( + query + == "mutation createOpenDssModel($input_0: OpenDssModelInput!) { createOpenDssModel(input: $input_0) }" + ) + assert actual_body["variables"] == { "input_0": { "modelName": "TEST OPENDSS MODEL 1", "isPublic": True, @@ -674,31 +838,35 @@ def run_opendss_export_request_handler(request): "modelOptions": { "feeder": "feeder1", "scenario": "scenario1", - "year": 2024 + "year": 2024, }, "modulesConfiguration": { "common": { "fixedTime": { "loadTime": "2022-04-01T00:00:00", - "overrides": [{ - 'loadId': 'meter1', - 'loadWattsOverride': [4.0], - 'genWattsOverride': [2.0], - 'loadVarOverride': [3.0], - 'genVarOverride': [1.0] - }] + "overrides": [ + { + "loadId": "meter1", + "loadWattsOverride": [4.0], + "genWattsOverride": [2.0], + "loadVarOverride": [3.0], + "genVarOverride": [1.0], + } + ], }, "timePeriod": { - "startTime": "2022-04-01T10:13:00", - "endTime": "2023-04-01T12:14:00", - "overrides": [{ - 'loadId': 'meter1', - 'loadWattsOverride': [4.0], - 'genWattsOverride': [2.0], - 'loadVarOverride': [3.0], - 'genVarOverride': [1.0] - }] - } + "startTime": "2022-04-01T10:13:00", + "endTime": "2023-04-01T12:14:00", + "overrides": [ + { + "loadId": "meter1", + "loadWattsOverride": [4.0], + "genWattsOverride": [2.0], + "loadVarOverride": [3.0], + "genVarOverride": [1.0], + } + ], + }, }, "generator": { "model": { @@ -724,8 +892,6 @@ def run_opendss_export_request_handler(request): "simplifyNetwork": False, "collapseLvNetworks": False, "collapseNegligibleImpedances": False, - "negligibleImpedanceMinHvThreshold": 0.12, - "negligibleImpedanceMinLvThreshold": 0.34, "combineCommonImpedances": False, "feederScenarioAllocationStrategy": "ADDITIVE", "closedLoopVRegEnabled": True, @@ -746,7 +912,7 @@ def run_opendss_export_request_handler(request): [6350, 11000], [6400, 11000], [12700, 22000], - [19100, 33000] + [19100, 33000], ], "loadPlacement": "PER_USAGE_POINT", "loadIntervalLengthHours": 0.5, @@ -756,10 +922,10 @@ def run_opendss_export_request_handler(request): "switchMeterPlacementConfigs": [ { "meterSwitchClass": "LOAD_BREAK_SWITCH", - "namePattern": ".*" + "namePattern": ".*", } ], - "energyConsumerMeterGroup": "meter group 1" + "energyConsumerMeterGroup": "meter group 1", }, "seed": 42, "defaultLoadWatts": [100.0, 200.0, 300.0], @@ -772,10 +938,10 @@ def run_opendss_export_request_handler(request): "ratingThreshold": 20.0, "simplifyPLSIThreshold": 20.0, "emergAmpScaling": 1.8, - 'inverterControlConfig': { - 'afterCutOffProfile': 'afterProfile', - 'beforeCutOffProfile': 'beforeProfile', - 'cutOffDate': '2024-04-12T11:42:00' + "inverterControlConfig": { + "afterCutOffProfile": "afterProfile", + "beforeCutOffProfile": "beforeProfile", + "cutOffDate": "2024-04-12T11:42:00", }, }, "solve": { @@ -784,18 +950,27 @@ def run_opendss_export_request_handler(request): "emergVMinPu": 0.8, "emergVMaxPu": 1.1, "baseFrequency": 50, - "voltageBases": [0.4, 0.433, 6.6, 11.0, 22.0, 33.0, 66.0, 132.0], + "voltageBases": [ + 0.4, + 0.433, + 6.6, + 11.0, + 22.0, + 33.0, + 66.0, + 132.0, + ], "maxIter": 25, "maxControlIter": 20, "mode": "YEARLY", - "stepSizeMinutes": 60 + "stepSizeMinutes": 60, }, "rawResults": { "energyMeterVoltagesRaw": True, "energyMetersRaw": True, "resultsPerMeter": True, "overloadsRaw": True, - "voltageExceptionsRaw": True + "voltageExceptionsRaw": True, }, "nodeLevelResults": { "collectVoltage": True, @@ -805,15 +980,18 @@ def run_opendss_export_request_handler(request): "collectAllSwitches": False, "collectAllTransformers": True, "collectAllConductors": False, - "collectAllEnergyConsumers": True - } - } - } - } + "collectAllEnergyConsumers": True, + }, + }, + }, + }, } } - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) + OPENDSS_CONFIG = OpenDssModelInput( modelName="TEST OPENDSS MODEL 1", @@ -826,7 +1004,7 @@ def run_opendss_export_request_handler(request): ), modulesConfiguration=OpenDssModulesConfigInput( common=OpenDssCommonConfigInput( - fixedTime= FixedTimeInput( + fixedTime=FixedTimeInput( loadTime=datetime(2022, 4, 1), overrides=[ FixedTimeLoadOverrideInput( @@ -834,9 +1012,9 @@ def run_opendss_export_request_handler(request): genVarOverride=[1.0], genWattsOverride=[2.0], loadVarOverride=[3.0], - loadWattsOverride=[4.0] + loadWattsOverride=[4.0], ) - ] + ], ), timePeriod=TimePeriodInput( startTime=datetime(2022, 4, 1, 10, 13), @@ -847,9 +1025,9 @@ def run_opendss_export_request_handler(request): genVarOverride=[1.0], genWattsOverride=[2.0], loadVarOverride=[3.0], - loadWattsOverride=[4.0] + loadWattsOverride=[4.0], ) - ] + ], ), ), generator=HcGeneratorConfigInput( @@ -876,8 +1054,6 @@ def run_opendss_export_request_handler(request): simplify_network=False, collapse_lv_networks=False, collapse_negligible_impedances=False, - negligible_impedance_min_hv_threshold=0.12, - negligible_impedance_min_lv_threshold=0.34, combine_common_impedances=False, feeder_scenario_allocation_strategy=HcFeederScenarioAllocationStrategy.ADDITIVE, closed_loop_v_reg_enabled=True, @@ -898,7 +1074,7 @@ def run_opendss_export_request_handler(request): [6350, 11000], [6400, 11000], [12700, 22000], - [19100, 33000] + [19100, 33000], ], load_placement=HcLoadPlacement.PER_USAGE_POINT, loadIntervalLengthHours=0.5, @@ -908,10 +1084,10 @@ def run_opendss_export_request_handler(request): switchMeterPlacementConfigs=[ HcSwitchMeterPlacementConfigInput( meterSwitchClass=HcSwitchClass.LOAD_BREAK_SWITCH, - namePattern=".*" + namePattern=".*", ) ], - energyConsumerMeterGroup="meter group 1" + energyConsumerMeterGroup="meter group 1", ), seed=42, default_load_watts=[100.0, 200.0, 300.0], @@ -927,8 +1103,8 @@ def run_opendss_export_request_handler(request): inverter_control_config=HcInverterControlConfigInput( cut_off_date=datetime(2024, 4, 12, 11, 42), before_cut_off_profile="beforeProfile", - after_cut_off_profile="afterProfile" - ) + after_cut_off_profile="afterProfile", + ), ), solve=HcSolveConfigInput( normVMinPu=0.9, @@ -940,14 +1116,14 @@ def run_opendss_export_request_handler(request): max_iter=25, max_control_iter=20, mode=HcSolveMode.YEARLY, - step_size_minutes=60 + step_size_minutes=60, ), rawResults=HcRawResultsConfigInput( energy_meter_voltages_raw=True, energy_meters_raw=True, results_per_meter=True, overloads_raw=True, - voltage_exceptions_raw=True + voltage_exceptions_raw=True, ), nodeLevelResults=HcNodeLevelResultsConfigInput( collect_voltage=True, @@ -957,11 +1133,10 @@ def run_opendss_export_request_handler(request): collect_all_switches=False, collect_all_transformers=True, collect_all_conductors=False, - collect_all_energy_consumers=True - ) - - ) - ) + collect_all_energy_consumers=True, + ), + ), + ), ), ) @@ -974,7 +1149,9 @@ def test_run_opendss_export_no_verify_success(httpserver: HTTPServer): enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/graphql").respond_with_handler(run_opendss_export_request_handler) + httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( + run_opendss_export_request_handler + ) res = eas_client.run_opendss_export(OPENDSS_CONFIG) httpserver.check_assertions() assert res == {"result": "success"} @@ -983,44 +1160,56 @@ def test_run_opendss_export_no_verify_success(httpserver: HTTPServer): def test_run_opendss_export_invalid_certificate_failure(httpserver: HTTPServer): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) with pytest.raises(httpx.ConnectError): eas_client.run_opendss_export(OPENDSS_CONFIG) -def test_run_opendss_export_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_run_opendss_export_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) dss_conf = OPENDSS_CONFIG.model_copy() - dss_conf.generation_spec.modules_configuration.common.fixed_time = FixedTimeInput(load_time=datetime(2022, 4, 1), - overrides=[ - FixedTimeLoadOverrideInput( - loadId="meter1", - genVarOverride=[1.0], - genWattsOverride=[2.0], - loadVarOverride=[3.0], - loadWattsOverride=[4.0] - ) - ]) - httpserver.expect_oneshot_request("/api/graphql").respond_with_handler(run_opendss_export_request_handler) + dss_conf.generation_spec.modules_configuration.common.fixed_time = FixedTimeInput( + load_time=datetime(2022, 4, 1), + overrides=[ + FixedTimeLoadOverrideInput( + loadId="meter1", + genVarOverride=[1.0], + genWattsOverride=[2.0], + loadVarOverride=[3.0], + loadWattsOverride=[4.0], + ) + ], + ) + httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( + run_opendss_export_request_handler + ) res = eas_client.run_opendss_export(dss_conf) httpserver.check_assertions() assert res == {"result": "success"} -get_paged_opendss_models_query = ("query pagedOpenDssModels($limit_0: Int, $offset_0: Long, $filter_0: " - "GetOpenDssModelsFilterInput, $sort_0: GetOpenDssModelsSortCriteriaInput) { " - "pagedOpenDssModels( limit: $limit_0 offset: $offset_0 filter: $filter_0 " - "sort: $sort_0 ) { totalCount offset models { id name createdAt state " - "downloadUrl isPublic errors generationSpec } } }") +get_paged_opendss_models_query = ( + "query pagedOpenDssModels($limit_0: Int, $offset_0: Long, $filter_0: " + "GetOpenDssModelsFilterInput, $sort_0: GetOpenDssModelsSortCriteriaInput) { " + "pagedOpenDssModels( limit: $limit_0 offset: $offset_0 filter: $filter_0 " + "sort: $sort_0 ) { totalCount offset models { id name createdAt state " + "downloadUrl isPublic errors generationSpec } } }" +) def get_paged_opendss_models_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == " ".join(line.strip() for line in get_paged_opendss_models_query.strip().splitlines()) - assert actual_body['variables'] == { + assert query == " ".join( + line.strip() for line in get_paged_opendss_models_query.strip().splitlines() + ) + assert actual_body["variables"] == { "limit_0": 5, "offset_0": 0, "filter_0": { @@ -1030,10 +1219,12 @@ def get_paged_opendss_models_request_handler(request): }, "sort_0": { "state": "ASC", - } + }, } - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_get_paged_opendss_models_no_verify_success(httpserver: HTTPServer): @@ -1045,10 +1236,18 @@ def test_get_paged_opendss_models_no_verify_success(httpserver: HTTPServer): ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_paged_opendss_models_request_handler) + get_paged_opendss_models_request_handler + ) res = eas_client.get_paged_opendss_models( - 5, 0, GetOpenDssModelsFilterInput(name="TEST OPENDSS MODEL 1", isPublic=True, state=[OpenDssModelState.COMPLETED.name]), - GetOpenDssModelsSortCriteriaInput(state=SortOrder.ASC)) + 5, + 0, + GetOpenDssModelsFilterInput( + name="TEST OPENDSS MODEL 1", + isPublic=True, + state=[OpenDssModelState.COMPLETED.name], + ), + GetOpenDssModelsSortCriteriaInput(state=SortOrder.ASC), + ) httpserver.check_assertions() assert res == {"result": "success"} @@ -1056,27 +1255,36 @@ def test_get_paged_opendss_models_no_verify_success(httpserver: HTTPServer): def test_get_paged_opendss_models_invalid_certificate_failure(httpserver: HTTPServer): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/graphql").respond_with_json({"result": "success"}) + httpserver.expect_oneshot_request("/api/graphql").respond_with_json( + {"result": "success"} + ) with pytest.raises(httpx.ConnectError): eas_client.get_paged_opendss_models() def get_paged_opendss_models_no_param_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == ('query pagedOpenDssModels { pagedOpenDssModels { totalCount offset models { id name createdAt ' - 'state downloadUrl isPublic errors generationSpec } } }') - assert actual_body['variables'] == {} + assert query == ( + "query pagedOpenDssModels { pagedOpenDssModels { totalCount offset models { id name createdAt " + "state downloadUrl isPublic errors generationSpec } } }" + ) + assert actual_body["variables"] == {} - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) -def test_get_paged_opendss_models_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_get_paged_opendss_models_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_paged_opendss_models_no_param_request_handler) + get_paged_opendss_models_no_param_request_handler + ) res = eas_client.get_paged_opendss_models() httpserver.check_assertions() assert res == {"result": "success"} @@ -1090,33 +1298,49 @@ def test_get_opendss_model_download_url_no_verify_success(httpserver: HTTPServer enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/opendss-model/1", method="GET").respond_with_response(Response( - status=HTTPStatus.FOUND, - headers={"Location": "https://example.com/download/1"} - )) + httpserver.expect_oneshot_request( + "/api/opendss-model/1", method="GET" + ).respond_with_response( + Response( + status=HTTPStatus.FOUND, + headers={"Location": "https://example.com/download/1"}, + ) + ) res = eas_client.get_opendss_model_download_url(1) httpserver.check_assertions() assert res == "https://example.com/download/1" -def test_get_opendss_model_download_url_invalid_certificate_failure(httpserver: HTTPServer): +def test_get_opendss_model_download_url_invalid_certificate_failure( + httpserver: HTTPServer, +): eas_client = _invalid_ca(httpserver.port) - httpserver.expect_oneshot_request("/api/opendss-model/1", method="GET").respond_with_response(Response( - status=HTTPStatus.FOUND, - headers={"Location": "https://example.com/download/1"} - )) + httpserver.expect_oneshot_request( + "/api/opendss-model/1", method="GET" + ).respond_with_response( + Response( + status=HTTPStatus.FOUND, + headers={"Location": "https://example.com/download/1"}, + ) + ) with pytest.raises(httpx.ConnectError): eas_client.get_opendss_model_download_url(1) -def test_get_opendss_model_download_url_valid_certificate_success(httpserver: HTTPServer, ca: trustme.CA): +def test_get_opendss_model_download_url_valid_certificate_success( + httpserver: HTTPServer, ca: trustme.CA +): eas_client = _valid_ca(httpserver.port, ca) - httpserver.expect_oneshot_request("/api/opendss-model/1", method="GET").respond_with_response(Response( - status=HTTPStatus.FOUND, - headers={"Location": "https://example.com/download/1"} - )) + httpserver.expect_oneshot_request( + "/api/opendss-model/1", method="GET" + ).respond_with_response( + Response( + status=HTTPStatus.FOUND, + headers={"Location": "https://example.com/download/1"}, + ) + ) res = eas_client.get_opendss_model_download_url(1) httpserver.check_assertions() assert res == "https://example.com/download/1" @@ -1124,13 +1348,22 @@ def test_get_opendss_model_download_url_valid_certificate_success(httpserver: HT def run_ingestor_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == "mutation executeIngestor($runConfig_0: [IngestorConfigInput!]) { executeIngestor(runConfig: $runConfig_0) }" - assert actual_body['variables'] == {'runConfig_0': [{'key': 'random.config', 'value': 'random.value'}, - {'key': 'dataStorePath', 'value': '/some/place/with/data'}]} + assert ( + query + == "mutation executeIngestor($runConfig_0: [IngestorConfigInput!]) { executeIngestor(runConfig: $runConfig_0) }" + ) + assert actual_body["variables"] == { + "runConfig_0": [ + {"key": "random.config", "value": "random.value"}, + {"key": "dataStorePath", "value": "/some/place/with/data"}, + ] + } - return Response(json.dumps({"executeIngestor": 5}), status=200, content_type="application/json") + return Response( + json.dumps({"executeIngestor": 5}), status=200, content_type="application/json" + ) def test_run_ingestor_no_verify_success(httpserver: HTTPServer): @@ -1142,23 +1375,32 @@ def test_run_ingestor_no_verify_success(httpserver: HTTPServer): ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - run_ingestor_request_handler) - res = eas_client.run_ingestor([IngestorConfigInput(key="random.config", value="random.value"), - IngestorConfigInput(key="dataStorePath", value="/some/place/with/data")]) + run_ingestor_request_handler + ) + res = eas_client.run_ingestor( + [ + IngestorConfigInput(key="random.config", value="random.value"), + IngestorConfigInput(key="dataStorePath", value="/some/place/with/data"), + ] + ) httpserver.check_assertions() assert res == {"executeIngestor": 5} def get_ingestor_run_request_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - assert query == ("query getIngestorRun($id_0: Int!) { getIngestorRun(id: $id_0) { completedAt " - "containerRuntimeType id payload startedAt status statusLastUpdatedAt token } " - "}") - assert actual_body['variables'] == {"id_0": 1} + assert query == ( + "query getIngestorRun($id_0: Int!) { getIngestorRun(id: $id_0) { completedAt " + "containerRuntimeType id payload startedAt status statusLastUpdatedAt token } " + "}" + ) + assert actual_body["variables"] == {"id_0": 1} - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_get_ingestor_run_no_verify_success(httpserver: HTTPServer): @@ -1169,7 +1411,9 @@ def test_get_ingestor_run_no_verify_success(httpserver: HTTPServer): enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/graphql").respond_with_handler(get_ingestor_run_request_handler) + httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( + get_ingestor_run_request_handler + ) res = eas_client.get_ingestor_run(1) httpserver.check_assertions() assert res == {"result": "success"} @@ -1177,14 +1421,20 @@ def test_get_ingestor_run_no_verify_success(httpserver: HTTPServer): def get_ingestor_run_list_request_empty_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) + query = " ".join(actual_body["query"].split()) - get_ingestor_run_list_query = ("query listIngestorRuns { listIngestorRuns { id containerRuntimeType payload " - "token status startedAt statusLastUpdatedAt completedAt } }") - assert query == " ".join(line.strip() for line in get_ingestor_run_list_query.strip().splitlines()) - assert actual_body['variables'] == {} + get_ingestor_run_list_query = ( + "query listIngestorRuns { listIngestorRuns { id containerRuntimeType payload " + "token status startedAt statusLastUpdatedAt completedAt } }" + ) + assert query == " ".join( + line.strip() for line in get_ingestor_run_list_query.strip().splitlines() + ) + assert actual_body["variables"] == {} - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_get_ingestor_run_list_empty_filter_no_verify_success(httpserver: HTTPServer): @@ -1195,7 +1445,9 @@ def test_get_ingestor_run_list_empty_filter_no_verify_success(httpserver: HTTPSe enable_legacy_methods=True, ) - httpserver.expect_oneshot_request("/api/graphql").respond_with_handler(get_ingestor_run_list_request_empty_handler) + httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( + get_ingestor_run_list_request_empty_handler + ) res = eas_client.get_ingestor_run_list() httpserver.check_assertions() assert res == {"result": "success"} @@ -1203,19 +1455,23 @@ def test_get_ingestor_run_list_empty_filter_no_verify_success(httpserver: HTTPSe def get_ingestor_run_list_request_complete_handler(request): actual_body = json.loads(request.data.decode()) - query = " ".join(actual_body['query'].split()) - - get_ingestor_run_list_query = ("query listIngestorRuns($filter_0: IngestorRunsFilterInput, $sort_0: " - "IngestorRunsSortCriteriaInput) { listIngestorRuns(filter: $filter_0, sort: " - "$sort_0) { id containerRuntimeType payload token status startedAt " - "statusLastUpdatedAt completedAt } }") - assert query == " ".join(line.strip() for line in get_ingestor_run_list_query.strip().splitlines()) - assert actual_body['variables'] == { + query = " ".join(actual_body["query"].split()) + + get_ingestor_run_list_query = ( + "query listIngestorRuns($filter_0: IngestorRunsFilterInput, $sort_0: " + "IngestorRunsSortCriteriaInput) { listIngestorRuns(filter: $filter_0, sort: " + "$sort_0) { id containerRuntimeType payload token status startedAt " + "statusLastUpdatedAt completedAt } }" + ) + assert query == " ".join( + line.strip() for line in get_ingestor_run_list_query.strip().splitlines() + ) + assert actual_body["variables"] == { "filter_0": { - "id": '4', + "id": "4", "status": ["SUCCESS", "STARTED", "FAILED_TO_START"], "completed": True, - "containerRuntimeType": ["TEMPORAL_KUBERNETES", "AZURE_CONTAINER_APP_JOB"] + "containerRuntimeType": ["TEMPORAL_KUBERNETES", "AZURE_CONTAINER_APP_JOB"], }, "sort_0": { "status": "ASC", @@ -1223,10 +1479,12 @@ def get_ingestor_run_list_request_complete_handler(request): "statusLastUpdatedAt": "ASC", "completedAt": "DESC", "containerRuntimeType": "ASC", - } + }, } - return Response(json.dumps({"result": "success"}), status=200, content_type="application/json") + return Response( + json.dumps({"result": "success"}), status=200, content_type="application/json" + ) def test_get_ingestor_run_list_all_filters_no_verify_success(httpserver: HTTPServer): @@ -1238,22 +1496,29 @@ def test_get_ingestor_run_list_all_filters_no_verify_success(httpserver: HTTPSer ) httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - get_ingestor_run_list_request_complete_handler) + get_ingestor_run_list_request_complete_handler + ) res = eas_client.get_ingestor_run_list( query_filter=IngestorRunsFilterInput( - id='4', - status=[IngestorRunState.SUCCESS, IngestorRunState.STARTED, IngestorRunState.FAILED_TO_START], + id="4", + status=[ + IngestorRunState.SUCCESS, + IngestorRunState.STARTED, + IngestorRunState.FAILED_TO_START, + ], completed=True, - containerRuntimeType=[IngestorRuntimeKind.TEMPORAL_KUBERNETES, - IngestorRuntimeKind.AZURE_CONTAINER_APP_JOB] + containerRuntimeType=[ + IngestorRuntimeKind.TEMPORAL_KUBERNETES, + IngestorRuntimeKind.AZURE_CONTAINER_APP_JOB, + ], ), query_sort=IngestorRunsSortCriteriaInput( status=SortOrder.ASC, startedAt=SortOrder.DESC, statusLastUpdatedAt=SortOrder.ASC, completedAt=SortOrder.DESC, - containerRuntimeType=SortOrder.ASC - ) + containerRuntimeType=SortOrder.ASC, + ), ) httpserver.check_assertions() assert res == {"result": "success"} @@ -1264,17 +1529,17 @@ def test_work_package_config_to_json_omits_server_defaulted_fields_if_unspecifie wp_config = WorkPackageInput( feederConfigs=FeederConfigsInput(configs=[]), intervention=InterventionConfigInput( - baseWorkPackageId="abc", - interventionType=InterventionClass.COMMUNITY_BESS - ) + baseWorkPackageId="abc", interventionType=InterventionClass.COMMUNITY_BESS + ), ) json_config = wp_config.model_dump_json(by_alias=True, exclude_defaults=True) - assert json.loads(json_config)['intervention'] == { + assert json.loads(json_config)["intervention"] == { "baseWorkPackageId": "abc", "interventionType": "COMMUNITY_BESS", } + def test_work_package_config_to_json_includes_server_defaulted_fields_if_specified(): wp_config = WorkPackageInput( @@ -1283,26 +1548,24 @@ def test_work_package_config_to_json_includes_server_defaulted_fields_if_specifi baseWorkPackageId="abc", yearRange=YearRangeInput(minYear=2020, maxYear=2025), interventionType=InterventionClass.COMMUNITY_BESS, - allocationLimitPerYear=5 - ) + allocationLimitPerYear=5, + ), ) json_config = wp_config.model_dump_json(by_alias=True) - assert json.loads(json_config)['intervention'] == { + assert json.loads(json_config)["intervention"] == { "baseWorkPackageId": "abc", - "yearRange": { - "maxYear": 2025, - "minYear": 2020 - }, + "yearRange": {"maxYear": 2025, "minYear": 2020}, "interventionType": "COMMUNITY_BESS", "candidateGeneration": None, "allocationCriteria": None, "specificAllocationInstance": None, "phaseRebalanceProportions": None, "dvms": None, - "allocationLimitPerYear": 5 + "allocationLimitPerYear": 5, } + def test_work_package_config_to_json_for_tap_optimization(): wp_config = WorkPackageInput( feederConfigs=FeederConfigsInput(configs=[]), @@ -1317,9 +1580,9 @@ def test_work_package_config_to_json_for_tap_optimization(): voltageUnderLimitHoursThreshold=1, voltageOverLimitHoursThreshold=2, tapWeightingFactorLowerThreshold=-0.3, - tapWeightingFactorUpperThreshold=0.4 - ) - ) + tapWeightingFactorUpperThreshold=0.4, + ), + ), ) json_config = wp_config.model_dump_json(by_alias=True) @@ -1330,10 +1593,7 @@ def test_work_package_config_to_json_for_tap_optimization(): "generatorConfig": None, "intervention": { "baseWorkPackageId": "abc", - "yearRange": { - "maxYear": 2025, - "minYear": 2020 - }, + "yearRange": {"maxYear": 2025, "minYear": 2020}, "interventionType": "DISTRIBUTION_TAP_OPTIMIZATION", "candidateGeneration": { "type": "TAP_OPTIMIZATION", @@ -1348,7 +1608,7 @@ def test_work_package_config_to_json_for_tap_optimization(): "specificAllocationInstance": None, "phaseRebalanceProportions": None, "dvms": None, - "allocationLimitPerYear": 5 + "allocationLimitPerYear": 5, }, "qualityAssuranceProcessing": None, "resultProcessorConfig": None, diff --git a/test/test_feeder_load_analysis.py b/test/test_feeder_load_analysis.py index dfc4b81..051efdf 100644 --- a/test/test_feeder_load_analysis.py +++ b/test/test_feeder_load_analysis.py @@ -3,7 +3,10 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -from zepben.eas.lib.generated_graphql_client import FeederLoadAnalysisInput, FlaForecastConfigInput +from zepben.eas import ( + FeederLoadAnalysisInput, + FlaForecastConfigInput, +) def test_feeder_load_analysis_constructor(): @@ -25,8 +28,8 @@ def test_feeder_load_analysis_constructor(): year=2030, pv_upgrade_threshold=8000, bess_upgrade_threshold=8000, - seed=64513 - ) + seed=64513, + ), ) assert feeder_load_analysis_input is not None diff --git a/test/test_integration_testing.py b/test/test_integration_testing.py index 9630fde..9c52306 100644 --- a/test/test_integration_testing.py +++ b/test/test_integration_testing.py @@ -8,12 +8,22 @@ import pytest -from zepben.eas import EasClient, OpenDssModelInput, OpenDssModelGenerationSpecInput, OpenDssModelOptionsInput, \ - OpenDssModulesConfigInput, OpenDssCommonConfigInput, Query, IngestionRunFields, IngestionJobFields +from zepben.eas import ( + EasClient, + OpenDssModelInput, + OpenDssModelGenerationSpecInput, + OpenDssModelOptionsInput, + OpenDssModulesConfigInput, + OpenDssCommonConfigInput, + Query, + IngestionRunFields, + IngestionJobFields, +) if TYPE_CHECKING: from zepben.eas import GraphQLQuery + @pytest.mark.skip("Local testing if you really want it...") def test_can_connect_to_local_eas_non_async(): client = EasClient( @@ -24,7 +34,7 @@ def test_can_connect_to_local_eas_non_async(): asynchronous=False, enable_legacy_methods=True, ) - assert client.get_ingestor_run_list() == {'data': {'listIngestorRuns': []}} + assert client.get_ingestor_run_list() == {"data": {"listIngestorRuns": []}} @pytest.mark.skip("Local testing if you really want it...") @@ -37,7 +47,9 @@ def test_can_connect_to_local_eas_async_asyncio_run_calling(): asynchronous=True, enable_legacy_methods=True, ) - assert asyncio.run(client.get_ingestor_run_list()) == {'data': {'listIngestorRuns': []}} + assert asyncio.run(client.get_ingestor_run_list()) == { + "data": {"listIngestorRuns": []} + } @pytest.mark.skip("Local testing if you really want it...") @@ -51,27 +63,38 @@ async def test_can_connect_to_local_eas_async_calling_func(): asynchronous=True, enable_legacy_methods=True, ) - assert await client.get_ingestor_run_list() == {'data': {'listIngestorRuns': []}} - print(await client.run_opendss_export( - OpenDssModelInput( - generationSpec=OpenDssModelGenerationSpecInput( - modelOptions=OpenDssModelOptionsInput(feeder='feeder', scenario='foo', year=1), - modulesConfiguration=OpenDssModulesConfigInput(common=OpenDssCommonConfigInput()), + assert await client.get_ingestor_run_list() == {"data": {"listIngestorRuns": []}} + print( + await client.run_opendss_export( + OpenDssModelInput( + generationSpec=OpenDssModelGenerationSpecInput( + modelOptions=OpenDssModelOptionsInput( + feeder="feeder", scenario="foo", year=1 + ), + modulesConfiguration=OpenDssModulesConfigInput( + common=OpenDssCommonConfigInput() + ), + ) ) ) - )) + ) + @pytest.mark.skip("only displays type hinting in client.query call") @pytest.mark.asyncio async def test_do_things(): - client = EasClient( - host="localhost", - port=7654, - asynchronous=True - ) + client = EasClient(host="localhost", port=7654, asynchronous=True) try: - await client.query(Query.list_ingestor_runs(filter_=None, sort=None), IngestionRunFields.completed_at, IngestionRunFields.status) - await client.query(Query.list_ingestor_runs(filter_=None, sort=None), IngestionJobFields.application, 1) + await client.query( + Query.list_ingestor_runs(filter_=None, sort=None), + IngestionRunFields.completed_at, + IngestionRunFields.status, + ) + await client.query( + Query.list_ingestor_runs(filter_=None, sort=None), + IngestionJobFields.application, + 1, + ) except: pass # my_query(Query.list_ingestor_runs(filter_=None, sort=None)) diff --git a/test/test_patched_client.py b/test/test_patched_client.py index e6f2f90..ec87f96 100644 --- a/test/test_patched_client.py +++ b/test/test_patched_client.py @@ -4,7 +4,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -from zepben.eas import FeederLoadAnalysisReportFields, EasClient, FeederLoadAnalysisSpecFields +from zepben.eas import ( + FeederLoadAnalysisReportFields, + EasClient, + FeederLoadAnalysisSpecFields, +) class MockResponse: @@ -27,7 +31,7 @@ def test_patched_client_used_in_eas_client(): def test_patched_client_overrides_get_data_to_return_the_whole_json_response(): client = EasClient(host="test_host", port=9876) - assert client.get_data(MockResponse()) == {'json': 'probably'} + assert client.get_data(MockResponse()) == {"json": "probably"} def test_all_fields(): @@ -38,4 +42,4 @@ def test_all_fields(): if isinstance(f, FeederLoadAnalysisSpecFields): break else: - assert False \ No newline at end of file + assert False From 600329632eaa286d7ba4638a5db4f73ebbc18e47 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:50:57 +1000 Subject: [PATCH 2/9] missed github files Signed-off-by: Max Chesterfield --- .github/evolve-app-server/client-config.json | 38 +++++++++++++++++++ .github/evolve-app-server/config.json | 38 +++++++++++++++++++ .github/workflows/client-build.yml | 17 +++++++++ .../workflows/python-lib-build-eas-edge.yml | 13 +++++++ .../workflows/python-lib-build-eas-tag.yml | 21 ++++++++++ .github/workflows/python-lib-release.yml | 26 +++++++++++++ 6 files changed, 153 insertions(+) create mode 100644 .github/evolve-app-server/client-config.json create mode 100644 .github/evolve-app-server/config.json create mode 100644 .github/workflows/client-build.yml create mode 100644 .github/workflows/python-lib-build-eas-edge.yml create mode 100644 .github/workflows/python-lib-build-eas-tag.yml create mode 100644 .github/workflows/python-lib-release.yml diff --git a/.github/evolve-app-server/client-config.json b/.github/evolve-app-server/client-config.json new file mode 100644 index 0000000..ea430a0 --- /dev/null +++ b/.github/evolve-app-server/client-config.json @@ -0,0 +1,38 @@ +{ + "server": { + "host": "0.0.0.0", + "publicAddress": "http://localhost", + "useTls": false, + "port": 7654, + "webRoot": "../evolve-web-app/dist", + "webClientHost": "*", + "logFile": "logs/logFile.log" + }, + "ewb": { + "host": "ewb.local", + "port": 9000, + "protocol": "HTTPS", + "requestMethod": "GET", + "verifyCertificate": false + }, + "database": { + "url": "jdbc:postgresql://localhost:5432/eas?user=eas&password=password", + "driver": "org.postgresql.Driver", + "createSchemaOnStart": true + }, + "ui": { + "powerFactoryExporterEnabled": true + }, + "jwks": { + "issuer": "http://localhost:7654" + }, + "auth": { + "audience": "80b6b329-bc8f-4479-943a-9daf755a06a7", + "method": "none", + "defaultUserId": "guy1", + "defaultUsername": "some", + "defaultUserEmail": "a@b", + "defaultUserRoles": ["MAP_VIEWER", "SUPER_ADMIN", "EWB_ADMIN", "DEVELOPER", "METRICS_VIEWER"] + } + +} diff --git a/.github/evolve-app-server/config.json b/.github/evolve-app-server/config.json new file mode 100644 index 0000000..a41ca8e --- /dev/null +++ b/.github/evolve-app-server/config.json @@ -0,0 +1,38 @@ +{ + "server": { + "host": "0.0.0.0", + "publicAddress": "http://localhost", + "useTls": false, + "port": 7654, + "webRoot": "../evolve-web-app/dist", + "webClientHost": "*", + "logFile": "logs/logFile.log" + }, + "ewb": { + "host": "ewb.local", + "port": 9000, + "protocol": "HTTPS", + "requestMethod": "GET", + "verifyCertificate": false + }, + "database": { + "url": "jdbc:postgresql://postgres:5432/eas?user=eas&password=password", + "driver": "org.postgresql.Driver", + "createSchemaOnStart": true + }, + "ui": { + "powerFactoryExporterEnabled": true + }, + "jwks": { + "issuer": "http://localhost:7654" + }, + "auth": { + "audience": "80b6b329-bc8f-4479-943a-9daf755a06a7", + "method": "none", + "defaultUserId": "guy1", + "defaultUsername": "some", + "defaultUserEmail": "a@b", + "defaultUserRoles": ["MAP_VIEWER", "SUPER_ADMIN", "EWB_ADMIN", "DEVELOPER", "METRICS_VIEWER"] + } + +} diff --git a/.github/workflows/client-build.yml b/.github/workflows/client-build.yml new file mode 100644 index 0000000..bcbabc4 --- /dev/null +++ b/.github/workflows/client-build.yml @@ -0,0 +1,17 @@ +name: Python Library Release + +on: + repository_dispatch: + types: + [evolve-app-server-build] + +jobs: + run: + uses: zepben/.github/.github/workflows/python-lib-release.yml@eas-client-test + with: + private: false + python-version: "3.10" + docker-container: codegen + docker-compose-env: '{"EAS_TAG": "${{ github.event.client_payload.eas-tag }}"}' + package-release-version: "${{ github.event.client_payload.eas-tag }}" + secrets: inherit diff --git a/.github/workflows/python-lib-build-eas-edge.yml b/.github/workflows/python-lib-build-eas-edge.yml new file mode 100644 index 0000000..d127689 --- /dev/null +++ b/.github/workflows/python-lib-build-eas-edge.yml @@ -0,0 +1,13 @@ +name: Python Lib Build (Latest Evolve App Server) + +on: + push: + pull_request: + +jobs: + run: + uses: zepben/.github/.github/workflows/python-build.yml@eas-client-test + with: + python-versions-to-test: "['3.10', '3.11', '3.12']" + docker-container: codegen + secrets: inherit diff --git a/.github/workflows/python-lib-build-eas-tag.yml b/.github/workflows/python-lib-build-eas-tag.yml new file mode 100644 index 0000000..671e818 --- /dev/null +++ b/.github/workflows/python-lib-build-eas-tag.yml @@ -0,0 +1,21 @@ +name: Python Lib Build (Tagged Evolve App Server) + +on: + workflow_dispatch: + inputs: + eas-tag: + description: 'evolve-app-server version tag (e.g. 2.13.0) to generate client for.' + required: true + type: string + +jobs: + run: + uses: zepben/.github/.github/workflows/python-build.yml@eas-client-test + if: ${{ inputs.eas-tag }} != '' + with: + docker-compose-env: '{"EAS_TAG": "${{ inputs.eas-tag }}"}' + override-version: "${{ inputs.eas-tag }}" + python-versions-to-test: "['3.10', '3.11', '3.12']" + docker-container: codegen + secrets: inherit + diff --git a/.github/workflows/python-lib-release.yml b/.github/workflows/python-lib-release.yml new file mode 100644 index 0000000..64fe646 --- /dev/null +++ b/.github/workflows/python-lib-release.yml @@ -0,0 +1,26 @@ +name: Python Library Release + +on: + workflow_dispatch: + inputs: + eas-tag: + description: 'evolve-app-server version tag (e.g. 2.13.0) to generate client for.' + required: true + type: string + workflow_call: + inputs: + eas-tag: + description: 'evolve-app-server version tag (e.g. 2.13.0) to generate client for.' + required: true + type: string + +jobs: + run: + uses: zepben/.github/.github/workflows/python-lib-release.yml@eas-client-test + with: + private: false + python-version: "3.10" + docker-container: codegen + docker-compose-env: '{"EAS_TAG": "${{ inputs.eas-tag }}"}' + package-release-version: "${{ inputs.eas-tag }}" + secrets: inherit From a4386e285b31aa528742e1a0adfe9d5abcf5d575 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:57:45 +1000 Subject: [PATCH 3/9] Update client-build.yml Signed-off-by: Max Chesterfield --- .github/workflows/client-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-build.yml b/.github/workflows/client-build.yml index bcbabc4..8eeaeb1 100644 --- a/.github/workflows/client-build.yml +++ b/.github/workflows/client-build.yml @@ -7,7 +7,7 @@ on: jobs: run: - uses: zepben/.github/.github/workflows/python-lib-release.yml@eas-client-test + uses: zepben/.github/.github/workflows/python-lib-release.yml@main with: private: false python-version: "3.10" From 9ee44d05f311d4279a55539a354ec6d2ec954b95 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:58:28 +1000 Subject: [PATCH 4/9] Update python-lib-build-eas-edge.yml Signed-off-by: Max Chesterfield --- .github/workflows/python-lib-build-eas-edge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-lib-build-eas-edge.yml b/.github/workflows/python-lib-build-eas-edge.yml index d127689..7c93a0e 100644 --- a/.github/workflows/python-lib-build-eas-edge.yml +++ b/.github/workflows/python-lib-build-eas-edge.yml @@ -6,7 +6,7 @@ on: jobs: run: - uses: zepben/.github/.github/workflows/python-build.yml@eas-client-test + uses: zepben/.github/.github/workflows/python-build.yml@main with: python-versions-to-test: "['3.10', '3.11', '3.12']" docker-container: codegen From a6911a3e266eff9fee11b3b1f17bc924f2c64b46 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:58:46 +1000 Subject: [PATCH 5/9] Update python-lib-build-eas-tag.yml Signed-off-by: Max Chesterfield --- .github/workflows/python-lib-build-eas-tag.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-lib-build-eas-tag.yml b/.github/workflows/python-lib-build-eas-tag.yml index 671e818..5c91537 100644 --- a/.github/workflows/python-lib-build-eas-tag.yml +++ b/.github/workflows/python-lib-build-eas-tag.yml @@ -10,7 +10,7 @@ on: jobs: run: - uses: zepben/.github/.github/workflows/python-build.yml@eas-client-test + uses: zepben/.github/.github/workflows/python-build.yml@main if: ${{ inputs.eas-tag }} != '' with: docker-compose-env: '{"EAS_TAG": "${{ inputs.eas-tag }}"}' From 1ee872a27bd9dd67f6fdcb74a551589e4496294e Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 13:59:04 +1000 Subject: [PATCH 6/9] Update python-lib-release.yml Signed-off-by: Max Chesterfield --- .github/workflows/python-lib-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-lib-release.yml b/.github/workflows/python-lib-release.yml index 64fe646..11e91fa 100644 --- a/.github/workflows/python-lib-release.yml +++ b/.github/workflows/python-lib-release.yml @@ -16,7 +16,7 @@ on: jobs: run: - uses: zepben/.github/.github/workflows/python-lib-release.yml@eas-client-test + uses: zepben/.github/.github/workflows/python-lib-release.yml@main with: private: false python-version: "3.10" From 5f7e6d1b1bdfc2208daf3c06303ca3536a5c5e68 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 14:04:44 +1000 Subject: [PATCH 7/9] Update pyproject.toml Signed-off-by: Max Chesterfield --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f3983d2..2b5c2c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ requires = [ build-backend = "setuptools.build_meta" [project] -name = "zepben.test-eas-client-python" +name = "zepben.eas-client-python" version = "0.0.0b1" description = "Python SDK for interacting with the Evolve App Server" readme = {file = "README.md", content-type = "text/markdown"} From f5d6ed5f5741d2b8ab06f1bc5667471588af1cd3 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 14:05:12 +1000 Subject: [PATCH 8/9] Update pyproject.toml Signed-off-by: Max Chesterfield --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2b5c2c7..13fa815 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta" [project] name = "zepben.eas-client-python" -version = "0.0.0b1" +version = "1.0.0b4" description = "Python SDK for interacting with the Evolve App Server" readme = {file = "README.md", content-type = "text/markdown"} license = "MPL-2.0" From 86e5b88ba7cbe9efae1231f78a5129ee01187886 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 7 May 2026 14:08:19 +1000 Subject: [PATCH 9/9] dont run tests twice Signed-off-by: Max Chesterfield --- .github/workflows/python-lib-build-eas-edge.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/python-lib-build-eas-edge.yml b/.github/workflows/python-lib-build-eas-edge.yml index 7c93a0e..3b0d81e 100644 --- a/.github/workflows/python-lib-build-eas-edge.yml +++ b/.github/workflows/python-lib-build-eas-edge.yml @@ -2,7 +2,6 @@ name: Python Lib Build (Latest Evolve App Server) on: push: - pull_request: jobs: run: