zepben.ewb 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zepben/ewb/__init__.py +601 -0
- zepben/ewb/auth/__init__.py +10 -0
- zepben/ewb/auth/client/__init__.py +5 -0
- zepben/ewb/auth/client/zepben_token_fetcher.py +273 -0
- zepben/ewb/auth/common/__init__.py +5 -0
- zepben/ewb/auth/common/auth_exception.py +16 -0
- zepben/ewb/auth/common/auth_method.py +28 -0
- zepben/ewb/auth/common/auth_provider_config.py +96 -0
- zepben/ewb/database/__init__.py +4 -0
- zepben/ewb/database/paths/__init__.py +4 -0
- zepben/ewb/database/paths/database_type.py +34 -0
- zepben/ewb/database/paths/ewb_data_file_paths.py +237 -0
- zepben/ewb/database/sql/__init__.py +4 -0
- zepben/ewb/database/sql/column.py +37 -0
- zepben/ewb/database/sql/sql_table.py +142 -0
- zepben/ewb/database/sqlite/__init__.py +4 -0
- zepben/ewb/database/sqlite/common/__init__.py +4 -0
- zepben/ewb/database/sqlite/common/base_cim_reader.py +212 -0
- zepben/ewb/database/sqlite/common/base_cim_writer.py +159 -0
- zepben/ewb/database/sqlite/common/base_collection_reader.py +96 -0
- zepben/ewb/database/sqlite/common/base_collection_writer.py +73 -0
- zepben/ewb/database/sqlite/common/base_database_reader.py +127 -0
- zepben/ewb/database/sqlite/common/base_database_tables.py +137 -0
- zepben/ewb/database/sqlite/common/base_database_writer.py +195 -0
- zepben/ewb/database/sqlite/common/base_entry_writer.py +34 -0
- zepben/ewb/database/sqlite/common/base_service_reader.py +50 -0
- zepben/ewb/database/sqlite/common/base_service_writer.py +104 -0
- zepben/ewb/database/sqlite/common/metadata_collection_reader.py +39 -0
- zepben/ewb/database/sqlite/common/metadata_collection_writer.py +38 -0
- zepben/ewb/database/sqlite/common/metadata_entry_reader.py +45 -0
- zepben/ewb/database/sqlite/common/metadata_entry_writer.py +41 -0
- zepben/ewb/database/sqlite/common/reader_exceptions.py +30 -0
- zepben/ewb/database/sqlite/customer/__init__.py +4 -0
- zepben/ewb/database/sqlite/customer/customer_cim_reader.py +169 -0
- zepben/ewb/database/sqlite/customer/customer_cim_writer.py +137 -0
- zepben/ewb/database/sqlite/customer/customer_database_reader.py +44 -0
- zepben/ewb/database/sqlite/customer/customer_database_tables.py +37 -0
- zepben/ewb/database/sqlite/customer/customer_database_writer.py +45 -0
- zepben/ewb/database/sqlite/customer/customer_service_reader.py +57 -0
- zepben/ewb/database/sqlite/customer/customer_service_writer.py +47 -0
- zepben/ewb/database/sqlite/diagram/__init__.py +4 -0
- zepben/ewb/database/sqlite/diagram/diagram_cim_reader.py +105 -0
- zepben/ewb/database/sqlite/diagram/diagram_cim_writer.py +81 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_reader.py +45 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_tables.py +29 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_writer.py +44 -0
- zepben/ewb/database/sqlite/diagram/diagram_service_reader.py +49 -0
- zepben/ewb/database/sqlite/diagram/diagram_service_writer.py +41 -0
- zepben/ewb/database/sqlite/extensions/__init__.py +4 -0
- zepben/ewb/database/sqlite/extensions/prepared_statement.py +112 -0
- zepben/ewb/database/sqlite/extensions/result_set.py +153 -0
- zepben/ewb/database/sqlite/network/__init__.py +4 -0
- zepben/ewb/database/sqlite/network/network_cim_reader.py +3167 -0
- zepben/ewb/database/sqlite/network/network_cim_writer.py +2561 -0
- zepben/ewb/database/sqlite/network/network_database_reader.py +175 -0
- zepben/ewb/database/sqlite/network/network_database_tables.py +242 -0
- zepben/ewb/database/sqlite/network/network_database_writer.py +43 -0
- zepben/ewb/database/sqlite/network/network_service_reader.py +265 -0
- zepben/ewb/database/sqlite/network/network_service_writer.py +209 -0
- zepben/ewb/database/sqlite/tables/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/associations/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/associations/loop_substation_relationship.py +17 -0
- zepben/ewb/database/sqlite/tables/associations/table_asset_organisation_roles_assets.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_assets_power_system_resources.py +41 -0
- zepben/ewb/database/sqlite/tables/associations/table_battery_units_battery_controls.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_circuits_substations.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_circuits_terminals.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_customer_agreements_pricing_structures.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_end_devices_end_device_functions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_equipment_containers.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_operational_restrictions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_usage_points.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_loops_substations.py +43 -0
- zepben/ewb/database/sqlite/tables/associations/table_pricing_structures_tariffs.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_protected_switches.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_sensors.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_schemes_protection_relay_functions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_synchronous_machines_reactive_capability_curves.py +39 -0
- zepben/ewb/database/sqlite/tables/associations/table_usage_points_end_devices.py +40 -0
- zepben/ewb/database/sqlite/tables/exceptions.py +10 -0
- zepben/ewb/database/sqlite/tables/extensions/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_reclose_delays.py +38 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_relay_info.py +21 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/table_pan_demand_response_functions.py +21 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/table_sites.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_loops.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_lv_feeders.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/table_ev_charging_units.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_distance_relays.py +28 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_thresholds.py +36 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_time_limits.py +34 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_functions.py +24 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_schemes.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_systems.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_voltage_relays.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_battery_controls.py +23 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_power_transformer_end_ratings.py +34 -0
- zepben/ewb/database/sqlite/tables/iec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_cable_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_no_load_tests.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_open_circuit_tests.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_overhead_wire_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_power_transformer_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_short_circuit_tests.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_shunt_compensator_info.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_switch_info.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_end_info.py +46 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_tank_info.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_test.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_wire_info.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_functions.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_info.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_organisation_roles.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_owners.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_assets.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_streetlights.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_structures.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_agreements.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_documents.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_address_field.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_addresses.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_locations.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_organisation_roles.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_organisations.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_position_points.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_street_addresses.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_town_details.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_customer_agreements.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_customers.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_pricing_structures.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_tariffs.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_current_transformer_info.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_potential_transformer_info.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/table_poles.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_device_functions.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_devices.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_meters.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_usage_points.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/operations/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/operations/table_operational_restrictions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_auxiliary_equipment.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_current_transformers.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_fault_indicators.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_potential_transformers.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_sensors.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_ac_dc_terminals.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_base_voltages.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_conducting_equipment.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_node_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_nodes.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curve_data.py +46 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curves.py +17 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_feeders.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_geographical_regions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_identified_objects.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_name_types.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_names.py +36 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_power_system_resources.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_sub_geographical_regions.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_substations.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_terminals.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_object_points.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_objects.py +31 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagrams.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_branches.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_equipment.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_battery_units.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_photo_voltaic_units.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_units.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_wind_units.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_accumulators.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_analogs.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_controls.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_discretes.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_io_points.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_measurements.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/protection/table_current_relays.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_controls.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_points.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_sources.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ac_line_segments.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_breakers.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_busbar_sections.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_clamps.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_conductors.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_connectors.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_cuts.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_disconnectors.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_earth_fault_compensators.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_connections.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumer_phases.py +37 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumers.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_source_phases.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_sources.py +44 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_fuses.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ground_disconnectors.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounding_impedances.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounds.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_jumpers.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_junctions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_linear_shunt_compensators.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_lines.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_load_break_switches.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_impedances.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_line_parameters.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_phase_impedances.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_sequence_impedances.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_petersen_coils.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_phase_impedance_data.py +52 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connection_phases.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connections.py +50 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformer_ends.py +43 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformers.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_protected_switches.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ratio_tap_changers.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reactive_capability_curves.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reclosers.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_cond_eq.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_controls.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_rotating_machines.py +36 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_series_compensators.py +25 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_shunt_compensators.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_static_var_compensator.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_switches.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_synchronous_machines.py +95 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changer_controls.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changers.py +25 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_ends.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_star_impedances.py +32 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/table_circuits.py +27 -0
- zepben/ewb/database/sqlite/tables/sqlite_table.py +45 -0
- zepben/ewb/database/sqlite/tables/table_metadata_data_sources.py +21 -0
- zepben/ewb/database/sqlite/tables/table_version.py +39 -0
- zepben/ewb/dataclassy/__init__.py +15 -0
- zepben/ewb/dataclassy/dataclass.py +192 -0
- zepben/ewb/dataclassy/decorator.py +35 -0
- zepben/ewb/dataclassy/functions.py +80 -0
- zepben/ewb/examples/__init__.py +6 -0
- zepben/ewb/examples/simple_test_network.py +158 -0
- zepben/ewb/exceptions.py +52 -0
- zepben/ewb/model/__init__.py +4 -0
- zepben/ewb/model/busbranch/__init__.py +4 -0
- zepben/ewb/model/busbranch/bus_branch.py +1051 -0
- zepben/ewb/model/cim/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/assetinfo/relay_info.py +128 -0
- zepben/ewb/model/cim/extensions/iec61968/metering/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/metering/pan_demand_reponse_function.py +112 -0
- zepben/ewb/model/cim/extensions/iec61970/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/core/site.py +37 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/loop.py +207 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/lv_feeder.py +258 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/production/ev_charging_unit.py +18 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/distance_relay.py +69 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/power_direction_kind.py +36 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_kind.py +112 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_function.py +448 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_scheme.py +97 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_system.py +97 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/relay_setting.py +35 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/voltage_relay.py +20 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control.py +36 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control_mode.py +83 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_cooling_type.py +57 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_end_rated_s.py +26 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/vector_group.py +293 -0
- zepben/ewb/model/cim/extensions/zbex.py +17 -0
- zepben/ewb/model/cim/iec61968/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assetinfo/cable_info.py +15 -0
- zepben/ewb/model/cim/iec61968/assetinfo/no_load_test.py +42 -0
- zepben/ewb/model/cim/iec61968/assetinfo/open_circuit_test.py +42 -0
- zepben/ewb/model/cim/iec61968/assetinfo/overhead_wire_info.py +15 -0
- zepben/ewb/model/cim/iec61968/assetinfo/power_transformer_info.py +103 -0
- zepben/ewb/model/cim/iec61968/assetinfo/short_circuit_test.py +67 -0
- zepben/ewb/model/cim/iec61968/assetinfo/shunt_compensator_info.py +26 -0
- zepben/ewb/model/cim/iec61968/assetinfo/switch_info.py +17 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_end_info.py +137 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_tank_info.py +108 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_test.py +26 -0
- zepben/ewb/model/cim/iec61968/assetinfo/wire_info.py +24 -0
- zepben/ewb/model/cim/iec61968/assetinfo/wire_material_kind.py +57 -0
- zepben/ewb/model/cim/iec61968/assets/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assets/asset.py +154 -0
- zepben/ewb/model/cim/iec61968/assets/asset_container.py +16 -0
- zepben/ewb/model/cim/iec61968/assets/asset_function.py +15 -0
- zepben/ewb/model/cim/iec61968/assets/asset_info.py +19 -0
- zepben/ewb/model/cim/iec61968/assets/asset_organisation_role.py +13 -0
- zepben/ewb/model/cim/iec61968/assets/asset_owner.py +13 -0
- zepben/ewb/model/cim/iec61968/assets/streetlight.py +29 -0
- zepben/ewb/model/cim/iec61968/assets/structure.py +16 -0
- zepben/ewb/model/cim/iec61968/common/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/common/agreement.py +16 -0
- zepben/ewb/model/cim/iec61968/common/document.py +36 -0
- zepben/ewb/model/cim/iec61968/common/location.py +129 -0
- zepben/ewb/model/cim/iec61968/common/organisation.py +15 -0
- zepben/ewb/model/cim/iec61968/common/organisation_role.py +22 -0
- zepben/ewb/model/cim/iec61968/common/position_point.py +44 -0
- zepben/ewb/model/cim/iec61968/common/street_address.py +28 -0
- zepben/ewb/model/cim/iec61968/common/street_detail.py +46 -0
- zepben/ewb/model/cim/iec61968/common/town_detail.py +25 -0
- zepben/ewb/model/cim/iec61968/customers/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/customers/customer.py +93 -0
- zepben/ewb/model/cim/iec61968/customers/customer_agreement.py +107 -0
- zepben/ewb/model/cim/iec61968/customers/customer_kind.py +69 -0
- zepben/ewb/model/cim/iec61968/customers/pricing_structure.py +88 -0
- zepben/ewb/model/cim/iec61968/customers/tariff.py +18 -0
- zepben/ewb/model/cim/iec61968/infiec61968/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/current_transformer_info.py +51 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/potential_transformer_info.py +33 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_construction_kind.py +69 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_function_kind.py +45 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/pole.py +87 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/streetlight_lamp_kind.py +27 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infcommon/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infcommon/ratio.py +34 -0
- zepben/ewb/model/cim/iec61968/metering/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py +152 -0
- zepben/ewb/model/cim/iec61968/metering/end_device.py +165 -0
- zepben/ewb/model/cim/iec61968/metering/end_device_function.py +17 -0
- zepben/ewb/model/cim/iec61968/metering/end_device_function_kind.py +48 -0
- zepben/ewb/model/cim/iec61968/metering/meter.py +28 -0
- zepben/ewb/model/cim/iec61968/metering/usage_point.py +186 -0
- zepben/ewb/model/cim/iec61968/operations/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/operations/operational_restriction.py +92 -0
- zepben/ewb/model/cim/iec61970/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/auxiliary_equipment.py +24 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/current_transformer.py +37 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/fault_indicator.py +18 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer.py +38 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer_kind.py +30 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/sensor.py +92 -0
- zepben/ewb/model/cim/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/core/ac_dc_terminal.py +16 -0
- zepben/ewb/model/cim/iec61970/base/core/base_voltage.py +17 -0
- zepben/ewb/model/cim/iec61970/base/core/conducting_equipment.py +198 -0
- zepben/ewb/model/cim/iec61970/base/core/connectivity_node.py +105 -0
- zepben/ewb/model/cim/iec61970/base/core/connectivity_node_container.py +15 -0
- zepben/ewb/model/cim/iec61970/base/core/curve.py +125 -0
- zepben/ewb/model/cim/iec61970/base/core/curve_data.py +29 -0
- zepben/ewb/model/cim/iec61970/base/core/equipment.py +366 -0
- zepben/ewb/model/cim/iec61970/base/core/equipment_container.py +199 -0
- zepben/ewb/model/cim/iec61970/base/core/feeder.py +260 -0
- zepben/ewb/model/cim/iec61970/base/core/geographical_region.py +82 -0
- zepben/ewb/model/cim/iec61970/base/core/identified_object.py +239 -0
- zepben/ewb/model/cim/iec61970/base/core/name.py +36 -0
- zepben/ewb/model/cim/iec61970/base/core/name_type.py +203 -0
- zepben/ewb/model/cim/iec61970/base/core/phase_code.py +202 -0
- zepben/ewb/model/cim/iec61970/base/core/power_system_resource.py +106 -0
- zepben/ewb/model/cim/iec61970/base/core/sub_geographical_region.py +93 -0
- zepben/ewb/model/cim/iec61970/base/core/substation.py +277 -0
- zepben/ewb/model/cim/iec61970/base/core/terminal.py +171 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram.py +109 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object.py +160 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object_point.py +25 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_style.py +28 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/orientation_kind.py +29 -0
- zepben/ewb/model/cim/iec61970/base/domain/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/domain/unit_symbol.py +494 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_branch.py +113 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_equipment.py +15 -0
- zepben/ewb/model/cim/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/battery_state_kind.py +39 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/battery_unit.py +108 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/photo_voltaic_unit.py +13 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_unit.py +28 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_wind_unit.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/meas/accumulator.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/accumulator_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/analog.py +18 -0
- zepben/ewb/model/cim/iec61970/base/meas/analog_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/control.py +26 -0
- zepben/ewb/model/cim/iec61970/base/meas/discrete.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/discrete_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/iopoint.py +16 -0
- zepben/ewb/model/cim/iec61970/base/meas/measurement.py +60 -0
- zepben/ewb/model/cim/iec61970/base/meas/measurement_value.py +21 -0
- zepben/ewb/model/cim/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/protection/current_relay.py +23 -0
- zepben/ewb/model/cim/iec61970/base/scada/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_control.py +22 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_point.py +16 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_source.py +22 -0
- zepben/ewb/model/cim/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/wires/ac_line_segment.py +214 -0
- zepben/ewb/model/cim/iec61970/base/wires/breaker.py +32 -0
- zepben/ewb/model/cim/iec61970/base/wires/busbar_section.py +19 -0
- zepben/ewb/model/cim/iec61970/base/wires/clamp.py +32 -0
- zepben/ewb/model/cim/iec61970/base/wires/conductor.py +49 -0
- zepben/ewb/model/cim/iec61970/base/wires/connector.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/cut.py +36 -0
- zepben/ewb/model/cim/iec61970/base/wires/disconnector.py +17 -0
- zepben/ewb/model/cim/iec61970/base/wires/earth_fault_compensator.py +21 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_connection.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_consumer.py +107 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_consumer_phase.py +56 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_source.py +172 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_source_phase.py +45 -0
- zepben/ewb/model/cim/iec61970/base/wires/fuse.py +23 -0
- zepben/ewb/model/cim/iec61970/base/wires/ground.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/ground_disconnector.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/grounding_impedance.py +19 -0
- zepben/ewb/model/cim/iec61970/base/wires/jumper.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/junction.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/line.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/linear_shunt_compensator.py +26 -0
- zepben/ewb/model/cim/iec61970/base/wires/load_break_switch.py +14 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_impedance.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_line_parameter.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_phase_impedance.py +99 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_sequence_impedance.py +43 -0
- zepben/ewb/model/cim/iec61970/base/wires/petersen_coil.py +22 -0
- zepben/ewb/model/cim/iec61970/base/wires/phase_impedance_data.py +37 -0
- zepben/ewb/model/cim/iec61970/base/wires/phase_shunt_connection_kind.py +40 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection.py +524 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection_phase.py +34 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_transformer.py +217 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_transformer_end.py +208 -0
- zepben/ewb/model/cim/iec61970/base/wires/protected_switch.py +96 -0
- zepben/ewb/model/cim/iec61970/base/wires/ratio_tap_changer.py +30 -0
- zepben/ewb/model/cim/iec61970/base/wires/reactive_capability_curve.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/recloser.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_cond_eq.py +45 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_control.py +173 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_control_mode_kind.py +48 -0
- zepben/ewb/model/cim/iec61970/base/wires/rotating_machine.py +36 -0
- zepben/ewb/model/cim/iec61970/base/wires/series_compensator.py +42 -0
- zepben/ewb/model/cim/iec61970/base/wires/shunt_compensator.py +59 -0
- zepben/ewb/model/cim/iec61970/base/wires/single_phase_kind.py +107 -0
- zepben/ewb/model/cim/iec61970/base/wires/static_var_compensator.py +40 -0
- zepben/ewb/model/cim/iec61970/base/wires/svc_control_mode.py +30 -0
- zepben/ewb/model/cim/iec61970/base/wires/switch.py +119 -0
- zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine.py +168 -0
- zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine_kind.py +46 -0
- zepben/ewb/model/cim/iec61970/base/wires/tap_changer.py +150 -0
- zepben/ewb/model/cim/iec61970/base/wires/tap_changer_control.py +49 -0
- zepben/ewb/model/cim/iec61970/base/wires/transformer_end.py +73 -0
- zepben/ewb/model/cim/iec61970/base/wires/transformer_star_impedance.py +48 -0
- zepben/ewb/model/cim/iec61970/base/wires/winding_connection.py +45 -0
- zepben/ewb/model/cim/iec61970/infiec61970/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/infiec61970/feeder/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/infiec61970/feeder/circuit.py +144 -0
- zepben/ewb/model/phases.py +168 -0
- zepben/ewb/model/resistance_reactance.py +40 -0
- zepben/ewb/services/__init__.py +4 -0
- zepben/ewb/services/common/__init__.py +16 -0
- zepben/ewb/services/common/base_service.py +383 -0
- zepben/ewb/services/common/base_service_comparator.py +394 -0
- zepben/ewb/services/common/difference.py +47 -0
- zepben/ewb/services/common/enum_mapper.py +55 -0
- zepben/ewb/services/common/meta/__init__.py +4 -0
- zepben/ewb/services/common/meta/data_source.py +16 -0
- zepben/ewb/services/common/meta/metadata_collection.py +28 -0
- zepben/ewb/services/common/meta/metadata_translations.py +47 -0
- zepben/ewb/services/common/meta/service_info.py +22 -0
- zepben/ewb/services/common/reference_resolvers.py +374 -0
- zepben/ewb/services/common/resolver.py +597 -0
- zepben/ewb/services/common/translator/__init__.py +4 -0
- zepben/ewb/services/common/translator/base_cim2proto.py +115 -0
- zepben/ewb/services/common/translator/base_proto2cim.py +146 -0
- zepben/ewb/services/common/translator/service_differences.py +81 -0
- zepben/ewb/services/common/translator/util.py +75 -0
- zepben/ewb/services/customer/__init__.py +4 -0
- zepben/ewb/services/customer/customer_service_comparator.py +52 -0
- zepben/ewb/services/customer/customers.py +23 -0
- zepben/ewb/services/customer/translator/__init__.py +21 -0
- zepben/ewb/services/customer/translator/customer_cim2proto.py +71 -0
- zepben/ewb/services/customer/translator/customer_enum_mappers.py +18 -0
- zepben/ewb/services/customer/translator/customer_proto2cim.py +87 -0
- zepben/ewb/services/diagram/__init__.py +4 -0
- zepben/ewb/services/diagram/diagram_service_comparator.py +39 -0
- zepben/ewb/services/diagram/diagrams.py +107 -0
- zepben/ewb/services/diagram/translator/__init__.py +11 -0
- zepben/ewb/services/diagram/translator/diagram_cim2proto.py +51 -0
- zepben/ewb/services/diagram/translator/diagram_enum_mappers.py +21 -0
- zepben/ewb/services/diagram/translator/diagram_proto2cim.py +61 -0
- zepben/ewb/services/measurement/__init__.py +4 -0
- zepben/ewb/services/measurement/measurements.py +35 -0
- zepben/ewb/services/measurement/translator/__init__.py +6 -0
- zepben/ewb/services/measurement/translator/measurement_cim2proto.py +42 -0
- zepben/ewb/services/measurement/translator/measurement_proto2cim.py +52 -0
- zepben/ewb/services/network/__init__.py +4 -0
- zepben/ewb/services/network/network_extensions.py +119 -0
- zepben/ewb/services/network/network_service.py +302 -0
- zepben/ewb/services/network/network_service_comparator.py +1322 -0
- zepben/ewb/services/network/network_state.py +36 -0
- zepben/ewb/services/network/tracing/__init__.py +4 -0
- zepben/ewb/services/network/tracing/busbranch_trace.py +36 -0
- zepben/ewb/services/network/tracing/connectivity/__init__.py +4 -0
- zepben/ewb/services/network/tracing/connectivity/connectivity_result.py +105 -0
- zepben/ewb/services/network/tracing/connectivity/nominal_phase_path.py +23 -0
- zepben/ewb/services/network/tracing/connectivity/phase_paths.py +70 -0
- zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_connected.py +226 -0
- zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_internal.py +64 -0
- zepben/ewb/services/network/tracing/connectivity/transformer_phase_paths.py +202 -0
- zepben/ewb/services/network/tracing/connectivity/xy_candidate_phase_paths.py +235 -0
- zepben/ewb/services/network/tracing/connectivity/xy_phase_step.py +24 -0
- zepben/ewb/services/network/tracing/feeder/__init__.py +4 -0
- zepben/ewb/services/network/tracing/feeder/assign_to_feeders.py +202 -0
- zepben/ewb/services/network/tracing/feeder/assign_to_lv_feeders.py +202 -0
- zepben/ewb/services/network/tracing/feeder/clear_direction.py +80 -0
- zepben/ewb/services/network/tracing/feeder/direction_status.py +133 -0
- zepben/ewb/services/network/tracing/feeder/feeder_direction.py +107 -0
- zepben/ewb/services/network/tracing/feeder/set_direction.py +143 -0
- zepben/ewb/services/network/tracing/find_swer_equipment.py +175 -0
- zepben/ewb/services/network/tracing/networktrace/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/actions/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/actions/equipment_tree_builder.py +104 -0
- zepben/ewb/services/network/tracing/networktrace/actions/tree_node.py +35 -0
- zepben/ewb/services/network/tracing/networktrace/compute_data.py +60 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/conditions.py +73 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/direction_condition.py +63 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/equipment_step_limit_condition.py +26 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/equipment_type_step_limit_condition.py +44 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_queue_condition.py +67 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_stop_condition.py +65 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/open_condition.py +39 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace.py +433 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_action_type.py +42 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_queue_next.py +84 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_step.py +128 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_step_path_provider.py +351 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_tracker.py +39 -0
- zepben/ewb/services/network/tracing/networktrace/operators/__init__.py +14 -0
- zepben/ewb/services/network/tracing/networktrace/operators/equipment_container_state_operators.py +264 -0
- zepben/ewb/services/network/tracing/networktrace/operators/feeder_direction_state_operations.py +181 -0
- zepben/ewb/services/network/tracing/networktrace/operators/in_service_state_operators.py +76 -0
- zepben/ewb/services/network/tracing/networktrace/operators/network_state_operators.py +120 -0
- zepben/ewb/services/network/tracing/networktrace/operators/open_state_operators.py +104 -0
- zepben/ewb/services/network/tracing/networktrace/operators/phase_state_operators.py +56 -0
- zepben/ewb/services/network/tracing/networktrace/tracing.py +132 -0
- zepben/ewb/services/network/tracing/phases/__init__.py +4 -0
- zepben/ewb/services/network/tracing/phases/phase_inferrer.py +205 -0
- zepben/ewb/services/network/tracing/phases/phase_status.py +101 -0
- zepben/ewb/services/network/tracing/phases/remove_phases.py +143 -0
- zepben/ewb/services/network/tracing/phases/set_phases.py +490 -0
- zepben/ewb/services/network/tracing/traversal/__init__.py +4 -0
- zepben/ewb/services/network/tracing/traversal/context_value_computer.py +63 -0
- zepben/ewb/services/network/tracing/traversal/debug_logging.py +124 -0
- zepben/ewb/services/network/tracing/traversal/queue.py +112 -0
- zepben/ewb/services/network/tracing/traversal/queue_condition.py +75 -0
- zepben/ewb/services/network/tracing/traversal/step_action.py +83 -0
- zepben/ewb/services/network/tracing/traversal/step_context.py +59 -0
- zepben/ewb/services/network/tracing/traversal/stop_condition.py +57 -0
- zepben/ewb/services/network/tracing/traversal/traversal.py +634 -0
- zepben/ewb/services/network/tracing/traversal/traversal_condition.py +22 -0
- zepben/ewb/services/network/tracing/traversal/weighted_priority_queue.py +85 -0
- zepben/ewb/services/network/tracing/util.py +93 -0
- zepben/ewb/services/network/translator/__init__.py +392 -0
- zepben/ewb/services/network/translator/network_cim2proto.py +1867 -0
- zepben/ewb/services/network/translator/network_enum_mappers.py +78 -0
- zepben/ewb/services/network/translator/network_proto2cim.py +2201 -0
- zepben/ewb/services/services.py +48 -0
- zepben/ewb/streaming/__init__.py +4 -0
- zepben/ewb/streaming/data/__init__.py +4 -0
- zepben/ewb/streaming/data/current_state_event.py +314 -0
- zepben/ewb/streaming/data/current_state_event_batch.py +25 -0
- zepben/ewb/streaming/data/set_current_states_status.py +286 -0
- zepben/ewb/streaming/exceptions.py +14 -0
- zepben/ewb/streaming/get/__init__.py +4 -0
- zepben/ewb/streaming/get/consumer.py +209 -0
- zepben/ewb/streaming/get/customer_consumer.py +111 -0
- zepben/ewb/streaming/get/diagram_consumer.py +107 -0
- zepben/ewb/streaming/get/hierarchy/__init__.py +4 -0
- zepben/ewb/streaming/get/hierarchy/data.py +27 -0
- zepben/ewb/streaming/get/included_energized_containers.py +36 -0
- zepben/ewb/streaming/get/included_energizing_containers.py +36 -0
- zepben/ewb/streaming/get/network_consumer.py +870 -0
- zepben/ewb/streaming/get/query_network_state_client.py +64 -0
- zepben/ewb/streaming/get/query_network_state_service.py +94 -0
- zepben/ewb/streaming/grpc/__init__.py +4 -0
- zepben/ewb/streaming/grpc/auth_token_plugin.py +24 -0
- zepben/ewb/streaming/grpc/connect.py +209 -0
- zepben/ewb/streaming/grpc/grpc.py +107 -0
- zepben/ewb/streaming/grpc/grpc_channel_builder.py +190 -0
- zepben/ewb/streaming/mutations/__init__.py +4 -0
- zepben/ewb/streaming/mutations/update_network_state_client.py +80 -0
- zepben/ewb/streaming/mutations/update_network_state_service.py +61 -0
- zepben/ewb/testing/__init__.py +4 -0
- zepben/ewb/testing/test_network_builder.py +816 -0
- zepben/ewb/types.py +17 -0
- zepben/ewb/util.py +200 -0
- zepben_ewb-1.0.0.dist-info/METADATA +90 -0
- zepben_ewb-1.0.0.dist-info/RECORD +641 -0
- zepben_ewb-1.0.0.dist-info/WHEEL +5 -0
- zepben_ewb-1.0.0.dist-info/licenses/LICENSE +374 -0
- zepben_ewb-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Copyright 2024 Zeppelin Bend Pty Ltd
|
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
|
|
6
|
+
__all__ = ["QueryNetworkStateClient"]
|
|
7
|
+
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from typing import List, Callable, AsyncGenerator
|
|
10
|
+
|
|
11
|
+
from zepben.protobuf.ns.network_state_pb2_grpc import QueryNetworkStateServiceStub
|
|
12
|
+
from zepben.protobuf.ns.network_state_requests_pb2 import GetCurrentStatesRequest
|
|
13
|
+
|
|
14
|
+
from zepben.ewb.streaming.data.current_state_event import CurrentStateEvent
|
|
15
|
+
from zepben.ewb.streaming.data.current_state_event_batch import CurrentStateEventBatch
|
|
16
|
+
from zepben.ewb.streaming.data.set_current_states_status import SetCurrentStatesStatus
|
|
17
|
+
from zepben.ewb.streaming.grpc.grpc import GrpcClient
|
|
18
|
+
from zepben.ewb.util import datetime_to_timestamp
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class QueryNetworkStateClient(GrpcClient):
|
|
22
|
+
"""
|
|
23
|
+
A client class that provides functionality to interact with the gRPC service for querying network states.
|
|
24
|
+
A gRPC channel or stub must be provided.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
_stub: QueryNetworkStateServiceStub = None
|
|
28
|
+
|
|
29
|
+
def __init__(self, channel=None, stub: QueryNetworkStateServiceStub = None, error_handlers: List[Callable[[Exception], bool]] = None, timeout: int = 60):
|
|
30
|
+
super().__init__(error_handlers=error_handlers, timeout=timeout)
|
|
31
|
+
if channel is None and stub is None:
|
|
32
|
+
raise ValueError("Must provide either a channel or a stub")
|
|
33
|
+
if stub is not None:
|
|
34
|
+
self._stub = stub
|
|
35
|
+
else:
|
|
36
|
+
self._stub = QueryNetworkStateServiceStub(channel)
|
|
37
|
+
|
|
38
|
+
async def get_current_states(self, query_id: int, from_datetime: datetime, to_datetime: datetime) -> AsyncGenerator[CurrentStateEventBatch, None]:
|
|
39
|
+
"""
|
|
40
|
+
Asynchronously retrieves a collection containing CurrentStateEvent objects, representing the network states
|
|
41
|
+
within a specified time range.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
query_id: A unique identifier for the query being processed.
|
|
45
|
+
from_datetime: The start time, as a datetime, for the query range.
|
|
46
|
+
to_datetime: The end time, as a datetime, for the query range.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
A stream of batched network state events in the specified time range.
|
|
50
|
+
"""
|
|
51
|
+
request = GetCurrentStatesRequest(
|
|
52
|
+
messageId=query_id,
|
|
53
|
+
fromTimestamp=datetime_to_timestamp(from_datetime),
|
|
54
|
+
toTimestamp=datetime_to_timestamp(to_datetime)
|
|
55
|
+
)
|
|
56
|
+
async for response in self._stub.getCurrentStates(request):
|
|
57
|
+
yield CurrentStateEventBatch(response.messageId, [CurrentStateEvent.from_pb(event) for event in response.event])
|
|
58
|
+
|
|
59
|
+
def report_batch_status(self, status: SetCurrentStatesStatus):
|
|
60
|
+
"""
|
|
61
|
+
Send a response to a previous `getCurrentStates` request to let the server know how we handled its response.
|
|
62
|
+
:param status: The batch status to report.
|
|
63
|
+
"""
|
|
64
|
+
self._stub.reportBatchStatus(iter([status.to_pb()]))
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Copyright 2024 Zeppelin Bend Pty Ltd
|
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
|
|
6
|
+
__all__ = ["QueryNetworkStateService"]
|
|
7
|
+
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from typing import Callable, AsyncGenerator, Optional
|
|
10
|
+
|
|
11
|
+
from google.protobuf import empty_pb2
|
|
12
|
+
from zepben.protobuf.ns.network_state_pb2_grpc import QueryNetworkStateServiceServicer
|
|
13
|
+
from zepben.protobuf.ns.network_state_requests_pb2 import GetCurrentStatesRequest
|
|
14
|
+
from zepben.protobuf.ns.network_state_responses_pb2 import GetCurrentStatesResponse, SetCurrentStatesResponse
|
|
15
|
+
|
|
16
|
+
from zepben.ewb.streaming.data.current_state_event_batch import CurrentStateEventBatch
|
|
17
|
+
from zepben.ewb.streaming.data.set_current_states_status import SetCurrentStatesStatus
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class QueryNetworkStateService(QueryNetworkStateServiceServicer):
|
|
21
|
+
"""
|
|
22
|
+
A service class that provides a simplified interface for retrieving current state events
|
|
23
|
+
via gRPC without exposing the underlying complexity of gRPC mechanisms.
|
|
24
|
+
|
|
25
|
+
This class serves as a wrapper around the gRPC-generated service implementation,
|
|
26
|
+
allowing users to interact with it using a more convenient function type.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
on_get_current_states: An function that retrieves CurrentStateEvent objects within the specified time range.
|
|
30
|
+
on_current_states_status: A callback triggered when the response status of an event returned via `on_get_current_states` is received from the client.
|
|
31
|
+
on_processing_error: A function that takes a message and optional cause. Called when `on_current_states_status` raises an exception, or the
|
|
32
|
+
`SetCurrentStatesResponse` is for an unknown event status.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
on_get_current_states: Callable[[datetime, datetime], AsyncGenerator[CurrentStateEventBatch, None]],
|
|
38
|
+
on_current_states_status: Callable[[SetCurrentStatesStatus], None],
|
|
39
|
+
on_processing_error: Callable[[str, Optional[Exception]], None]
|
|
40
|
+
):
|
|
41
|
+
self.on_get_current_states = on_get_current_states
|
|
42
|
+
self.on_current_states_status = on_current_states_status
|
|
43
|
+
self.on_processing_error = on_processing_error
|
|
44
|
+
|
|
45
|
+
async def getCurrentStates(self, request: GetCurrentStatesRequest, context) -> AsyncGenerator[GetCurrentStatesResponse, None]:
|
|
46
|
+
"""
|
|
47
|
+
Handles the incoming request for retrieving current state events.
|
|
48
|
+
|
|
49
|
+
You shouldn't be calling this method directly, it will be invoked automatically via the gRPC engine. Each
|
|
50
|
+
`GetCurrentStatesRequest` retrieves the corresponding current state events using the `onGetCurrentStates`
|
|
51
|
+
callback function passed in the constructor, and asynchronously returns a `GetCurrentStatesResponse`.
|
|
52
|
+
|
|
53
|
+
It acts as a bridge between the gRPC request and the business logic that fetches the current state events.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
request: The request object containing parameters for fetching current state events,
|
|
57
|
+
including the time range for the query.
|
|
58
|
+
context: The gRPC context.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
A stream of gRPC response messages
|
|
62
|
+
"""
|
|
63
|
+
async for batch in self.on_get_current_states(request.fromTimestamp.ToDatetime(), request.toTimestamp.ToDatetime()):
|
|
64
|
+
yield GetCurrentStatesResponse(messageId=batch.batch_id, event=[event.to_pb() for event in batch.events])
|
|
65
|
+
|
|
66
|
+
# noinspection PyUnresolvedReferences
|
|
67
|
+
async def reportBatchStatus(self, status_responses: AsyncGenerator[SetCurrentStatesResponse, None], context) -> empty_pb2.Empty:
|
|
68
|
+
"""
|
|
69
|
+
Handles incoming status reports in response to an event batch returned via `getCurrentStates`.
|
|
70
|
+
|
|
71
|
+
You shouldn't be calling this method directly, it will be invoked automatically via the gRPC engine. Each
|
|
72
|
+
`SetCurrentStatesResponse` will trigger the `on_current_states_status` callback function passed in the constructor.
|
|
73
|
+
|
|
74
|
+
It acts as a bridge between the gRPC request and the business logic that validates/logs the status of event
|
|
75
|
+
handling. Any errors in this handling, or unexpected status message will trigger the `on_processing_error`
|
|
76
|
+
callback function passed in the constructor.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
status_responses: The request object stream (yes you read that correctly that the request is a response...) containing the response to our current state batch.
|
|
80
|
+
context: The gRPC context.
|
|
81
|
+
"""
|
|
82
|
+
async for status_response in status_responses:
|
|
83
|
+
status = SetCurrentStatesStatus.from_pb(status_response)
|
|
84
|
+
if status is not None:
|
|
85
|
+
try:
|
|
86
|
+
self.on_current_states_status(status)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
message = f"Exception thrown in status response handler for batch `{status_response.messageId}`: {str(e)}"
|
|
89
|
+
self.on_processing_error(message, e)
|
|
90
|
+
else:
|
|
91
|
+
self.on_processing_error(f"Failed to decode status response for batch `{status_response.messageId}`: Unsupported type {status_response.WhichOneof('status')}", None)
|
|
92
|
+
|
|
93
|
+
# noinspection PyUnresolvedReferences
|
|
94
|
+
return empty_pb2.Empty()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright 2024 Zeppelin Bend Pty Ltd
|
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
|
|
6
|
+
__all__ = ["AuthTokenPlugin"]
|
|
7
|
+
|
|
8
|
+
import grpc
|
|
9
|
+
from zepben.ewb.auth import ZepbenTokenFetcher
|
|
10
|
+
|
|
11
|
+
_AUTH_HEADER_KEY = 'authorization'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AuthTokenPlugin(grpc.AuthMetadataPlugin):
|
|
15
|
+
"""
|
|
16
|
+
Metadata plugin that injects tokens into the metadata of each call.
|
|
17
|
+
Tokens are fetched using a provided :class:`ZepbenTokenFetcher`.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, token_fetcher: ZepbenTokenFetcher):
|
|
21
|
+
self.token_fetcher = token_fetcher
|
|
22
|
+
|
|
23
|
+
def __call__(self, context, callback):
|
|
24
|
+
callback(((_AUTH_HEADER_KEY, self.token_fetcher.fetch_token()),), None)
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Copyright 2024 Zeppelin Bend Pty Ltd
|
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
|
|
6
|
+
__all__ = ["connect_tls", "connect_insecure", "connect_with_password", "connect_with_secret", "connect_with_identity", "connect_with_token"]
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Union
|
|
9
|
+
|
|
10
|
+
import grpc
|
|
11
|
+
from zepben.ewb.auth import ZepbenTokenFetcher, create_token_fetcher, create_token_fetcher_managed_identity
|
|
12
|
+
|
|
13
|
+
from zepben.ewb import GrpcChannelBuilder
|
|
14
|
+
|
|
15
|
+
GRPC_READY_TIMEOUT = 20 # seconds
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def connect_insecure(
|
|
19
|
+
host: str = "localhost",
|
|
20
|
+
rpc_port: int = 50051,
|
|
21
|
+
**kwargs
|
|
22
|
+
) -> grpc.aio.Channel:
|
|
23
|
+
"""
|
|
24
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service over plaintext.
|
|
25
|
+
|
|
26
|
+
:param host: The hostname where the gRPC service is hosted
|
|
27
|
+
:param rpc_port: The port of the gRPC service
|
|
28
|
+
:return: A plaintext connection to the gRPC service
|
|
29
|
+
"""
|
|
30
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).build(**kwargs)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def connect_tls(
|
|
34
|
+
host: str = "localhost",
|
|
35
|
+
rpc_port: int = 50051,
|
|
36
|
+
ca_filename: Optional[str] = None,
|
|
37
|
+
**kwargs
|
|
38
|
+
) -> grpc.aio.Channel:
|
|
39
|
+
"""
|
|
40
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service using SSL/TLS transport security.
|
|
41
|
+
|
|
42
|
+
:param host: The hostname where the gRPC service is hosted
|
|
43
|
+
:param rpc_port: The port of the gRPC service
|
|
44
|
+
:param ca_filename: The filename of a truststore containing additional trusted root certificates. This parameter is optional
|
|
45
|
+
and defaults to null, in which case only the system CAs are used to verify certificates.
|
|
46
|
+
:return:An encrypted connection to the gRPC service
|
|
47
|
+
"""
|
|
48
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).make_secure(root_certificates=ca_filename).build(**kwargs)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def connect_with_identity(host: str,
|
|
52
|
+
rpc_port: int,
|
|
53
|
+
identity_url: str,
|
|
54
|
+
ca_filename: Optional[str] = None,
|
|
55
|
+
verify_auth: bool = True,
|
|
56
|
+
**kwargs) -> grpc.aio.Channel:
|
|
57
|
+
"""
|
|
58
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service using SSL/TLS transport security and the OAuth client credentials flow,
|
|
59
|
+
utilising an Azure managed identity for fetching access tokens.
|
|
60
|
+
|
|
61
|
+
:param host: The hostname where the gRPC service is hosted
|
|
62
|
+
:param rpc_port: The port of the gRPC service
|
|
63
|
+
:param identity_url: The URL including resource identifier (API) to fetch token from. Typically something like:
|
|
64
|
+
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=<SOME_IDENTIFIER>
|
|
65
|
+
:param ca_filename: The filename of a truststore containing additional trusted root certificates. This parameter is optional
|
|
66
|
+
and defaults to null, in which case only the system CAs are used to verify certificates.
|
|
67
|
+
:param verify_auth: Passed through to `requests.post()` when fetching access tokens to verify certificates of the auth service.
|
|
68
|
+
:return: An authenticated, encrypted connection to the gRPC service based on OAuth2 flows. If the authentication configuration specifies that no
|
|
69
|
+
authentication is required, a non-authenticated, encrypted connection is returned instead.
|
|
70
|
+
"""
|
|
71
|
+
token_fetcher = create_token_fetcher_managed_identity(identity_url, verify_auth)
|
|
72
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).make_secure(root_certificates=ca_filename).with_token_fetcher(token_fetcher).build(**kwargs)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def connect_with_secret(
|
|
76
|
+
client_id: str,
|
|
77
|
+
client_secret: str,
|
|
78
|
+
host: str = "localhost",
|
|
79
|
+
rpc_port: int = 50051,
|
|
80
|
+
conf_address: Optional[str] = None,
|
|
81
|
+
verify_conf: Union[bool, str] = True,
|
|
82
|
+
verify_auth: Union[bool, str] = True,
|
|
83
|
+
ca_filename: Optional[str] = None,
|
|
84
|
+
**kwargs
|
|
85
|
+
) -> grpc.aio.Channel:
|
|
86
|
+
"""
|
|
87
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service using SSL/TLS transport security and the OAuth client credentials flow.
|
|
88
|
+
The OAuth provider's domain and the "audience" parameter of the token request are fetched as JSON from a specified URL.
|
|
89
|
+
|
|
90
|
+
:param client_id: The client ID of the OAuth application to authenticate for
|
|
91
|
+
:param client_secret: The client secret of the OAuth application to authenticate for
|
|
92
|
+
:param host: The hostname where the gRPC service is hosted
|
|
93
|
+
:param rpc_port: The port of the gRPC service
|
|
94
|
+
:param conf_address: The address of the authentication configuration
|
|
95
|
+
:param verify_conf: Passed through to `requests.get()` when fetching the authentication configuration
|
|
96
|
+
:param verify_auth: Passed through to `requests.post()` when fetching access tokens to verify certificates of the auth service.
|
|
97
|
+
:param ca_filename: The filename of a truststore containing additional trusted root certificates. This parameter is optional
|
|
98
|
+
and defaults to null, in which case only the system CAs are used to verify certificates.
|
|
99
|
+
:return: An authenticated, encrypted connection to the gRPC service based on OAuth2 flows. If the authentication configuration specifies that no
|
|
100
|
+
authentication is required, a non-authenticated, encrypted connection is returned instead.
|
|
101
|
+
"""
|
|
102
|
+
token_fetcher = create_token_fetcher(
|
|
103
|
+
conf_address=conf_address or f"https://{host}/ewb/auth",
|
|
104
|
+
verify_conf=verify_conf,
|
|
105
|
+
verify_auth=verify_auth
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if token_fetcher:
|
|
109
|
+
return _connect_with_secret_using_token_fetcher(token_fetcher, client_id, client_secret, host, rpc_port, ca_filename, **kwargs)
|
|
110
|
+
else:
|
|
111
|
+
return connect_tls(host, rpc_port, ca_filename, **kwargs)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def connect_with_token(
|
|
115
|
+
access_token: str,
|
|
116
|
+
host: str = "localhost",
|
|
117
|
+
rpc_port: int = 50051,
|
|
118
|
+
ca_filename: Optional[str] = None,
|
|
119
|
+
**kwargs
|
|
120
|
+
) -> grpc.aio.Channel:
|
|
121
|
+
"""
|
|
122
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service using SSL/TLS transport security and a personal access token generated from Evolve App Server or Evolve Web Client.
|
|
123
|
+
|
|
124
|
+
:param access_token: The token string of the client generated using Evolve App
|
|
125
|
+
:param host: The hostname where the gRPC service is hosted
|
|
126
|
+
:param rpc_port: The port of the gRPC service
|
|
127
|
+
:param ca_filename: The filename of a truststore containing additional trusted root certificates. This parameter is optional
|
|
128
|
+
and defaults to null, in which case only the system CAs are used to verify certificates.
|
|
129
|
+
:return: An authenticated, encrypted connection to the gRPC service based on OAuth2 flows. If the authentication configuration specifies that no
|
|
130
|
+
authentication is required, a non-authenticated, encrypted connection is returned instead.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).make_secure(root_certificates=ca_filename).with_client_token(access_token).build(**kwargs)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def connect_with_password(
|
|
137
|
+
client_id: str,
|
|
138
|
+
username: str,
|
|
139
|
+
password: str,
|
|
140
|
+
host: str = "localhost",
|
|
141
|
+
rpc_port: int = 50051,
|
|
142
|
+
conf_address: Optional[str] = None,
|
|
143
|
+
verify_conf: Union[bool, str] = True,
|
|
144
|
+
verify_auth: Union[bool, str] = True,
|
|
145
|
+
ca_filename: Optional[str] = None,
|
|
146
|
+
**kwargs
|
|
147
|
+
) -> grpc.aio.Channel:
|
|
148
|
+
"""
|
|
149
|
+
Create a :class:`grpc.aio.Channel` that communicates with the gRPC service using SSL/TLS transport security and the OAuth password grant flow.
|
|
150
|
+
The OAuth provider's domain and the "audience" parameter of the token request are fetched as JSON from a specified URL.
|
|
151
|
+
|
|
152
|
+
:param client_id: The client ID of the OAuth application to authenticate for
|
|
153
|
+
:param username: The username of the user to authenticate with
|
|
154
|
+
:param password: The password of the user to authenticate with
|
|
155
|
+
:param host: The hostname where the gRPC service is hosted
|
|
156
|
+
:param rpc_port: The port of the gRPC service
|
|
157
|
+
:param conf_address: The address of the authentication configuration
|
|
158
|
+
:param verify_conf: Passed through to `requests.get()` when fetching the authentication configuration
|
|
159
|
+
:param verify_auth: Passed through to `requests.post()` when fetching access tokens to verify certificates of the auth service.
|
|
160
|
+
:param ca_filename: The filename of a truststore containing additional trusted root certificates. This parameter is optional
|
|
161
|
+
and defaults to null, in which case only the system CAs are used to verify certificates.
|
|
162
|
+
:return: An authenticated, encrypted connection to the gRPC service based on OAuth2 flows. If the authentication configuration specifies that no
|
|
163
|
+
authentication is required, a non-authenticated, encrypted connection is returned instead.
|
|
164
|
+
"""
|
|
165
|
+
token_fetcher = create_token_fetcher(
|
|
166
|
+
conf_address=conf_address or f"https://{host}/ewb/auth",
|
|
167
|
+
verify_conf=verify_conf,
|
|
168
|
+
verify_auth=verify_auth
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
if token_fetcher:
|
|
172
|
+
return _connect_with_password_using_token_fetcher(token_fetcher, client_id, username, password, host, rpc_port, ca_filename, **kwargs)
|
|
173
|
+
else:
|
|
174
|
+
return connect_tls(host, rpc_port, ca_filename, **kwargs)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _connect_with_secret_using_token_fetcher(
|
|
178
|
+
token_fetcher: ZepbenTokenFetcher,
|
|
179
|
+
client_id: str,
|
|
180
|
+
client_secret: str,
|
|
181
|
+
host: str,
|
|
182
|
+
rpc_port: int,
|
|
183
|
+
ca_filename: Optional[str],
|
|
184
|
+
**kwargs
|
|
185
|
+
) -> grpc.aio.Channel:
|
|
186
|
+
token_fetcher.token_request_data["client_id"] = client_id
|
|
187
|
+
token_fetcher.token_request_data["client_secret"] = client_secret
|
|
188
|
+
token_fetcher.token_request_data["grant_type"] = "client_credentials"
|
|
189
|
+
|
|
190
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).make_secure(root_certificates=ca_filename).with_token_fetcher(token_fetcher).build(**kwargs)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _connect_with_password_using_token_fetcher(
|
|
194
|
+
token_fetcher: ZepbenTokenFetcher,
|
|
195
|
+
client_id: str,
|
|
196
|
+
username: str,
|
|
197
|
+
password: str,
|
|
198
|
+
host: str,
|
|
199
|
+
rpc_port: int,
|
|
200
|
+
ca_filename: Optional[str],
|
|
201
|
+
**kwargs
|
|
202
|
+
) -> grpc.aio.Channel:
|
|
203
|
+
token_fetcher.token_request_data["client_id"] = client_id
|
|
204
|
+
token_fetcher.token_request_data["username"] = username
|
|
205
|
+
token_fetcher.token_request_data["password"] = password
|
|
206
|
+
token_fetcher.token_request_data["grant_type"] = "password"
|
|
207
|
+
token_fetcher.token_request_data["scope"] = "offline_access"
|
|
208
|
+
|
|
209
|
+
return GrpcChannelBuilder().for_address(host, rpc_port).make_secure(root_certificates=ca_filename).with_token_fetcher(token_fetcher).build(**kwargs)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Copyright 2024 Zeppelin Bend Pty Ltd
|
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
__all__ = ["GrpcResult", "GrpcClient"]
|
|
9
|
+
|
|
10
|
+
from typing import TypeVar, Generic, Callable, List, Union, Coroutine
|
|
11
|
+
|
|
12
|
+
from zepben.ewb.dataclassy import dataclass
|
|
13
|
+
|
|
14
|
+
T = TypeVar("T")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(slots=True)
|
|
18
|
+
class GrpcResult(Generic[T]):
|
|
19
|
+
result: Union[T, Exception]
|
|
20
|
+
was_error_handled: bool = False
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def value(self) -> T:
|
|
24
|
+
if self.result is not None and isinstance(self.result, Exception):
|
|
25
|
+
raise TypeError("You can only call value on a successful result.")
|
|
26
|
+
return self.result
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def thrown(self) -> Exception:
|
|
30
|
+
if self.result is None or not isinstance(self.result, Exception):
|
|
31
|
+
raise TypeError("You can only call thrown on an unsuccessful result.")
|
|
32
|
+
return self.result
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def was_successful(self):
|
|
36
|
+
return not self.was_failure
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def was_failure(self):
|
|
40
|
+
return isinstance(self.result, Exception)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def was_error_unhandled(self):
|
|
44
|
+
return not self.was_error_handled
|
|
45
|
+
|
|
46
|
+
def on_success(self, handler: Callable[[T], None]) -> GrpcResult[T]:
|
|
47
|
+
"""Calls `handler` with the `result` if this `was_successful`"""
|
|
48
|
+
if self.was_successful:
|
|
49
|
+
handler(self.result)
|
|
50
|
+
return self
|
|
51
|
+
|
|
52
|
+
def on_error(self, handler: Callable[[Exception, bool], GrpcResult[T]]) -> GrpcResult[T]:
|
|
53
|
+
"""Calls `handler` with the `thrown` exception and `self.was_error_handled` if `self.was_failure`."""
|
|
54
|
+
if self.was_failure and self.was_error_handled:
|
|
55
|
+
return handler(self.result, self.was_error_handled)
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
def on_handled_error(self, handler: Callable[[Exception], None]) -> GrpcResult[T]:
|
|
59
|
+
"""Calls `handler` with the `thrown` exception if `self.was_failure` only if `self.was_error_handled`."""
|
|
60
|
+
if self.was_failure and self.was_error_handled:
|
|
61
|
+
handler(self.result)
|
|
62
|
+
return self
|
|
63
|
+
|
|
64
|
+
def on_unhandled_error(self, handler: Callable[[Exception], None]) -> GrpcResult[T]:
|
|
65
|
+
"""Calls `handler` with the `thrown` exception if `self.was_failure` only if not `self.was_error_handled`."""
|
|
66
|
+
if self.was_failure and not self.was_error_handled:
|
|
67
|
+
handler(self.result)
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
def throw_on_error(self) -> GrpcResult[T]:
|
|
71
|
+
"""Throws `self.result` if `self.was_failure`"""
|
|
72
|
+
if self.was_failure:
|
|
73
|
+
raise self.result
|
|
74
|
+
return self
|
|
75
|
+
|
|
76
|
+
def throw_on_unhandled_error(self) -> GrpcResult[T]:
|
|
77
|
+
"""Throws `self.result` only if `self.was_failure` and not `self.was_error_handled`"""
|
|
78
|
+
if self.was_failure and not self.was_error_handled:
|
|
79
|
+
raise self.result
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(init=False, slots=True)
|
|
84
|
+
class GrpcClient(object):
|
|
85
|
+
error_handlers: List[Callable[[Exception], bool]] = []
|
|
86
|
+
|
|
87
|
+
timeout: int = 0
|
|
88
|
+
'''Timeout for client gRPC requests'''
|
|
89
|
+
|
|
90
|
+
def __init__(self, error_handlers: List[Callable[[Exception], bool]] = None, timeout: int = 60):
|
|
91
|
+
if error_handlers:
|
|
92
|
+
self.error_handlers = error_handlers.copy()
|
|
93
|
+
else:
|
|
94
|
+
self.error_handlers = list()
|
|
95
|
+
self.timeout = timeout
|
|
96
|
+
|
|
97
|
+
def try_handle_error(self, e: Exception) -> bool:
|
|
98
|
+
for handler in self.error_handlers:
|
|
99
|
+
if handler(e):
|
|
100
|
+
return True
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
async def try_rpc(self, rpc: Callable[[], Coroutine[None, None, T]]) -> GrpcResult[T]:
|
|
104
|
+
try:
|
|
105
|
+
return GrpcResult(await rpc())
|
|
106
|
+
except Exception as e:
|
|
107
|
+
return GrpcResult(e, self.try_handle_error(e))
|