validio-sdk 0.0.1__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- validio_sdk-0.2.0/PKG-INFO +35 -0
- validio_sdk-0.2.0/README_PUBLIC.md +14 -0
- validio_sdk-0.2.0/pyproject.toml +169 -0
- validio_sdk-0.2.0/validio_sdk/__init__.py +27 -0
- validio_sdk-0.2.0/validio_sdk/code/apply.py +17 -0
- validio_sdk-0.2.0/validio_sdk/code/plan.py +145 -0
- validio_sdk-0.2.0/validio_sdk/code/scaffold.py +56 -0
- validio_sdk-0.2.0/validio_sdk/code/settings.py +8 -0
- validio_sdk-0.2.0/validio_sdk/config.py +198 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/__init__.py +3702 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/apply_validator_recommendation.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/async_base_client.py +214 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/aws_credential_secret_changed.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/aws_redshift_credential_secret_changed.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/backfill_source.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/base_model.py +58 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/client.py +19270 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_kinesis_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_kinesis_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_redshift_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_redshift_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_aws_s3_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_categorical_distribution_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_categorical_distribution_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_demo_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_demo_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_file_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_fixed_batch_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_freshness_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_freshness_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_big_query_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_big_query_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_pub_sub_lite_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_pub_sub_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_gcp_storage_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_notification_rule.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_anomaly_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_anomaly_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_distribution_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_distribution_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_distribution_validator_with_monotonic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_numeric_validator_with_monotonic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_postgre_sql_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_postgre_sql_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_relative_time_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_relative_time_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_relative_time_validator_with_monotonic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_relative_volume_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_relative_volume_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_saml_identity_provider.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_segmentation.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_sessionized_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_slack_channel.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_snowflake_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_snowflake_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_snowflake_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_tumbling_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_user.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_volume_validator_with_dynamic_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_volume_validator_with_fixed_threshold.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/create_webhook_channel.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_channel.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_credential.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_credentials.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_destination.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_destinations.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_identity.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_identity_provider.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_notification_rule.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_segmentation.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_source.py +23 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_sources.py +23 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_user.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_validators.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_window.py +23 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/delete_windows.py +23 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/dismiss_validator_recommendation.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/enums.py +142 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/exceptions.py +79 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/fragments.py +4456 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/gcp_credential_secret_changed.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_channel_by_resource_name.py +71 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_channels.py +71 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_credential_by_resource_name.py +124 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_destination_by_resource_name.py +151 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_identity_provider_by_resource_name.py +59 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_identity_providers.py +57 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_incidents.py +135 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_notification_rule_by_resource_name.py +22 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_notification_rules.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_segment_incidents.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_segmentation.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_segmentation_by_resource_name.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_source.py +550 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_source_by_resource_name.py +590 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_source_incidents.py +51 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_source_recommended_validators.py +509 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_user_by_resource_name.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_users.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_validator.py +956 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_validator_by_resource_name.py +1070 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_validator_incidents.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_validator_segment_incidents.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_validator_segment_metrics.py +98 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/get_window_by_resource_name.py +132 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_aws_kinesis_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_aws_redshift_schema.py +14 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_aws_s3_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_demo_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_gcp_big_query_schema.py +14 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_gcp_pub_sub_lite_schema.py +14 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_gcp_pub_sub_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_gcp_storage_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_postgre_sql_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/infer_snowflake_schema.py +12 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/input_types.py +1020 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_credentials.py +114 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_destinations.py +131 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_segmentations.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_sources.py +550 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_validators.py +992 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/list_windows.py +132 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/postgre_sql_credential_secret_changed.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/scalars.py +19 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/segments.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/segments_by_resource_name.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/snowflake_credential_secret_changed.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/start_source.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/stop_source.py +25 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_kinesis_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_kinesis_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_redshift_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_redshift_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_aws_s3_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_categorical_distribution_validator.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_fixed_batch_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_freshness_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_big_query_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_big_query_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_pub_sub_lite_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_pub_sub_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_gcp_storage_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_local_identity_provider.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_notification_rule.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_numeric_anomaly_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_numeric_distribution_validator.py +20 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_numeric_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_postgre_sql_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_postgre_sql_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_relative_time_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_relative_volume_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_saml_identity_provider.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_sessionized_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_slack_channel.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_snowflake_credential.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_snowflake_destination.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_snowflake_source.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_tumbling_window.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_user.py +16 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_validator_with_dynamic_threshold.py +1102 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_validator_with_fixed_threshold.py +1102 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_validator_with_monotonic_threshold.py +1104 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_volume_validator.py +18 -0
- validio_sdk-0.2.0/validio_sdk/graphql_client/update_webhook_channel.py +18 -0
- validio_sdk-0.2.0/validio_sdk/metadata.py +9 -0
- validio_sdk-0.2.0/validio_sdk/py.typed +0 -0
- validio_sdk-0.2.0/validio_sdk/resource/__init__.py +6 -0
- validio_sdk-0.2.0/validio_sdk/resource/_diff.py +575 -0
- validio_sdk-0.2.0/validio_sdk/resource/_diff_util.py +33 -0
- validio_sdk-0.2.0/validio_sdk/resource/_diffable.py +46 -0
- validio_sdk-0.2.0/validio_sdk/resource/_errors.py +39 -0
- validio_sdk-0.2.0/validio_sdk/resource/_field_selector.py +143 -0
- validio_sdk-0.2.0/validio_sdk/resource/_resource.py +466 -0
- validio_sdk-0.2.0/validio_sdk/resource/_resource_graph.py +38 -0
- validio_sdk-0.2.0/validio_sdk/resource/_serde.py +177 -0
- validio_sdk-0.2.0/validio_sdk/resource/_server_resources.py +631 -0
- validio_sdk-0.2.0/validio_sdk/resource/_util.py +28 -0
- validio_sdk-0.2.0/validio_sdk/resource/channels.py +166 -0
- validio_sdk-0.2.0/validio_sdk/resource/credentials.py +275 -0
- validio_sdk-0.2.0/validio_sdk/resource/destinations.py +208 -0
- validio_sdk-0.2.0/validio_sdk/resource/filters.py +233 -0
- validio_sdk-0.2.0/validio_sdk/resource/notification_rules.py +148 -0
- validio_sdk-0.2.0/validio_sdk/resource/segmentations.py +67 -0
- validio_sdk-0.2.0/validio_sdk/resource/sources.py +868 -0
- validio_sdk-0.2.0/validio_sdk/resource/tests/__init__.py +0 -0
- validio_sdk-0.2.0/validio_sdk/resource/tests/test__diff.py +427 -0
- validio_sdk-0.2.0/validio_sdk/resource/tests/test__field_selector.py +68 -0
- validio_sdk-0.2.0/validio_sdk/resource/tests/test__resource.py +532 -0
- validio_sdk-0.2.0/validio_sdk/resource/thresholds.py +206 -0
- validio_sdk-0.2.0/validio_sdk/resource/validators.py +988 -0
- validio_sdk-0.2.0/validio_sdk/resource/windows.py +214 -0
- validio_sdk-0.2.0/validio_sdk/scalars.py +59 -0
- validio_sdk-0.2.0/validio_sdk/util.py +68 -0
- validio_sdk-0.2.0/validio_sdk/validio_client.py +77 -0
- validio_sdk-0.0.1/PKG-INFO +0 -14
- validio_sdk-0.0.1/pyproject.toml +0 -36
- {validio_sdk-0.0.1 → validio_sdk-0.2.0}/LICENSE +0 -0
- {validio_sdk-0.0.1/validio_sdk → validio_sdk-0.2.0/validio_sdk/code}/__init__.py +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: validio-sdk
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: SDK to interact with the Validio platform
|
|
5
|
+
Home-page: https://validio.io/
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Author: Validio
|
|
8
|
+
Author-email: support@validio.io
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Requires-Dist: camel-converter (>=3.0.0,<4.0.0)
|
|
15
|
+
Requires-Dist: httpx (>=0.24.0,<0.25.0)
|
|
16
|
+
Requires-Dist: platformdirs (>=3.5.0,<4.0.0)
|
|
17
|
+
Requires-Dist: pydantic (>=1.10.7,<2.0.0)
|
|
18
|
+
Project-URL: Documentation, https://docs.validio.io/
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# validio-sdk
|
|
22
|
+
|
|
23
|
+
This SDK is maintained by [Validio] to enable users to integrate with the Validio platform in a programmatic way.
|
|
24
|
+
|
|
25
|
+
See the [SDK docs] for more information.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
pip install validio-sdk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
[Validio]: https://validio.io
|
|
34
|
+
[SDK docs]: https://dev.validio.io/sdk-docs
|
|
35
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# validio-sdk
|
|
2
|
+
|
|
3
|
+
This SDK is maintained by [Validio] to enable users to integrate with the Validio platform in a programmatic way.
|
|
4
|
+
|
|
5
|
+
See the [SDK docs] for more information.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install validio-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
[Validio]: https://validio.io
|
|
14
|
+
[SDK docs]: https://dev.validio.io/sdk-docs
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "validio-sdk"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "SDK to interact with the Validio platform"
|
|
5
|
+
authors = ["Validio <support@validio.io>"]
|
|
6
|
+
license = "Apache-2.0"
|
|
7
|
+
homepage = "https://validio.io/"
|
|
8
|
+
documentation = "https://docs.validio.io/"
|
|
9
|
+
packages = [{ include = "validio_sdk" }]
|
|
10
|
+
exclude = ["./validio_sdk/bin/pull_graphql.py", "./schema/**", "./plugins/**", "./examples/**"]
|
|
11
|
+
readme = "README_PUBLIC.md"
|
|
12
|
+
|
|
13
|
+
[tool.poetry.dependencies]
|
|
14
|
+
python = "^3.10"
|
|
15
|
+
camel-converter = "^3.0.0"
|
|
16
|
+
httpx = "^0.24.0"
|
|
17
|
+
platformdirs = "^3.5.0"
|
|
18
|
+
pydantic = "^1.10.7"
|
|
19
|
+
|
|
20
|
+
[tool.poetry.group.dev.dependencies]
|
|
21
|
+
black = "^23.3.0"
|
|
22
|
+
licensecheck = "^2023.1.1"
|
|
23
|
+
mypy = "^1.2.0"
|
|
24
|
+
pytest = "^7.3.1"
|
|
25
|
+
pytest-asyncio = "^0.21.0"
|
|
26
|
+
ruff = "^0.0.263"
|
|
27
|
+
sphinx = "^6.2.1" # We use <7 because most themes only work with that.
|
|
28
|
+
sphinx-rtd-theme = "^1.2.1"
|
|
29
|
+
ariadne-codegen = "^0.7.1"
|
|
30
|
+
tqdm = "^4.65.0"
|
|
31
|
+
types-tqdm = "^4.65.0.1"
|
|
32
|
+
python-dotenv = "^1.0.0"
|
|
33
|
+
|
|
34
|
+
[tool.ariadne-codegen]
|
|
35
|
+
queries_path = "./schema/operations/"
|
|
36
|
+
schema_path = "./schema/schema.graphql"
|
|
37
|
+
target_package_path = "./validio_sdk/"
|
|
38
|
+
include_comments = false
|
|
39
|
+
plugins = [
|
|
40
|
+
"ariadne_codegen.contrib.shorter_results.ShorterResultsPlugin",
|
|
41
|
+
"plugins.schema_translation.SchemaFieldTranslationPlugin",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[tool.ariadne-codegen.scalars.CredentialId]
|
|
45
|
+
type = "validio_sdk.scalars.CredentialId"
|
|
46
|
+
|
|
47
|
+
[tool.ariadne-codegen.scalars.DestinationId]
|
|
48
|
+
type = "validio_sdk.scalars.DestinationId"
|
|
49
|
+
|
|
50
|
+
[tool.ariadne-codegen.scalars.SegmentationId]
|
|
51
|
+
type = "validio_sdk.scalars.SegmentationId"
|
|
52
|
+
|
|
53
|
+
[tool.ariadne-codegen.scalars.SourceId]
|
|
54
|
+
type = "validio_sdk.scalars.SourceId"
|
|
55
|
+
|
|
56
|
+
[tool.ariadne-codegen.scalars.ValidatorId]
|
|
57
|
+
type = "validio_sdk.scalars.ValidatorId"
|
|
58
|
+
|
|
59
|
+
[tool.ariadne-codegen.scalars.WindowId]
|
|
60
|
+
type = "validio_sdk.scalars.WindowId"
|
|
61
|
+
|
|
62
|
+
[tool.ariadne-codegen.scalars.DateTime]
|
|
63
|
+
type = "datetime.datetime"
|
|
64
|
+
|
|
65
|
+
[tool.ariadne-codegen.scalars.JsonPointer]
|
|
66
|
+
type = "validio_sdk.scalars.JsonPointer"
|
|
67
|
+
|
|
68
|
+
# The JsonFilterExpression is a scalar but a union in python representation so
|
|
69
|
+
# we need to add a map between all our union types.
|
|
70
|
+
[tool.ariadne-codegen.scalars.JsonFilterExpression]
|
|
71
|
+
type = "validio_sdk.scalars.JsonFilterExpression"
|
|
72
|
+
|
|
73
|
+
[tool.ariadne-codegen.scalars.EnumFilter]
|
|
74
|
+
type = "validio_sdk.scalars.EnumFilter"
|
|
75
|
+
serialize = "validio_sdk.scalars.serialize_json_filter_expression"
|
|
76
|
+
|
|
77
|
+
[tool.ariadne-codegen.scalars.NullFilter]
|
|
78
|
+
type = "validio_sdk.scalars.NullFilter"
|
|
79
|
+
serialize = "validio_sdk.scalars.serialize_json_filter_expression"
|
|
80
|
+
|
|
81
|
+
[tool.ariadne-codegen.scalars.StringFilter]
|
|
82
|
+
type = "validio_sdk.scalars.StringFilter"
|
|
83
|
+
serialize = "validio_sdk.scalars.serialize_json_filter_expression"
|
|
84
|
+
|
|
85
|
+
[tool.ariadne-codegen.scalars.ThresholdFilter]
|
|
86
|
+
type = "validio_sdk.scalars.ThresholdFilter"
|
|
87
|
+
serialize = "validio_sdk.scalars.serialize_json_filter_expression"
|
|
88
|
+
|
|
89
|
+
[tool.ariadne-codegen.scalars.JsonTypeDefinition]
|
|
90
|
+
type = "validio_sdk.scalars.JsonTypeDefinition"
|
|
91
|
+
|
|
92
|
+
[tool.ariadne-codegen.scalars.CronExpression]
|
|
93
|
+
type = "validio_sdk.scalars.CronExpression"
|
|
94
|
+
|
|
95
|
+
[build-system]
|
|
96
|
+
requires = ["poetry-core"]
|
|
97
|
+
build-backend = "poetry.core.masonry.api"
|
|
98
|
+
|
|
99
|
+
[tool.poetry.scripts]
|
|
100
|
+
example-client = "examples.client:run"
|
|
101
|
+
example-config = "examples.use_config:run"
|
|
102
|
+
pull-graphql = "validio_sdk.bin.pull_graphql:run"
|
|
103
|
+
|
|
104
|
+
[tool.ruff]
|
|
105
|
+
fix = true
|
|
106
|
+
|
|
107
|
+
exclude = [
|
|
108
|
+
# Generated code
|
|
109
|
+
"validio_sdk/graphql_client/*",
|
|
110
|
+
# Docs (mostly generated)
|
|
111
|
+
"docs/*",
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
select = [
|
|
115
|
+
"ARG", # flake8-unused-argument
|
|
116
|
+
"C4", # flake8-comprehension
|
|
117
|
+
"D", # pydocstyle
|
|
118
|
+
"E", # pycodestyle error
|
|
119
|
+
"F", # pyflakes
|
|
120
|
+
"I", # isort
|
|
121
|
+
"N", # pep8-naming
|
|
122
|
+
"PIE", # flake8-pie
|
|
123
|
+
"PL", # pylint
|
|
124
|
+
"PT", # flake8-pytest-style
|
|
125
|
+
"PTH", # flake8-use-pathlib
|
|
126
|
+
"RET", # flake8-ret
|
|
127
|
+
"RUF", # ruff specific rules
|
|
128
|
+
"SIM", # flake8-simplify
|
|
129
|
+
"UP", # pyupgrade
|
|
130
|
+
"W", # pycodestyle warning
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
ignore = [
|
|
134
|
+
"D203", # `one-blank-line-before-class` Incompatible with D211
|
|
135
|
+
"D212", # `multi-line-summary-first-line` Incompatible with D213
|
|
136
|
+
"D205", # blank line required between summary line and description
|
|
137
|
+
"PLR0913", # Too many arguments to function call (named arguments take care of this)
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
[tool.ruff.per-file-ignores]
|
|
141
|
+
"__init__.py" = [
|
|
142
|
+
# We don't need docstrings in __init__
|
|
143
|
+
"D104",
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
# Raw error handling for testing purposes
|
|
147
|
+
# No need for documentation in binaries, examples or generated code
|
|
148
|
+
"*/bin/*.py" = ["D"]
|
|
149
|
+
"examples/*.py" = ["D", "E"]
|
|
150
|
+
"*/graphql_client/*.py" = ["D"]
|
|
151
|
+
"*/tests/*.py" = ["D"]
|
|
152
|
+
|
|
153
|
+
[tool.ruff.pydocstyle]
|
|
154
|
+
convention = "google"
|
|
155
|
+
|
|
156
|
+
[tool.black]
|
|
157
|
+
preview = true
|
|
158
|
+
|
|
159
|
+
# For some reason this is not a list but a regex
|
|
160
|
+
extend-exclude = """
|
|
161
|
+
(
|
|
162
|
+
# Generated code
|
|
163
|
+
validio_sdk/graphql_client/*
|
|
164
|
+
)
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
[tool.mypy]
|
|
168
|
+
ignore_missing_imports = true
|
|
169
|
+
plugins = "pydantic.mypy"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from validio_sdk.resource.filters import (
|
|
2
|
+
BooleanFilter,
|
|
3
|
+
BooleanFilterOperator,
|
|
4
|
+
EnumFilter,
|
|
5
|
+
EnumFilterOperator,
|
|
6
|
+
NullFilter,
|
|
7
|
+
NullFilterOperator,
|
|
8
|
+
StringFilter,
|
|
9
|
+
StringFilterOperator,
|
|
10
|
+
ThresholdFilter,
|
|
11
|
+
ThresholdFilterOperator,
|
|
12
|
+
)
|
|
13
|
+
from validio_sdk.util import load_jtd_schema
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"BooleanFilter",
|
|
17
|
+
"BooleanFilterOperator",
|
|
18
|
+
"EnumFilter",
|
|
19
|
+
"EnumFilterOperator",
|
|
20
|
+
"NullFilter",
|
|
21
|
+
"NullFilterOperator",
|
|
22
|
+
"StringFilter",
|
|
23
|
+
"StringFilterOperator",
|
|
24
|
+
"ThresholdFilter",
|
|
25
|
+
"ThresholdFilterOperator",
|
|
26
|
+
"load_jtd_schema",
|
|
27
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Apply command implementation."""
|
|
2
|
+
|
|
3
|
+
from validio_sdk.resource._diff import GraphDiff
|
|
4
|
+
from validio_sdk.resource._resource import DiffContext
|
|
5
|
+
from validio_sdk.resource._server_resources import apply_updates_on_server
|
|
6
|
+
from validio_sdk.validio_client import ValidioAPIClient
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def apply(
|
|
10
|
+
namespace: str,
|
|
11
|
+
client: ValidioAPIClient,
|
|
12
|
+
ctx: DiffContext,
|
|
13
|
+
diff: GraphDiff,
|
|
14
|
+
show_secrets: bool,
|
|
15
|
+
):
|
|
16
|
+
"""Applies the provided diff operations on the server."""
|
|
17
|
+
await apply_updates_on_server(namespace, ctx, diff, client, show_secrets)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""Plan command implementation."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from validio_sdk.code import scaffold
|
|
12
|
+
from validio_sdk.code.settings import dump_graph_var, graph_preamble_var
|
|
13
|
+
from validio_sdk.graphql_client import GraphQLClientHttpError
|
|
14
|
+
from validio_sdk.resource._diff import (
|
|
15
|
+
GraphDiff,
|
|
16
|
+
diff_resource_graph,
|
|
17
|
+
)
|
|
18
|
+
from validio_sdk.resource._resource import DiffContext, Resource, ResourceGraph
|
|
19
|
+
from validio_sdk.resource._server_resources import load_resources
|
|
20
|
+
from validio_sdk.resource._util import SourceSchemaReinference
|
|
21
|
+
from validio_sdk.resource.credentials import Credential
|
|
22
|
+
from validio_sdk.validio_client import ValidioAPIClient
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async def plan(
|
|
26
|
+
namespace: str,
|
|
27
|
+
client: ValidioAPIClient,
|
|
28
|
+
directory: pathlib.Path,
|
|
29
|
+
schema_reinference: SourceSchemaReinference,
|
|
30
|
+
destroy: bool,
|
|
31
|
+
no_capture: bool,
|
|
32
|
+
show_secrets: bool,
|
|
33
|
+
) -> tuple[GraphDiff, DiffContext]:
|
|
34
|
+
"""Computes a diff between the manifest program and the live server resources."""
|
|
35
|
+
try:
|
|
36
|
+
manifest_ctx = (
|
|
37
|
+
_get_manifest_graph(directory, no_capture) if not destroy else DiffContext()
|
|
38
|
+
)
|
|
39
|
+
server_ctx = await load_resources(namespace, client)
|
|
40
|
+
|
|
41
|
+
diff = await diff_resource_graph(
|
|
42
|
+
namespace=namespace,
|
|
43
|
+
client=client,
|
|
44
|
+
schema_reinference=schema_reinference,
|
|
45
|
+
show_secrets=show_secrets,
|
|
46
|
+
manifest_ctx=manifest_ctx,
|
|
47
|
+
server_ctx=server_ctx,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return diff, manifest_ctx
|
|
51
|
+
except GraphQLClientHttpError as e:
|
|
52
|
+
raise RuntimeError(f"API error: ({e.status_code}: {e.response.json()})")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _get_manifest_graph(directory: pathlib.Path, no_capture: bool) -> DiffContext:
|
|
56
|
+
"""Runs the manifest program and captures its output into a ResourceGraph."""
|
|
57
|
+
process_env = os.environ.copy()
|
|
58
|
+
process_env[dump_graph_var] = "1"
|
|
59
|
+
child = subprocess.run(
|
|
60
|
+
["python", directory / scaffold.main_file_name],
|
|
61
|
+
cwd=directory,
|
|
62
|
+
env=process_env,
|
|
63
|
+
capture_output=True,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if child.returncode != 0:
|
|
67
|
+
_dump_child_stderr(child)
|
|
68
|
+
sys.exit(child.returncode)
|
|
69
|
+
|
|
70
|
+
raw_output: str = child.stdout.decode("utf-8")
|
|
71
|
+
(_graph, ctx, captured_output) = _extract_resource_graph(raw_output, child)
|
|
72
|
+
if no_capture and captured_output:
|
|
73
|
+
print(captured_output)
|
|
74
|
+
|
|
75
|
+
return ctx
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _dump_child_stderr(child: subprocess.CompletedProcess):
|
|
79
|
+
print(child.stderr.decode("unicode_escape"), file=sys.stderr)
|
|
80
|
+
print(
|
|
81
|
+
f"{scaffold.main_file_name} terminated with a non-zero exit code",
|
|
82
|
+
file=sys.stderr,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# Parse the graph from the child program's output. Returns also any captured stdout
|
|
87
|
+
# of the child program.
|
|
88
|
+
def _extract_resource_graph(
|
|
89
|
+
raw_output: str,
|
|
90
|
+
child: subprocess.CompletedProcess,
|
|
91
|
+
) -> tuple[ResourceGraph, DiffContext, str]:
|
|
92
|
+
preamble_start_idx: int = raw_output.find(graph_preamble_var)
|
|
93
|
+
if preamble_start_idx < 0:
|
|
94
|
+
return ResourceGraph(), DiffContext(), ""
|
|
95
|
+
|
|
96
|
+
std_output = raw_output[:preamble_start_idx]
|
|
97
|
+
|
|
98
|
+
graph_str = raw_output[preamble_start_idx + len(graph_preamble_var) :].strip()
|
|
99
|
+
if len(graph_str) == 0:
|
|
100
|
+
_dump_child_stderr(child)
|
|
101
|
+
raise RuntimeError(
|
|
102
|
+
"BUG(internal): missing resource graph from manifest program"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
graph_json = json.loads(graph_str)
|
|
107
|
+
except Exception as e:
|
|
108
|
+
# We wrap the error here, because otherwise the exception thrown by
|
|
109
|
+
# JSON parser can be cryptic if it lands in the terminal on its own.
|
|
110
|
+
raise RuntimeError(f"failed to load resource graph output JSON: {e}")
|
|
111
|
+
|
|
112
|
+
graph, ctx = ResourceGraph._decode(graph_json)
|
|
113
|
+
return graph, ctx, std_output
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _create_resource_diff_object(
|
|
117
|
+
r: Resource | dict, show_secrets: bool, rewrites: dict[str, Any] | None = None
|
|
118
|
+
) -> dict[str, object]:
|
|
119
|
+
if rewrites is None:
|
|
120
|
+
rewrites = {}
|
|
121
|
+
|
|
122
|
+
data = r.__dict__ if isinstance(r, Resource) else r
|
|
123
|
+
|
|
124
|
+
diff_object = {}
|
|
125
|
+
for k, v in data.items():
|
|
126
|
+
if k.startswith("_"):
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
if k in rewrites:
|
|
130
|
+
diff_object[k] = rewrites[k]
|
|
131
|
+
elif isinstance(v, Resource | dict):
|
|
132
|
+
diff_object[k] = _create_resource_diff_object(v, show_secrets)
|
|
133
|
+
elif hasattr(v, "__dict__") and not isinstance(v, Enum):
|
|
134
|
+
diff_object[k] = _create_resource_diff_object(v.__dict__, show_secrets)
|
|
135
|
+
else:
|
|
136
|
+
diff_object[k] = v
|
|
137
|
+
|
|
138
|
+
# Mask any sensitive info if requested.
|
|
139
|
+
if not show_secrets and isinstance(r, Credential):
|
|
140
|
+
secret_fields = r._secret_fields()
|
|
141
|
+
if secret_fields:
|
|
142
|
+
for field in secret_fields:
|
|
143
|
+
diff_object[field] = "REDACTED"
|
|
144
|
+
|
|
145
|
+
return diff_object
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Init command implementation."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
settings_file_name: str = "validio.json"
|
|
9
|
+
main_file_name: str = "main.py"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class ProjectSettings:
|
|
14
|
+
"""Represents the settings for a project."""
|
|
15
|
+
|
|
16
|
+
namespace: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _new_project(namespace: str, directory: pathlib.Path, force: bool):
|
|
20
|
+
_ensure_directory(directory, force)
|
|
21
|
+
_ensure_project_settings_file(directory, namespace)
|
|
22
|
+
_gen_main_py_file(directory)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _ensure_directory(p: pathlib.Path, force: bool):
|
|
26
|
+
if not p.exists():
|
|
27
|
+
pathlib.Path.mkdir(p)
|
|
28
|
+
|
|
29
|
+
if not p.is_dir():
|
|
30
|
+
raise RuntimeError(f"{p} is not a directory; rerun specifying a directory")
|
|
31
|
+
|
|
32
|
+
if not force and len(os.listdir(p)):
|
|
33
|
+
raise RuntimeError(
|
|
34
|
+
f"{p} is not empty; rerun in an empty directory, or use --force"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _ensure_project_settings_file(p: pathlib.Path, namespace: str):
|
|
39
|
+
with pathlib.Path.open(_project_settings_file_path(p), "w") as f:
|
|
40
|
+
print(
|
|
41
|
+
json.dumps(ProjectSettings(namespace=namespace).__dict__, indent=2), file=f
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _read_project_settings(p: pathlib.Path) -> ProjectSettings:
|
|
46
|
+
with pathlib.Path.open(_project_settings_file_path(p)) as f:
|
|
47
|
+
return ProjectSettings(**json.load(f))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _project_settings_file_path(p: pathlib.Path) -> pathlib.Path:
|
|
51
|
+
return p / settings_file_name
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _gen_main_py_file(p: pathlib.Path):
|
|
55
|
+
with pathlib.Path.open(p / main_file_name, "w") as f:
|
|
56
|
+
print("from validio_sdk.resource import credentials", file=f)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Contains shared constants."""
|
|
2
|
+
|
|
3
|
+
# Flag to write out the resource graph on exit.
|
|
4
|
+
dump_graph_var = "VALIDIO_DUMP_GRAPH"
|
|
5
|
+
|
|
6
|
+
# Preamble says where the graph output starts from. Anything before that is
|
|
7
|
+
# output belong to the program which will be captured.
|
|
8
|
+
graph_preamble_var = "VALIDIO_CONFIG_GRAPH_PREAMBLE"
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""Persistent configuration."""
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import platformdirs
|
|
7
|
+
|
|
8
|
+
from validio_sdk.util import ClassJSONEncoder
|
|
9
|
+
|
|
10
|
+
CONFIG_PATH_ENV = "VALIDIO_CONFIG_PATH"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ConfigNotFoundError(Exception):
|
|
14
|
+
"""Exception when no configuration is found."""
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
"""Construct the exception."""
|
|
18
|
+
super().__init__(
|
|
19
|
+
"No configuration file found. Run 'validio config' to create one"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConfigInvalidError(Exception):
|
|
24
|
+
"""Exception when the configuration file is invalid."""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Construct the exception."""
|
|
28
|
+
super().__init__("Configuration file is invalid.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ValidioConfig:
|
|
32
|
+
"""Representation of configuration to use in the Validio system and SDK."""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
endpoint: str = "",
|
|
37
|
+
access_key: str = "",
|
|
38
|
+
access_secret: str = "",
|
|
39
|
+
default_namespace: str = "default",
|
|
40
|
+
):
|
|
41
|
+
"""
|
|
42
|
+
Constructor for `ValidioConfig`.
|
|
43
|
+
|
|
44
|
+
Will ensure we can construct an object with the exposed property
|
|
45
|
+
`access_secret`.
|
|
46
|
+
"""
|
|
47
|
+
self.default_namespace = default_namespace
|
|
48
|
+
self.endpoint = endpoint
|
|
49
|
+
self.access_key = access_key
|
|
50
|
+
self._access_secret = access_secret
|
|
51
|
+
|
|
52
|
+
def asdict(self):
|
|
53
|
+
"""
|
|
54
|
+
Return a dictionary representation of the class.
|
|
55
|
+
|
|
56
|
+
This is used from our `ClassJSONEncoder` to ensure we save JSON
|
|
57
|
+
representing the class with the external property names. By doing this
|
|
58
|
+
we can also ensure that we can serialize the config by passing the JSON
|
|
59
|
+
to the constructor.
|
|
60
|
+
"""
|
|
61
|
+
return {
|
|
62
|
+
"default_namespace": self.default_namespace,
|
|
63
|
+
"endpoint": self.endpoint,
|
|
64
|
+
"access_key": self.access_key,
|
|
65
|
+
"access_secret": self._access_secret,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def _none_or_hidden(maybe_value):
|
|
70
|
+
"""
|
|
71
|
+
Represent a hidden value but be explicit if unset.
|
|
72
|
+
|
|
73
|
+
Will return fix length of asterisks for existing values but if no value
|
|
74
|
+
exist a single dash is returned.
|
|
75
|
+
"""
|
|
76
|
+
return "-" if maybe_value is None else "*****"
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def access_secret(self): # noqa: D102 No reason to document property.
|
|
80
|
+
return self._none_or_hidden(self._access_secret)
|
|
81
|
+
|
|
82
|
+
@access_secret.setter
|
|
83
|
+
def access_secret(self, value):
|
|
84
|
+
self._access_secret = value
|
|
85
|
+
|
|
86
|
+
def __repr__(self):
|
|
87
|
+
"""
|
|
88
|
+
Representation of a `ValidioConfig`.
|
|
89
|
+
|
|
90
|
+
Will ensure we don't print sensitive information.
|
|
91
|
+
"""
|
|
92
|
+
return (
|
|
93
|
+
f'{"Default namespace":<20} | {self.default_namespace}\n'
|
|
94
|
+
f'{"Endpoint":<20} | {self.endpoint}\n'
|
|
95
|
+
f'{"Access key":<20} | {self.access_key}\n'
|
|
96
|
+
f'{"Access secret":<20} | {self._none_or_hidden(self.access_secret)}\n'
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class Config:
|
|
101
|
+
"""
|
|
102
|
+
Config management.
|
|
103
|
+
|
|
104
|
+
A class to work with configuration such as reading, writing and deleting.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def __init__(self, config_dir: Path | None = None):
|
|
108
|
+
"""
|
|
109
|
+
Creates a new instance of `Config`.
|
|
110
|
+
|
|
111
|
+
:param config_dir: Optional directory where to put the config file. Will
|
|
112
|
+
default to system default set by `platformdirs`.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
:returns: A `Config` instance.
|
|
116
|
+
"""
|
|
117
|
+
if config_dir is None:
|
|
118
|
+
config_dir = default_config_dir()
|
|
119
|
+
|
|
120
|
+
self.config_path: Path = Path(config_dir, "config.json")
|
|
121
|
+
self.validio_config: ValidioConfig | None = None
|
|
122
|
+
|
|
123
|
+
def write(self, config: ValidioConfig):
|
|
124
|
+
"""
|
|
125
|
+
Write the passed configuration to disk.
|
|
126
|
+
|
|
127
|
+
This will fully overwrite the existing configuration, including any
|
|
128
|
+
fields that's not a part of the `ValidioConfig`.
|
|
129
|
+
|
|
130
|
+
:param config: A `ValidioConfig` object.
|
|
131
|
+
"""
|
|
132
|
+
self.validio_config = config
|
|
133
|
+
|
|
134
|
+
file_content = json.dumps(
|
|
135
|
+
config, indent=2, sort_keys=True, cls=ClassJSONEncoder
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
self.config_path.write_text(file_content)
|
|
139
|
+
|
|
140
|
+
def read(self) -> ValidioConfig:
|
|
141
|
+
"""
|
|
142
|
+
Read persistent configuration.
|
|
143
|
+
|
|
144
|
+
Will return `None` if no configuration is created yet.
|
|
145
|
+
|
|
146
|
+
:returns: The configuration, or None
|
|
147
|
+
:rtype: ValidioConfig | None
|
|
148
|
+
:raises: ConfigNotFoundError if no configuration exists
|
|
149
|
+
:raises: ConfigNotFoundError if the configuration is invalid
|
|
150
|
+
"""
|
|
151
|
+
if self.validio_config is not None:
|
|
152
|
+
return self.validio_config
|
|
153
|
+
|
|
154
|
+
if not self.config_path.is_file():
|
|
155
|
+
raise ConfigNotFoundError
|
|
156
|
+
|
|
157
|
+
file_content = self.config_path.read_text()
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
file_content_json = json.loads(file_content)
|
|
161
|
+
except json.decoder.JSONDecodeError:
|
|
162
|
+
raise ConfigInvalidError
|
|
163
|
+
|
|
164
|
+
# Ensure we filter out the fields from the configuration that is
|
|
165
|
+
# supported by ValidioConfig. We silently drop everything else.
|
|
166
|
+
validio_config_fields = [x.lstrip("_") for x in list(vars(ValidioConfig()))]
|
|
167
|
+
init_args = {
|
|
168
|
+
k: v for k, v in file_content_json.items() if k in validio_config_fields
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
return ValidioConfig(**init_args)
|
|
173
|
+
except TypeError:
|
|
174
|
+
raise ConfigInvalidError
|
|
175
|
+
|
|
176
|
+
def remove(self):
|
|
177
|
+
"""Remove the configuration at the instance's `config_path`."""
|
|
178
|
+
if self.config_path.is_file():
|
|
179
|
+
self.config_path.unlink()
|
|
180
|
+
|
|
181
|
+
def exists(self):
|
|
182
|
+
"""Check if any configuration exist."""
|
|
183
|
+
return self.validio_config is not None
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def default_config_dir() -> Path:
|
|
187
|
+
"""Get the default config dir based on the OS."""
|
|
188
|
+
env_path = os.getenv(CONFIG_PATH_ENV)
|
|
189
|
+
if env_path is not None:
|
|
190
|
+
return Path(env_path)
|
|
191
|
+
|
|
192
|
+
config_dir = platformdirs.user_config_dir(
|
|
193
|
+
appname="validio",
|
|
194
|
+
appauthor="Validio AB",
|
|
195
|
+
ensure_exists=True,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return Path(config_dir)
|