dsp-tools 9.1.0.post11__py3-none-any.whl → 18.3.0.post13__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.
- dsp_tools/__init__.py +4 -0
- dsp_tools/cli/args.py +36 -0
- dsp_tools/cli/call_action.py +51 -231
- dsp_tools/cli/call_action_files_only.py +101 -0
- dsp_tools/cli/call_action_with_network.py +207 -0
- dsp_tools/cli/create_parsers.py +156 -58
- dsp_tools/cli/entry_point.py +56 -26
- dsp_tools/cli/utils.py +87 -0
- dsp_tools/clients/CLAUDE.md +420 -0
- dsp_tools/clients/authentication_client.py +14 -0
- dsp_tools/clients/authentication_client_live.py +66 -0
- dsp_tools/{utils → clients}/connection.py +2 -18
- dsp_tools/clients/connection_live.py +233 -0
- dsp_tools/clients/fuseki_metrics.py +60 -0
- dsp_tools/clients/group_user_clients.py +35 -0
- dsp_tools/clients/group_user_clients_live.py +181 -0
- dsp_tools/clients/legal_info_client.py +23 -0
- dsp_tools/clients/legal_info_client_live.py +132 -0
- dsp_tools/clients/list_client.py +49 -0
- dsp_tools/clients/list_client_live.py +166 -0
- dsp_tools/clients/metadata_client.py +24 -0
- dsp_tools/clients/metadata_client_live.py +47 -0
- dsp_tools/clients/ontology_clients.py +49 -0
- dsp_tools/clients/ontology_create_client_live.py +166 -0
- dsp_tools/clients/ontology_get_client_live.py +80 -0
- dsp_tools/clients/permissions_client.py +68 -0
- dsp_tools/clients/project_client.py +16 -0
- dsp_tools/clients/project_client_live.py +66 -0
- dsp_tools/commands/create/communicate_problems.py +24 -0
- dsp_tools/commands/create/create.py +134 -0
- dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
- dsp_tools/commands/create/create_on_server/classes.py +99 -0
- dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
- dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
- dsp_tools/commands/create/create_on_server/group_users.py +165 -0
- dsp_tools/commands/create/create_on_server/lists.py +163 -0
- dsp_tools/commands/create/create_on_server/mappers.py +12 -0
- dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
- dsp_tools/commands/create/create_on_server/ontology.py +52 -0
- dsp_tools/commands/create/create_on_server/project.py +68 -0
- dsp_tools/commands/create/create_on_server/properties.py +119 -0
- dsp_tools/commands/create/exceptions.py +29 -0
- dsp_tools/commands/create/lists_only.py +66 -0
- dsp_tools/commands/create/models/create_problems.py +87 -0
- dsp_tools/commands/create/models/parsed_ontology.py +88 -0
- dsp_tools/commands/create/models/parsed_project.py +81 -0
- dsp_tools/commands/create/models/rdf_ontology.py +12 -0
- dsp_tools/commands/create/models/server_project_info.py +100 -0
- dsp_tools/commands/create/parsing/parse_lists.py +45 -0
- dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
- dsp_tools/commands/create/parsing/parse_project.py +149 -0
- dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
- dsp_tools/commands/create/project_validate.py +595 -0
- dsp_tools/commands/create/serialisation/ontology.py +119 -0
- dsp_tools/commands/create/serialisation/project.py +44 -0
- dsp_tools/commands/excel2json/CLAUDE.md +101 -0
- dsp_tools/commands/excel2json/json_header.py +57 -23
- dsp_tools/commands/excel2json/{new_lists → lists}/compliance_checks.py +26 -26
- dsp_tools/commands/excel2json/{new_lists/make_new_lists.py → lists/make_lists.py} +19 -18
- dsp_tools/commands/excel2json/{new_lists → lists}/models/input_error.py +1 -12
- dsp_tools/commands/excel2json/{new_lists → lists}/models/serialise.py +9 -5
- dsp_tools/commands/excel2json/{new_lists → lists}/utils.py +4 -4
- dsp_tools/commands/excel2json/models/input_error.py +31 -11
- dsp_tools/commands/excel2json/models/json_header.py +53 -15
- dsp_tools/commands/excel2json/models/ontology.py +4 -3
- dsp_tools/commands/excel2json/{lists.py → old_lists.py} +26 -112
- dsp_tools/commands/excel2json/project.py +78 -34
- dsp_tools/commands/excel2json/properties.py +57 -36
- dsp_tools/commands/excel2json/resources.py +32 -12
- dsp_tools/commands/excel2json/utils.py +20 -1
- dsp_tools/commands/excel2xml/__init__.py +2 -2
- dsp_tools/commands/excel2xml/excel2xml_cli.py +7 -15
- dsp_tools/commands/excel2xml/excel2xml_lib.py +138 -493
- dsp_tools/commands/excel2xml/propertyelement.py +5 -5
- dsp_tools/commands/{project → get}/get.py +29 -13
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/{project/models → get/legacy_models}/context.py +6 -6
- dsp_tools/commands/{project/models → get/legacy_models}/group.py +5 -10
- dsp_tools/commands/{project/models → get/legacy_models}/listnode.py +5 -35
- dsp_tools/commands/{project/models → get/legacy_models}/model.py +1 -1
- dsp_tools/commands/{project/models → get/legacy_models}/ontology.py +9 -14
- dsp_tools/commands/{project/models → get/legacy_models}/project.py +13 -6
- dsp_tools/commands/{project/models → get/legacy_models}/propertyclass.py +9 -16
- dsp_tools/commands/{project/models → get/legacy_models}/resourceclass.py +8 -46
- dsp_tools/commands/{project/models → get/legacy_models}/user.py +19 -60
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +20 -10
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +81 -56
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +4 -10
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +97 -37
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +2 -2
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +9 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +3 -3
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +2 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +12 -2
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +8 -9
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +18 -18
- dsp_tools/commands/start_stack.py +126 -77
- dsp_tools/commands/update_legal/CLAUDE.md +344 -0
- dsp_tools/commands/update_legal/__init__.py +0 -0
- dsp_tools/commands/update_legal/core.py +182 -0
- dsp_tools/commands/update_legal/csv_operations.py +135 -0
- dsp_tools/commands/update_legal/models.py +87 -0
- dsp_tools/commands/update_legal/xml_operations.py +247 -0
- dsp_tools/commands/validate_data/CLAUDE.md +159 -0
- dsp_tools/commands/validate_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/constants.py +59 -0
- dsp_tools/commands/validate_data/mappers.py +143 -0
- dsp_tools/commands/validate_data/models/__init__.py +0 -0
- dsp_tools/commands/validate_data/models/api_responses.py +45 -0
- dsp_tools/commands/validate_data/models/input_problems.py +119 -0
- dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
- dsp_tools/commands/validate_data/models/validation.py +106 -0
- dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
- dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
- dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
- dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
- dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
- dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
- dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
- dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
- dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
- dsp_tools/commands/{xml_validate/sparql/resource_shacl.py → validate_data/sparql/cardinality_shacl.py} +45 -47
- dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
- dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
- dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
- dsp_tools/commands/validate_data/utils.py +59 -0
- dsp_tools/commands/validate_data/validate_data.py +283 -0
- dsp_tools/commands/validate_data/validation/__init__.py +0 -0
- dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
- dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
- dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
- dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
- dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +0 -25
- dsp_tools/commands/xmlupload/models/ingest.py +56 -70
- dsp_tools/commands/xmlupload/models/input_problems.py +6 -14
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +0 -39
- dsp_tools/commands/xmlupload/models/{deserialise/xmlpermission.py → permissions_parsed.py} +2 -2
- dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
- dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
- dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
- dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
- dsp_tools/commands/xmlupload/models/upload_clients.py +3 -3
- dsp_tools/commands/xmlupload/models/upload_state.py +2 -4
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/{ark2iri.py → prepare_xml_input/ark2iri.py} +1 -1
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/{iiif_uri_validator.py → prepare_xml_input/iiif_uri_validator.py} +2 -14
- dsp_tools/commands/xmlupload/{list_client.py → prepare_xml_input/list_client.py} +15 -10
- dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
- dsp_tools/commands/xmlupload/resource_create_client.py +7 -468
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/{construct_and_analyze_graph.py → analyse_circular_reference_graph.py} +64 -157
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +13 -8
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +48 -115
- dsp_tools/commands/xmlupload/stash/stash_models.py +4 -9
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +34 -40
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +98 -108
- dsp_tools/commands/xmlupload/upload_config.py +8 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +14 -9
- dsp_tools/commands/xmlupload/xmlupload.py +214 -192
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/{utils → config}/warnings_config.py +4 -1
- dsp_tools/error/__init__.py +0 -0
- dsp_tools/error/custom_warnings.py +39 -0
- dsp_tools/error/exceptions.py +204 -0
- dsp_tools/error/problems.py +10 -0
- dsp_tools/error/xmllib_errors.py +20 -0
- dsp_tools/error/xmllib_warnings.py +54 -0
- dsp_tools/error/xmllib_warnings_util.py +159 -0
- dsp_tools/error/xsd_validation_error_msg.py +19 -0
- dsp_tools/legacy_models/__init__.py +0 -0
- dsp_tools/{models → legacy_models}/datetimestamp.py +7 -7
- dsp_tools/{models → legacy_models}/langstring.py +1 -1
- dsp_tools/{models → legacy_models}/projectContext.py +4 -4
- dsp_tools/resources/schema/data.xsd +108 -83
- dsp_tools/resources/schema/lists-only.json +4 -23
- dsp_tools/resources/schema/project.json +80 -35
- dsp_tools/resources/schema/properties-only.json +1 -4
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +34 -30
- dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
- dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
- dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
- dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
- dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
- dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/{date_util.py → data_formats/date_util.py} +13 -1
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/{shared.py → data_formats/shared.py} +1 -35
- dsp_tools/utils/{uri_util.py → data_formats/uri_util.py} +12 -2
- dsp_tools/utils/fuseki_bloating.py +63 -0
- dsp_tools/utils/json_parsing.py +22 -0
- dsp_tools/utils/rdf_constants.py +42 -0
- dsp_tools/utils/rdflib_utils.py +10 -0
- dsp_tools/utils/replace_id_with_iri.py +66 -0
- dsp_tools/utils/request_utils.py +238 -0
- dsp_tools/utils/xml_parsing/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
- dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
- dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
- dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
- dsp_tools/xmllib/CLAUDE.md +302 -0
- dsp_tools/xmllib/__init__.py +49 -0
- dsp_tools/xmllib/general_functions.py +877 -0
- dsp_tools/xmllib/internal/__init__.py +0 -0
- dsp_tools/xmllib/internal/checkers.py +162 -0
- dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
- dsp_tools/xmllib/internal/constants.py +46 -0
- dsp_tools/xmllib/internal/input_converters.py +155 -0
- dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
- dsp_tools/xmllib/internal/serialise_resource.py +177 -0
- dsp_tools/xmllib/internal/serialise_values.py +152 -0
- dsp_tools/xmllib/internal/type_aliases.py +11 -0
- dsp_tools/xmllib/models/config_options.py +28 -0
- dsp_tools/xmllib/models/date_formats.py +48 -0
- dsp_tools/xmllib/models/dsp_base_resources.py +1380 -400
- dsp_tools/xmllib/models/internal/__init__.py +0 -0
- dsp_tools/xmllib/models/internal/file_values.py +172 -0
- dsp_tools/xmllib/models/internal/geometry.py +162 -0
- dsp_tools/xmllib/models/{migration_metadata.py → internal/migration_metadata.py} +14 -10
- dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
- dsp_tools/xmllib/models/internal/values.py +342 -0
- dsp_tools/xmllib/models/licenses/__init__.py +0 -0
- dsp_tools/xmllib/models/licenses/other.py +59 -0
- dsp_tools/xmllib/models/licenses/recommended.py +107 -0
- dsp_tools/xmllib/models/permissions.py +41 -0
- dsp_tools/xmllib/models/res.py +1782 -0
- dsp_tools/xmllib/models/root.py +313 -26
- dsp_tools/xmllib/value_checkers.py +310 -47
- dsp_tools/xmllib/value_converters.py +765 -8
- dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
- dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
- dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
- {dsp_tools-9.1.0.post11.dist-info → dsp_tools-18.3.0.post13.dist-info}/entry_points.txt +1 -0
- dsp_tools/commands/project/create/project_create.py +0 -1107
- dsp_tools/commands/project/create/project_create_lists.py +0 -204
- dsp_tools/commands/project/create/project_validate.py +0 -453
- dsp_tools/commands/project/models/project_definition.py +0 -12
- dsp_tools/commands/rosetta.py +0 -124
- dsp_tools/commands/template.py +0 -30
- dsp_tools/commands/xml_validate/api_connection.py +0 -122
- dsp_tools/commands/xml_validate/deserialise_input.py +0 -135
- dsp_tools/commands/xml_validate/make_data_rdf.py +0 -193
- dsp_tools/commands/xml_validate/models/data_deserialised.py +0 -108
- dsp_tools/commands/xml_validate/models/data_rdf.py +0 -214
- dsp_tools/commands/xml_validate/models/input_problems.py +0 -191
- dsp_tools/commands/xml_validate/models/validation.py +0 -29
- dsp_tools/commands/xml_validate/reformat_validaton_result.py +0 -89
- dsp_tools/commands/xml_validate/sparql/construct_shapes.py +0 -16
- dsp_tools/commands/xml_validate/xml_validate.py +0 -151
- dsp_tools/commands/xmlupload/check_consistency_with_ontology.py +0 -253
- dsp_tools/commands/xmlupload/models/deserialise/deserialise_value.py +0 -236
- dsp_tools/commands/xmlupload/models/deserialise/xmlresource.py +0 -171
- dsp_tools/commands/xmlupload/models/namespace_context.py +0 -39
- dsp_tools/commands/xmlupload/models/ontology_lookup_models.py +0 -161
- dsp_tools/commands/xmlupload/models/ontology_problem_models.py +0 -178
- dsp_tools/commands/xmlupload/models/serialise/jsonld_serialiser.py +0 -40
- dsp_tools/commands/xmlupload/models/serialise/serialise_value.py +0 -51
- dsp_tools/commands/xmlupload/ontology_client.py +0 -92
- dsp_tools/commands/xmlupload/project_client.py +0 -91
- dsp_tools/commands/xmlupload/read_validate_xml_file.py +0 -99
- dsp_tools/models/custom_warnings.py +0 -31
- dsp_tools/models/exceptions.py +0 -90
- dsp_tools/resources/0100-template-repo/template.json +0 -45
- dsp_tools/resources/0100-template-repo/template.xml +0 -27
- dsp_tools/resources/start-stack/docker-compose-validation.yml +0 -5
- dsp_tools/resources/start-stack/start-stack-config.yml +0 -4
- dsp_tools/resources/xml_validate/api-shapes.ttl +0 -411
- dsp_tools/resources/xml_validate/replace_namespace.xslt +0 -61
- dsp_tools/utils/connection_live.py +0 -383
- dsp_tools/utils/iri_util.py +0 -14
- dsp_tools/utils/logger_config.py +0 -41
- dsp_tools/utils/set_encoder.py +0 -20
- dsp_tools/utils/xml_utils.py +0 -145
- dsp_tools/utils/xml_validation.py +0 -197
- dsp_tools/utils/xml_validation_models.py +0 -68
- dsp_tools/xmllib/models/file_values.py +0 -78
- dsp_tools/xmllib/models/resource.py +0 -415
- dsp_tools/xmllib/models/values.py +0 -428
- dsp_tools-9.1.0.post11.dist-info/METADATA +0 -130
- dsp_tools-9.1.0.post11.dist-info/RECORD +0 -167
- dsp_tools-9.1.0.post11.dist-info/WHEEL +0 -4
- dsp_tools-9.1.0.post11.dist-info/licenses/LICENSE +0 -674
- /dsp_tools/{commands/excel2json/new_lists → clients}/__init__.py +0 -0
- /dsp_tools/commands/{excel2json/new_lists/models → create}/__init__.py +0 -0
- /dsp_tools/commands/{project → create/create_on_server}/__init__.py +0 -0
- /dsp_tools/commands/{project/create → create/models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → create/parsing}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate → create/serialisation}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/models → excel2json/lists}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/sparql → excel2json/lists/models}/__init__.py +0 -0
- /dsp_tools/commands/excel2json/{new_lists → lists}/models/deserialise.py +0 -0
- /dsp_tools/commands/{xmlupload/models/deserialise → get}/__init__.py +0 -0
- /dsp_tools/commands/{xmlupload/models/serialise → get/legacy_models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → get/legacy_models}/helpers.py +0 -0
- /dsp_tools/{models → commands/get/models}/__init__.py +0 -0
|
@@ -2,21 +2,25 @@ import pickle
|
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
4
|
from loguru import logger
|
|
5
|
-
from termcolor import colored
|
|
6
5
|
|
|
7
6
|
from dsp_tools.cli.args import ServerCredentials
|
|
8
|
-
from dsp_tools.
|
|
9
|
-
from dsp_tools.
|
|
7
|
+
from dsp_tools.clients.authentication_client_live import AuthenticationClientLive
|
|
8
|
+
from dsp_tools.clients.connection_live import ConnectionLive
|
|
9
|
+
from dsp_tools.clients.legal_info_client import LegalInfoClient
|
|
10
|
+
from dsp_tools.clients.legal_info_client_live import LegalInfoClientLive
|
|
11
|
+
from dsp_tools.clients.project_client import ProjectClient
|
|
12
|
+
from dsp_tools.clients.project_client_live import ProjectClientLive
|
|
10
13
|
from dsp_tools.commands.xmlupload.models.ingest import AssetClient
|
|
11
14
|
from dsp_tools.commands.xmlupload.models.ingest import BulkIngestedAssetClient
|
|
12
15
|
from dsp_tools.commands.xmlupload.models.ingest import DspIngestClientLive
|
|
13
16
|
from dsp_tools.commands.xmlupload.models.upload_clients import UploadClients
|
|
14
17
|
from dsp_tools.commands.xmlupload.models.upload_state import UploadState
|
|
15
|
-
from dsp_tools.commands.xmlupload.
|
|
16
|
-
from dsp_tools.commands.xmlupload.
|
|
18
|
+
from dsp_tools.commands.xmlupload.prepare_xml_input.list_client import ListClient
|
|
19
|
+
from dsp_tools.commands.xmlupload.prepare_xml_input.list_client import ListClientLive
|
|
17
20
|
from dsp_tools.commands.xmlupload.upload_config import UploadConfig
|
|
18
21
|
from dsp_tools.commands.xmlupload.xmlupload import execute_upload
|
|
19
|
-
from dsp_tools.utils.
|
|
22
|
+
from dsp_tools.utils.ansi_colors import RED
|
|
23
|
+
from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
|
|
20
24
|
|
|
21
25
|
|
|
22
26
|
def resume_xmlupload(creds: ServerCredentials, skip_first_resource: bool = False) -> bool:
|
|
@@ -38,23 +42,19 @@ def resume_xmlupload(creds: ServerCredentials, skip_first_resource: bool = False
|
|
|
38
42
|
|
|
39
43
|
_print_and_log(upload_state, server)
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
con
|
|
45
|
+
auth = AuthenticationClientLive(server, creds.user, creds.password)
|
|
46
|
+
con = ConnectionLive(server, auth)
|
|
43
47
|
|
|
44
48
|
ingest_client: AssetClient
|
|
45
49
|
if upload_state.config.media_previously_uploaded:
|
|
46
50
|
ingest_client = BulkIngestedAssetClient()
|
|
47
51
|
else:
|
|
48
|
-
ingest_client = DspIngestClientLive(
|
|
49
|
-
dsp_ingest_url=creds.dsp_ingest_url,
|
|
50
|
-
token=con.get_token(),
|
|
51
|
-
shortcode=upload_state.config.shortcode,
|
|
52
|
-
imgdir=".",
|
|
53
|
-
)
|
|
52
|
+
ingest_client = DspIngestClientLive(creds.dsp_ingest_url, auth, upload_state.config.shortcode, ".")
|
|
54
53
|
|
|
55
|
-
project_client: ProjectClient = ProjectClientLive(
|
|
56
|
-
list_client: ListClient = ListClientLive(con, project_client.get_project_iri())
|
|
57
|
-
|
|
54
|
+
project_client: ProjectClient = ProjectClientLive(auth.server, auth)
|
|
55
|
+
list_client: ListClient = ListClientLive(con, project_client.get_project_iri(upload_state.config.shortcode))
|
|
56
|
+
legal_info_client: LegalInfoClient = LegalInfoClientLive(server, upload_state.config.shortcode, auth)
|
|
57
|
+
clients = UploadClients(ingest_client, list_client, legal_info_client)
|
|
58
58
|
|
|
59
59
|
return execute_upload(clients, upload_state)
|
|
60
60
|
|
|
@@ -77,7 +77,7 @@ def _skip_first_resource(upload_state: UploadState) -> None:
|
|
|
77
77
|
)
|
|
78
78
|
resp = None
|
|
79
79
|
while resp not in ["y", "n"]:
|
|
80
|
-
resp = input(
|
|
80
|
+
resp = input(RED + msg + RESET_TO_DEFAULT)
|
|
81
81
|
if resp == "n":
|
|
82
82
|
sys.exit(1)
|
|
83
83
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import importlib.resources
|
|
2
3
|
import shutil
|
|
3
4
|
import subprocess
|
|
@@ -9,11 +10,17 @@ from typing import Optional
|
|
|
9
10
|
import regex
|
|
10
11
|
import requests
|
|
11
12
|
import yaml
|
|
13
|
+
from jinja2 import Template
|
|
12
14
|
from loguru import logger
|
|
13
15
|
|
|
14
|
-
from dsp_tools.
|
|
16
|
+
from dsp_tools.error.exceptions import InputError
|
|
17
|
+
from dsp_tools.error.exceptions import PermanentConnectionError
|
|
18
|
+
from dsp_tools.utils.request_utils import RequestParameters
|
|
19
|
+
from dsp_tools.utils.request_utils import log_request
|
|
20
|
+
from dsp_tools.utils.request_utils import log_response
|
|
15
21
|
|
|
16
22
|
MAX_FILE_SIZE = 100_000
|
|
23
|
+
MINUTE = 60
|
|
17
24
|
|
|
18
25
|
|
|
19
26
|
@dataclass(frozen=True)
|
|
@@ -26,7 +33,6 @@ class StackConfiguration:
|
|
|
26
33
|
enforce_docker_system_prune: if True, prune Docker without asking the user
|
|
27
34
|
suppress_docker_system_prune: if True, don't prune Docker (and don't ask)
|
|
28
35
|
latest_dev_version: if True, start DSP-API from repo's main branch, instead of the latest deployed version
|
|
29
|
-
api_version_for_validate: if True a fixed API version is taken that has the features necessary for xml-validate
|
|
30
36
|
"""
|
|
31
37
|
|
|
32
38
|
max_file_size: Optional[int] = None
|
|
@@ -34,19 +40,23 @@ class StackConfiguration:
|
|
|
34
40
|
suppress_docker_system_prune: bool = False
|
|
35
41
|
latest_dev_version: bool = False
|
|
36
42
|
upload_test_data: bool = False
|
|
37
|
-
|
|
43
|
+
custom_host: Optional[str] = None
|
|
38
44
|
|
|
39
45
|
def __post_init__(self) -> None:
|
|
40
46
|
"""
|
|
41
47
|
Validate the input parameters passed by the user.
|
|
42
48
|
|
|
43
49
|
Raises:
|
|
44
|
-
|
|
50
|
+
InputError: if one of the parameters is invalid
|
|
45
51
|
"""
|
|
46
52
|
if self.max_file_size is not None and not 1 <= self.max_file_size <= MAX_FILE_SIZE:
|
|
47
|
-
raise
|
|
53
|
+
raise InputError(f"max_file_size must be between 1 and {MAX_FILE_SIZE}")
|
|
48
54
|
if self.enforce_docker_system_prune and self.suppress_docker_system_prune:
|
|
49
|
-
raise
|
|
55
|
+
raise InputError('The arguments "--prune" and "--no-prune" are mutually exclusive')
|
|
56
|
+
if self.custom_host is not None and not regex.match(
|
|
57
|
+
r"^(((\d{1,3}\.){3}\d{1,3})|((([-\w_~]+\.)*([a-z]){2,})))$", self.custom_host
|
|
58
|
+
):
|
|
59
|
+
raise InputError("Invalid format for custom host. Please, enter an IP or a domain name.")
|
|
50
60
|
|
|
51
61
|
|
|
52
62
|
class StackHandler:
|
|
@@ -77,28 +87,25 @@ class StackHandler:
|
|
|
77
87
|
For this reason, we need to know the commit hash of the DSP-API version that is currently deployed,
|
|
78
88
|
so that the files can be retrieved from the correct commit.
|
|
79
89
|
|
|
80
|
-
This function reads the
|
|
81
|
-
that is configured in start-stack-config.yml,
|
|
90
|
+
This function reads the version tag in the docker-compose.yml file,
|
|
82
91
|
and constructs the URL prefix necessary to retrieve the files from the DSP-API repository.
|
|
83
92
|
|
|
84
|
-
If something goes wrong,
|
|
85
|
-
the URL prefix falls back to pointing to the main branch of the DSP-API repository.
|
|
86
|
-
|
|
87
93
|
If the latest development version of DSP-API is started,
|
|
88
94
|
the URL prefix points to the main branch of the DSP-API repository.
|
|
89
95
|
|
|
90
96
|
Returns:
|
|
91
97
|
URL prefix used to retrieve files from the DSP-API repository
|
|
92
98
|
"""
|
|
93
|
-
url_prefix_base = "https://
|
|
99
|
+
url_prefix_base = "https://raw.githubusercontent.com/dasch-swiss/dsp-api"
|
|
94
100
|
|
|
95
101
|
if self.__stack_configuration.latest_dev_version:
|
|
96
102
|
return f"{url_prefix_base}/main/"
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
docker_compose_pth = importlib.resources.files("dsp_tools").joinpath("resources/start-stack/docker-compose.yml")
|
|
105
|
+
docker_compose = yaml.safe_load(docker_compose_pth.read_bytes())
|
|
106
|
+
tag = docker_compose["services"]["api"]["image"].split(":")[-1]
|
|
107
|
+
|
|
108
|
+
return f"{url_prefix_base}/{tag}/"
|
|
102
109
|
|
|
103
110
|
def _copy_resources_to_home_dir(self) -> None:
|
|
104
111
|
"""
|
|
@@ -110,6 +117,7 @@ class StackHandler:
|
|
|
110
117
|
by an earlier run of this method.
|
|
111
118
|
So, this method must always be called, at every run of start-stack.
|
|
112
119
|
"""
|
|
120
|
+
logger.debug("Copying resources to home directory ...")
|
|
113
121
|
docker_path_of_distribution = importlib.resources.files("dsp_tools").joinpath("resources/start-stack")
|
|
114
122
|
for file in docker_path_of_distribution.iterdir():
|
|
115
123
|
with importlib.resources.as_file(file) as f:
|
|
@@ -117,8 +125,40 @@ class StackHandler:
|
|
|
117
125
|
shutil.copy(file_path, self.__docker_path_of_user / file.name)
|
|
118
126
|
if not self.__stack_configuration.latest_dev_version:
|
|
119
127
|
Path(self.__docker_path_of_user / "docker-compose.override.yml").unlink()
|
|
120
|
-
|
|
121
|
-
|
|
128
|
+
|
|
129
|
+
def _set_custom_host(self) -> None:
|
|
130
|
+
"""
|
|
131
|
+
To ensure the frontend can communicate with a backend on a different server, the host in the environments
|
|
132
|
+
needs to be changed.
|
|
133
|
+
By design the IRIs match the host of the database.
|
|
134
|
+
|
|
135
|
+
This is done by overriding the environment variables in the docker-compose.yml and by replacing the
|
|
136
|
+
configuration for the frontend.
|
|
137
|
+
"""
|
|
138
|
+
if self.__stack_configuration.custom_host is not None:
|
|
139
|
+
logger.debug("Setting custom host...")
|
|
140
|
+
self.__localhost_url = f"http://{self.__stack_configuration.custom_host}"
|
|
141
|
+
|
|
142
|
+
docker_template_path = importlib.resources.files("dsp_tools").joinpath(
|
|
143
|
+
"resources/start-stack/docker-compose.override-host.j2"
|
|
144
|
+
)
|
|
145
|
+
docker_template = Template(docker_template_path.read_text(encoding="utf-8"))
|
|
146
|
+
docker_template_rendered = docker_template.render(CUSTOM_HOST=self.__stack_configuration.custom_host)
|
|
147
|
+
Path(self.__docker_path_of_user / "docker-compose.override-host.yml").write_text(
|
|
148
|
+
docker_template_rendered, encoding="utf-8"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
dsp_app_config_template_path = importlib.resources.files("dsp_tools").joinpath(
|
|
152
|
+
"resources/start-stack/dsp-app-config.override-host.j2"
|
|
153
|
+
)
|
|
154
|
+
dsp_app_config_template = Template(dsp_app_config_template_path.read_text(encoding="utf-8"))
|
|
155
|
+
dsp_app_config_rendered = dsp_app_config_template.render(CUSTOM_HOST=self.__stack_configuration.custom_host)
|
|
156
|
+
Path(self.__docker_path_of_user / "dsp-app-config.json").unlink()
|
|
157
|
+
Path(self.__docker_path_of_user / "dsp-app-config.json").write_text(
|
|
158
|
+
dsp_app_config_rendered, encoding="utf-8"
|
|
159
|
+
)
|
|
160
|
+
Path(self.__docker_path_of_user / "docker-compose.override-host.j2").unlink()
|
|
161
|
+
Path(self.__docker_path_of_user / "dsp-app-config.override-host.j2").unlink()
|
|
122
162
|
|
|
123
163
|
def _get_sipi_docker_config_lua(self) -> None:
|
|
124
164
|
"""
|
|
@@ -126,14 +166,15 @@ class StackHandler:
|
|
|
126
166
|
and set the max_file_size parameter if necessary.
|
|
127
167
|
|
|
128
168
|
Raises:
|
|
129
|
-
|
|
169
|
+
InputError: if max_file_size is set but cannot be injected into sipi.docker-config.lua
|
|
130
170
|
"""
|
|
171
|
+
logger.debug("Retrieving sipi.docker-config.lua...")
|
|
131
172
|
docker_config_lua_response = requests.get(f"{self.__url_prefix}sipi/config/sipi.docker-config.lua", timeout=30)
|
|
132
173
|
docker_config_lua_text = docker_config_lua_response.text
|
|
133
174
|
if self.__stack_configuration.max_file_size:
|
|
134
175
|
max_post_size_regex = r"max_post_size ?= ?[\'\"]?\d+[MG][\'\"]?"
|
|
135
176
|
if not regex.search(max_post_size_regex, docker_config_lua_text):
|
|
136
|
-
raise
|
|
177
|
+
raise InputError("Unable to set max_file_size. Please try again without this flag.")
|
|
137
178
|
docker_config_lua_text = regex.sub(
|
|
138
179
|
max_post_size_regex,
|
|
139
180
|
f"max_post_size = '{self.__stack_configuration.max_file_size}M'",
|
|
@@ -147,67 +188,43 @@ class StackHandler:
|
|
|
147
188
|
Start up the Docker container of the fuseki database.
|
|
148
189
|
|
|
149
190
|
Raises:
|
|
150
|
-
|
|
191
|
+
InputError: if the database cannot be started
|
|
151
192
|
"""
|
|
152
|
-
|
|
193
|
+
logger.debug("Starting up the fuseki container...")
|
|
194
|
+
cmd = "docker compose up -d db".split()
|
|
153
195
|
completed_process = subprocess.run(cmd, cwd=self.__docker_path_of_user, check=False)
|
|
154
196
|
if not completed_process or completed_process.returncode != 0:
|
|
155
|
-
msg = "Cannot start the API: Error while executing 'docker compose up
|
|
197
|
+
msg = "Cannot start the API: Error while executing 'docker compose up -d db'"
|
|
156
198
|
logger.error(f"{msg}. completed_process = '{vars(completed_process)}'")
|
|
157
|
-
raise
|
|
199
|
+
raise InputError(msg)
|
|
158
200
|
|
|
159
201
|
def _wait_for_fuseki(self) -> None:
|
|
160
202
|
"""
|
|
161
203
|
Wait up to 6 minutes, until the fuseki database is up and running.
|
|
162
204
|
This function imitates the behaviour of the script dsp-api/webapi/scripts/wait-for-db.sh.
|
|
163
205
|
"""
|
|
206
|
+
logger.debug("Waiting for the fuseki container to be up and running...")
|
|
164
207
|
for _ in range(6 * 60):
|
|
165
208
|
try:
|
|
166
209
|
response = requests.get(f"{self.__localhost_url}:3030/$/server", auth=("admin", "test"), timeout=10)
|
|
167
210
|
if response.ok:
|
|
211
|
+
logger.debug("Fuseki is now up and running.")
|
|
168
212
|
break
|
|
169
213
|
except Exception: # noqa: BLE001 (blind-except)
|
|
170
214
|
time.sleep(1)
|
|
171
215
|
time.sleep(1)
|
|
172
216
|
|
|
173
|
-
def _create_knora_test_repo(self) -> None:
|
|
174
|
-
"""
|
|
175
|
-
Inside fuseki, create the "knora-test" repository.
|
|
176
|
-
This function imitates the behaviour of the script dsp-api/webapi/scripts/fuseki-init-knora-test.sh.
|
|
177
|
-
|
|
178
|
-
Raises:
|
|
179
|
-
UserError: in case of failure
|
|
180
|
-
"""
|
|
181
|
-
repo_template_response = requests.get(
|
|
182
|
-
f"{self.__url_prefix}webapi/scripts/fuseki-repository-config.ttl.template",
|
|
183
|
-
timeout=30,
|
|
184
|
-
)
|
|
185
|
-
repo_template = repo_template_response.text
|
|
186
|
-
repo_template = repo_template.replace("@REPOSITORY@", "knora-test")
|
|
187
|
-
response = requests.post(
|
|
188
|
-
f"{self.__localhost_url}:3030/$/datasets",
|
|
189
|
-
files={"file": ("file.ttl", repo_template, "text/turtle; charset=utf8")},
|
|
190
|
-
auth=("admin", "test"),
|
|
191
|
-
timeout=30,
|
|
192
|
-
)
|
|
193
|
-
if not response.ok:
|
|
194
|
-
msg = (
|
|
195
|
-
"Cannot start DSP-API: Error when creating the 'knora-test' repository. "
|
|
196
|
-
"Is DSP-API perhaps running already?"
|
|
197
|
-
)
|
|
198
|
-
logger.error(f"{msg}. response = {vars(response)}")
|
|
199
|
-
raise UserError(msg)
|
|
200
|
-
|
|
201
217
|
def _load_data_into_repo(self) -> None:
|
|
202
218
|
"""
|
|
203
219
|
Load some basic ontologies and data into the repository.
|
|
204
220
|
This function imitates the behaviour of the script
|
|
205
|
-
dsp-api/webapi/
|
|
221
|
+
dsp-api/webapi/scripts/fuseki-init-knora-test.sh.
|
|
206
222
|
|
|
207
223
|
Raises:
|
|
208
|
-
|
|
224
|
+
InputError: if one of the graphs cannot be created
|
|
209
225
|
"""
|
|
210
|
-
|
|
226
|
+
logger.debug("Loading data into the 'dsp-repo' repository...")
|
|
227
|
+
graph_prefix = f"{self.__localhost_url}:3030/dsp-repo/data?graph="
|
|
211
228
|
ttl_files = [
|
|
212
229
|
("webapi/src/main/resources/knora-ontologies/knora-admin.ttl", "http://www.knora.org/ontology/knora-admin"),
|
|
213
230
|
("webapi/src/main/resources/knora-ontologies/knora-base.ttl", "http://www.knora.org/ontology/knora-base"),
|
|
@@ -224,7 +241,7 @@ class StackHandler:
|
|
|
224
241
|
if not ttl_response.ok:
|
|
225
242
|
msg = f"Cannot start DSP-API: Error when retrieving '{self.__url_prefix + ttl_file}'"
|
|
226
243
|
logger.error(f"{msg}'. response = {vars(ttl_response)}")
|
|
227
|
-
raise
|
|
244
|
+
raise InputError(msg)
|
|
228
245
|
ttl_text = ttl_response.text
|
|
229
246
|
response = requests.post(
|
|
230
247
|
graph_prefix + graph,
|
|
@@ -234,7 +251,7 @@ class StackHandler:
|
|
|
234
251
|
)
|
|
235
252
|
if not response.ok:
|
|
236
253
|
logger.error(f"Cannot start DSP-API: Error when creating graph '{graph}'. response = {vars(response)}")
|
|
237
|
-
raise
|
|
254
|
+
raise InputError(f"Cannot start DSP-API: Error when creating graph '{graph}'")
|
|
238
255
|
|
|
239
256
|
def _create_admin_user(self) -> None:
|
|
240
257
|
"""
|
|
@@ -242,9 +259,10 @@ class StackHandler:
|
|
|
242
259
|
The password is the hash for "test".
|
|
243
260
|
|
|
244
261
|
Raises:
|
|
245
|
-
|
|
262
|
+
InputError: If the user cannot be created.
|
|
246
263
|
"""
|
|
247
|
-
|
|
264
|
+
logger.debug("Creating the default admin user...")
|
|
265
|
+
graph_prefix = f"{self.__localhost_url}:3030/dsp-repo/data?graph="
|
|
248
266
|
admin_graph = "http://www.knora.org/data/admin"
|
|
249
267
|
admin_user = """
|
|
250
268
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
@@ -271,13 +289,12 @@ class StackHandler:
|
|
|
271
289
|
)
|
|
272
290
|
if not response.ok:
|
|
273
291
|
logger.error(f"Cannot start DSP-API: Error when creating the admin user. response = {vars(response)}")
|
|
274
|
-
raise
|
|
292
|
+
raise InputError("Cannot start DSP-API: Error when creating the admin user.")
|
|
275
293
|
|
|
276
294
|
def _initialize_fuseki(self) -> None:
|
|
277
295
|
"""
|
|
278
|
-
|
|
296
|
+
Load some basic ontologies and data into the 'dsp-repo' repository.
|
|
279
297
|
"""
|
|
280
|
-
self._create_knora_test_repo()
|
|
281
298
|
if self.__stack_configuration.upload_test_data:
|
|
282
299
|
self._load_data_into_repo()
|
|
283
300
|
else:
|
|
@@ -290,11 +307,13 @@ class StackHandler:
|
|
|
290
307
|
"""
|
|
291
308
|
compose_str = "docker compose -f docker-compose.yml"
|
|
292
309
|
if self.__stack_configuration.latest_dev_version:
|
|
310
|
+
logger.debug("In order to get the latest dev version, run 'docker compose pull' ...")
|
|
293
311
|
subprocess.run("docker compose pull".split(), cwd=self.__docker_path_of_user, check=True)
|
|
294
312
|
compose_str += " -f docker-compose.override.yml"
|
|
295
|
-
|
|
296
|
-
compose_str += " -f docker-compose-
|
|
313
|
+
if self.__stack_configuration.custom_host is not None:
|
|
314
|
+
compose_str += " -f docker-compose.override-host.yml"
|
|
297
315
|
compose_str += " up -d"
|
|
316
|
+
logger.debug(f"Running '{compose_str}' ...")
|
|
298
317
|
subprocess.run(compose_str.split(), cwd=self.__docker_path_of_user, check=True)
|
|
299
318
|
|
|
300
319
|
def _wait_for_api(self) -> None:
|
|
@@ -302,16 +321,37 @@ class StackHandler:
|
|
|
302
321
|
Wait until the API is up and running.
|
|
303
322
|
This mimicks the behaviour of the script webapi/scripts/wait-for-api.sh in the DSP-API repository.
|
|
304
323
|
"""
|
|
305
|
-
for
|
|
324
|
+
logger.debug("Waiting for the API to start...")
|
|
325
|
+
for num_secs in range(6 * 60):
|
|
306
326
|
try:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
327
|
+
params = RequestParameters("GET", f"{self.__localhost_url}:3333/health", timeout=1)
|
|
328
|
+
log_request(params)
|
|
329
|
+
response = requests.get(params.url, timeout=params.timeout)
|
|
330
|
+
log_response(response)
|
|
331
|
+
if response.ok:
|
|
332
|
+
break
|
|
333
|
+
except requests.exceptions.RequestException as e:
|
|
334
|
+
logger.debug(f"RequestException while checking API status: {e}")
|
|
335
|
+
if num_secs > MINUTE / 2 and num_secs % 10 == 0:
|
|
336
|
+
# There is probably an issue, so we need more logs
|
|
337
|
+
with contextlib.suppress():
|
|
338
|
+
docker_ps_output = subprocess.run(
|
|
339
|
+
"docker ps -a".split(), cwd=self.__docker_path_of_user, check=True, capture_output=True
|
|
340
|
+
).stdout.decode("utf-8")
|
|
341
|
+
docker_ps_output = "\n\t".join(docker_ps_output.split("\n"))
|
|
342
|
+
logger.debug(f"docker ps -a output:\n\t{docker_ps_output}")
|
|
343
|
+
docker_logs_output = subprocess.run(
|
|
344
|
+
"docker logs start-stack-api-1".split(),
|
|
345
|
+
cwd=self.__docker_path_of_user,
|
|
346
|
+
check=True,
|
|
347
|
+
capture_output=True,
|
|
348
|
+
).stdout.decode("utf-8")
|
|
349
|
+
docker_logs_output = "\n\t".join(docker_logs_output.split("\n"))
|
|
350
|
+
logger.debug(f"Logs of DSP-API container:\n\t{docker_logs_output}")
|
|
351
|
+
time.sleep(1)
|
|
352
|
+
msg = f"DSP-API is now running on {self.__localhost_url}:3333/ and DSP-APP on {self.__localhost_url}:4200/"
|
|
353
|
+
logger.debug(msg)
|
|
354
|
+
print(msg)
|
|
315
355
|
|
|
316
356
|
def _execute_docker_system_prune(self) -> None:
|
|
317
357
|
"""
|
|
@@ -333,6 +373,7 @@ class StackHandler:
|
|
|
333
373
|
"to keep your docker clean and running smoothly. [y/n]"
|
|
334
374
|
)
|
|
335
375
|
if prune_docker == "y":
|
|
376
|
+
logger.debug("Running 'docker system prune --volumes -f' ...")
|
|
336
377
|
subprocess.run("docker system prune --volumes -f".split(), cwd=self.__docker_path_of_user, check=False)
|
|
337
378
|
|
|
338
379
|
def _start_docker_containers(self) -> None:
|
|
@@ -356,15 +397,20 @@ class StackHandler:
|
|
|
356
397
|
After startup, ask user if Docker should be pruned or not.
|
|
357
398
|
|
|
358
399
|
Raises:
|
|
359
|
-
|
|
400
|
+
InputError: if the stack cannot be started with the parameters passed by the user
|
|
360
401
|
|
|
361
402
|
Returns:
|
|
362
403
|
True if everything went well, False otherwise
|
|
363
404
|
"""
|
|
364
|
-
if subprocess.run("docker stats --no-stream".split(), check=False, capture_output=True).returncode != 0:
|
|
365
|
-
raise UserError("Docker is not running properly. Please start Docker and try again.")
|
|
366
405
|
self._copy_resources_to_home_dir()
|
|
367
|
-
self.
|
|
406
|
+
self._set_custom_host()
|
|
407
|
+
try:
|
|
408
|
+
self._get_sipi_docker_config_lua()
|
|
409
|
+
except (requests.ConnectionError, requests.ReadTimeout):
|
|
410
|
+
raise PermanentConnectionError(
|
|
411
|
+
"This command requires an internet connection. "
|
|
412
|
+
"Please ensure that your computer is connected and try again."
|
|
413
|
+
)
|
|
368
414
|
self._start_docker_containers()
|
|
369
415
|
return True
|
|
370
416
|
|
|
@@ -376,4 +422,7 @@ class StackHandler:
|
|
|
376
422
|
True if everything went well, False otherwise
|
|
377
423
|
"""
|
|
378
424
|
subprocess.run("docker compose down --volumes".split(), cwd=self.__docker_path_of_user, check=True)
|
|
425
|
+
shutil.rmtree(self.__docker_path_of_user / "sipi", ignore_errors=True)
|
|
426
|
+
# ignore all errors, because the dir cannot be found if this function is called multiple times,
|
|
427
|
+
# and because in GitHub CI, python lacks permissions to delete this dir
|
|
379
428
|
return True
|