From 608509681afcc43fd92bff248d35177951c2097d Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Tue, 5 Nov 2024 13:27:03 +0000 Subject: [PATCH] Feature/s3 data db --- .docs/.swagger/swagger-generate.sh | 3 +- .docs/api/analyse-service.md | 10 +- .docs/api/auth-service.md | 6 + .docs/api/broker-service.md | 6 + .docs/api/dashboard-service.md | 10 +- .docs/api/data-db.md | 22 +- .docs/api/data-service.md | 10 +- .docs/api/identity-service.md | 6 + .docs/api/metadata-db.md | 6 + .docs/api/metadata-service.md | 10 +- .docs/api/metric-db.md | 10 +- .docs/api/search-service.md | 10 +- .docs/api/storage-service.md | 9 +- .docs/api/ui.md | 6 + .docs/api/upload-service.md | 6 + .docs/changelog.md | 1 + .docs/index.md | 3 +- .docs/installation.md | 1 - .docs/kubernetes.md | 9 + .gitlab-ci.yml | 10 - README.md | 3 +- dbrepo-analyse-service/Dockerfile | 20 +- dbrepo-analyse-service/Pipfile.lock | 1182 ++++++++--------- dbrepo-analyse-service/api/dto.py | 1 + dbrepo-analyse-service/app.py | 9 +- .../as-yml/import_dataset.yml | 62 + dbrepo-analyse-service/clients/s3_client.py | 5 +- dbrepo-analyse-service/determine_dt.py | 18 +- .../lib/dbrepo-1.4.7.tar.gz | Bin 39442 -> 39237 bytes dbrepo-analyse-service/test/conftest.py | 7 +- .../test/test_determine_dt.py | 27 +- dbrepo-data-db/.gitignore | 127 -- dbrepo-data-db/README.md | 5 - dbrepo-data-db/sidecar/Dockerfile | 24 - dbrepo-data-db/sidecar/Pipfile | 27 - dbrepo-data-db/sidecar/Pipfile.lock | 945 ------------- dbrepo-data-db/sidecar/README.md | 9 - dbrepo-data-db/sidecar/app.py | 198 --- .../sidecar/clients/keycloak_client.py | 35 - dbrepo-data-db/sidecar/clients/s3_client.py | 80 -- dbrepo-data-db/sidecar/ds-yml/export.yml | 32 - dbrepo-data-db/sidecar/ds-yml/health.yml | 32 - dbrepo-data-db/sidecar/ds-yml/import.yml | 32 - dbrepo-data-db/sidecar/metrics.md | 4 - dbrepo-data-service/Dockerfile | 8 +- dbrepo-data-service/metrics.md | 1 + dbrepo-data-service/pom.xml | 70 +- .../at/tuwien/endpoints/AccessEndpoint.java | 13 +- .../at/tuwien/endpoints/DatabaseEndpoint.java | 3 +- .../at/tuwien/endpoints/SubsetEndpoint.java | 12 +- .../at/tuwien/endpoints/TableEndpoint.java | 73 +- .../at/tuwien/endpoints/ViewEndpoint.java | 40 +- .../tuwien/handlers/ApiExceptionHandler.java | 21 +- .../src/main/resources/application-local.yml | 21 +- .../src/main/resources/application.yml | 6 +- .../java/at/tuwien/config/MariaDbConfig.java | 4 +- .../endpoint/SubsetEndpointUnitTest.java | 57 +- .../endpoint/TableEndpointUnitTest.java | 99 +- .../tuwien/endpoint/ViewEndpointUnitTest.java | 52 + ...ava => AnalyseServiceGatewayUnitTest.java} | 45 +- .../MetadataServiceGatewayUnitTest.java | 10 +- .../handlers/ApiExceptionHandlerTest.java | 54 +- .../StorageServiceIntegrationTest.java | 110 +- .../service/SubsetServiceIntegrationTest.java | 45 +- .../service/TableServiceIntegrationTest.java | 19 +- .../service/ViewServiceIntegrationTest.java | 3 +- dbrepo-data-service/services/pom.xml | 5 - .../java/at/tuwien/auth/AuthTokenFilter.java | 4 +- .../java/at/tuwien/config/GatewayConfig.java | 3 + .../java/at/tuwien/config/JacksonConfig.java | 4 +- .../java/at/tuwien/config/QueryConfig.java | 9 - .../main/java/at/tuwien/config/S3Config.java | 7 +- .../java/at/tuwien/config/SparkConfig.java | 71 + .../tuwien/gateway/AnalyseServiceGateway.java | 31 + .../gateway/DataDatabaseSidecarGateway.java | 30 - .../impl/AnalyseServiceGatewayImpl.java | 85 ++ .../impl/DataDatabaseSidecarGatewayImpl.java | 66 - .../gateway/impl/KeycloakGatewayImpl.java | 8 +- .../impl/MetadataServiceGatewayImpl.java | 40 +- .../java/at/tuwien/mapper/DataMapper.java | 18 +- .../java/at/tuwien/mapper/MariaDbMapper.java | 78 +- .../at/tuwien/service/StorageService.java | 29 +- .../java/at/tuwien/service/SubsetService.java | 16 +- .../java/at/tuwien/service/TableService.java | 121 +- .../java/at/tuwien/service/ViewService.java | 40 +- .../service/impl/HibernateConnector.java | 47 +- .../service/impl/StorageServiceS3Impl.java | 104 +- .../impl/SubsetServiceMariaDbImpl.java | 81 +- .../service/impl/TableServiceMariaDbImpl.java | 110 +- .../service/impl/ViewServiceMariaDbImpl.java | 78 +- dbrepo-metadata-db/1_setup-schema.sql | 6 +- dbrepo-metadata-service/Dockerfile | 2 +- .../api/container/ContainerCreateDto.java | 10 +- .../at/tuwien/api/container/ContainerDto.java | 8 - .../internal/PrivilegedContainerDto.java | 8 - .../tuwien/api/database/query/ImportDto.java | 8 +- .../tuwien/entities/container/Container.java | 6 - .../tuwien/entities/database/ViewColumn.java | 2 +- .../tuwien/entities/identifier/Creator.java | 6 +- .../entities/identifier/Identifier.java | 4 +- .../identifier/IdentifierDescription.java | 4 +- .../entities/identifier/IdentifierFunder.java | 2 +- .../entities/identifier/IdentifierTitle.java | 4 +- .../identifier/RelatedIdentifier.java | 4 +- .../entities/maintenance/BannerMessage.java | 2 +- dbrepo-metadata-service/pom.xml | 2 +- ...tion.java => AnalyseServiceException.java} | 10 +- .../exception/SidecarImportException.java | 21 - .../at/tuwien/endpoints/AccessEndpoint.java | 16 +- .../at/tuwien/endpoints/DatabaseEndpoint.java | 3 + .../tuwien/endpoints/IdentifierEndpoint.java | 5 - .../at/tuwien/endpoints/TableEndpoint.java | 16 +- .../at/tuwien/endpoints/ViewEndpoint.java | 12 +- .../tuwien/handlers/ApiExceptionHandler.java | 21 +- .../src/main/resources/application-local.yml | 1 - .../src/main/resources/application.yml | 1 - .../endpoints/ViewEndpointUnitTest.java | 68 +- ...nticationPrivilegedIntegrationMvcTest.java | 20 +- .../DatabaseServicePersistenceTest.java | 4 - .../main/java/at/tuwien/test/BaseTest.java | 12 - dbrepo-metric-db/prometheus.yml | 2 +- dbrepo-search-service/Pipfile.lock | 1110 ++++++++-------- dbrepo-search-service/init/Pipfile.lock | 738 +++++----- .../init/lib/dbrepo-1.4.7.tar.gz | Bin 39442 -> 39237 bytes dbrepo-search-service/lib/dbrepo-1.4.7.tar.gz | Bin 39442 -> 39237 bytes dbrepo-ui/components/table/TableImport.vue | 35 +- dbrepo-ui/locales/en-US.json | 5 +- .../[database_id]/table/[table_id]/data.vue | 21 +- .../[database_id]/table/create/dataset.vue | 25 +- dbrepo-ui/utils/index.ts | 8 + docker-compose.yml | 32 +- helm/dbrepo-mariadb-galera/.gitignore | 6 - helm/dbrepo-mariadb-galera/.helmignore | 30 - helm/dbrepo-mariadb-galera/Chart.lock | 6 - helm/dbrepo-mariadb-galera/Chart.yaml | 23 - helm/dbrepo-mariadb-galera/README.md | 6 - .../charts/mariadb-galera-10.1.3.tgz | Bin 48716 -> 0 bytes .../templates/_compatibility.tpl | 42 - .../templates/_helpers.tpl | 62 - .../templates/_names.tpl | 6 - .../templates/configmap.yaml | 580 -------- .../templates/secret.yaml | 9 - helm/dbrepo-mariadb-galera/values.schema.json | 301 ----- helm/dbrepo-mariadb-galera/values.yaml | 107 -- helm/dbrepo/Chart.lock | 10 +- helm/dbrepo/Chart.yaml | 8 +- .../charts/dbrepo-mariadb-galera-1.4.6.tgz | Bin 57156 -> 0 bytes helm/dbrepo/templates/analyse-secret.yaml | 5 +- helm/dbrepo/templates/data-deployment.yaml | 2 +- helm/dbrepo/templates/data-secret.yaml | 3 - helm/dbrepo/templates/metadata-configmap.yaml | 137 +- .../dbrepo/templates/metadata-deployment.yaml | 2 +- helm/dbrepo/values.schema.json | 29 +- helm/dbrepo/values.yaml | 67 +- lib/python/dbrepo/RestClient.py | 6 +- lib/python/dbrepo/api/dto.py | 6 +- make/dev.mk | 2 + make/rel.mk | 2 - 158 files changed, 3196 insertions(+), 5414 deletions(-) create mode 100644 dbrepo-analyse-service/as-yml/import_dataset.yml delete mode 100644 dbrepo-data-db/.gitignore delete mode 100644 dbrepo-data-db/README.md delete mode 100644 dbrepo-data-db/sidecar/Dockerfile delete mode 100644 dbrepo-data-db/sidecar/Pipfile delete mode 100644 dbrepo-data-db/sidecar/Pipfile.lock delete mode 100644 dbrepo-data-db/sidecar/README.md delete mode 100644 dbrepo-data-db/sidecar/app.py delete mode 100644 dbrepo-data-db/sidecar/clients/keycloak_client.py delete mode 100644 dbrepo-data-db/sidecar/clients/s3_client.py delete mode 100644 dbrepo-data-db/sidecar/ds-yml/export.yml delete mode 100644 dbrepo-data-db/sidecar/ds-yml/health.yml delete mode 100644 dbrepo-data-db/sidecar/ds-yml/import.yml delete mode 100644 dbrepo-data-db/sidecar/metrics.md rename dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/{DataDatabaseGatewayUnitTest.java => AnalyseServiceGatewayUnitTest.java} (68%) create mode 100644 dbrepo-data-service/services/src/main/java/at/tuwien/config/SparkConfig.java create mode 100644 dbrepo-data-service/services/src/main/java/at/tuwien/gateway/AnalyseServiceGateway.java delete mode 100644 dbrepo-data-service/services/src/main/java/at/tuwien/gateway/DataDatabaseSidecarGateway.java create mode 100644 dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/AnalyseServiceGatewayImpl.java delete mode 100644 dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/DataDatabaseSidecarGatewayImpl.java rename dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/{SidecarExportException.java => AnalyseServiceException.java} (53%) delete mode 100644 dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarImportException.java delete mode 100644 helm/dbrepo-mariadb-galera/.gitignore delete mode 100644 helm/dbrepo-mariadb-galera/.helmignore delete mode 100644 helm/dbrepo-mariadb-galera/Chart.lock delete mode 100644 helm/dbrepo-mariadb-galera/Chart.yaml delete mode 100644 helm/dbrepo-mariadb-galera/README.md delete mode 100644 helm/dbrepo-mariadb-galera/charts/mariadb-galera-10.1.3.tgz delete mode 100644 helm/dbrepo-mariadb-galera/templates/_compatibility.tpl delete mode 100644 helm/dbrepo-mariadb-galera/templates/_helpers.tpl delete mode 100644 helm/dbrepo-mariadb-galera/templates/_names.tpl delete mode 100644 helm/dbrepo-mariadb-galera/templates/configmap.yaml delete mode 100644 helm/dbrepo-mariadb-galera/templates/secret.yaml delete mode 100644 helm/dbrepo-mariadb-galera/values.schema.json delete mode 100644 helm/dbrepo-mariadb-galera/values.yaml delete mode 100644 helm/dbrepo/charts/dbrepo-mariadb-galera-1.4.6.tgz diff --git a/.docs/.swagger/swagger-generate.sh b/.docs/.swagger/swagger-generate.sh index 8ea2981243..884c2adfac 100644 --- a/.docs/.swagger/swagger-generate.sh +++ b/.docs/.swagger/swagger-generate.sh @@ -4,12 +4,11 @@ services[4000]=search services[5000]=analyse services[9093]=data services[9099]=metadata -services[3305]=sidecar # requires https://github.com/mikefarah/yq/ -> v4.44.3 function retrieve () { - if [[ "$2" == analyse ]] || [[ "$2" == search ]] || [[ "$2" == sidecar ]]; then + if [[ "$2" == analyse ]] || [[ "$2" == search ]]; then echo "... retrieve json api from localhost:$1" curl -sSL "http://localhost:$1/api-$2.json" | yq -p=json > "./.docs/.swagger/api-$2.yaml" else diff --git a/.docs/api/analyse-service.md b/.docs/api/analyse-service.md index 3529f0f3df..6a6bb5f506 100644 --- a/.docs/api/analyse-service.md +++ b/.docs/api/analyse-service.md @@ -6,12 +6,18 @@ author: Martin Weise !!! debug "Debug Information" - Image: [`registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.4.5`](https://hub.docker.com/r/dbrepo/analyse-service) + Image: [`registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.4.7`](https://hub.docker.com/r/dbrepo/analyse-service) * Ports: 5000/tcp * Prometheus: `http://<hostname>:5000/metrics` * Health: `http://<hostname>:5000/health` - * Swagger UI: `http://<hostname>:5000/swagger-ui/` <a href="./swagger/analyse" target="_blank">:fontawesome-solid-square-up-right: view online</a> + * Swagger UI: `http://<hostname>:5000/swagger-ui/` <a href="../../rest/" target="_blank">:fontawesome-solid-square-up-right: view online</a> + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/analyse-service 5000:80 + ``` ## Overview diff --git a/.docs/api/auth-service.md b/.docs/api/auth-service.md index 7b59ca1567..93e87beaf2 100644 --- a/.docs/api/auth-service.md +++ b/.docs/api/auth-service.md @@ -11,6 +11,12 @@ author: Martin Weise * Ports: 8080/tcp * UI: `http://<hostname>:8080/` + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/auth-service 8080:80 + ``` + ## Overview By default, users are created using the [User Interface](../ui) and the sign-up page in the User Interface. diff --git a/.docs/api/broker-service.md b/.docs/api/broker-service.md index 41e2dc10b1..373eb35b95 100644 --- a/.docs/api/broker-service.md +++ b/.docs/api/broker-service.md @@ -13,6 +13,12 @@ author: Martin Weise * Prometheus: `http://<hostname>:15692/metrics` * Management: `http://<hostname>:15672` + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/broker-service 15672:15672 + ``` + ## Overview It holds exchanges and topics responsible for holding AMQP messages for later consumption. We diff --git a/.docs/api/dashboard-service.md b/.docs/api/dashboard-service.md index 96db826021..60220229b3 100644 --- a/.docs/api/dashboard-service.md +++ b/.docs/api/dashboard-service.md @@ -8,8 +8,14 @@ author: Martin Weise Image: [`docker.io/bitnami/grafana:10.4.9-debian-12-r0`](https://hub.docker.com/r/bitnami/grafana) - * Ports: `http://<hostname>/dashboard` - * Prometheus: `http://<hostname>/dashboard/prometheus` + * Ports: `http://<hostname>:3000` + * Prometheus: `http://<hostname>:3000/prometheus` + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/broker-service 3000:3000 + ``` ## Overview diff --git a/.docs/api/data-db.md b/.docs/api/data-db.md index d5ba8d8361..aecabb9736 100644 --- a/.docs/api/data-db.md +++ b/.docs/api/data-db.md @@ -9,11 +9,11 @@ author: Martin Weise * Ports: 3306/tcp * JDBC: `jdbc://mariadb:<hostname>:3306` -!!! debug "Debug Information" - - Image: [`dbrepo/data-db-sidecar:1.4.5`](https://hub.docker.com/r/dbrepo/data-db-sidecar) + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: - * Ports: 8080/tcp + ```shell + kubectl [-n namespace] port-forward svc/data-db 3306:3306 + ``` ## Overview @@ -22,20 +22,6 @@ Any number of MariaDB ata databases can be integrated into DBRepo, even non-empt registered in the Metadata Database to be visible in the [User Interface](../ui) and usable from e.g. the Python Library. -## Architecture - -### Sidecar - -We deploy a sidecar that handles the CSV-file upload/download operations between -the [Storage Service](../system-services-storage) and the Data Database using a Python Flask application and -the [`boto3`](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) client until MariaDB supports S3 -natively. - -<figure markdown> - -<figcaption>Sidecar that handles the CSV-file upload/download.</figcaption> -</figure> - ## Data The procedures require the user-generated databases to have the same collation (because of comparison operations). diff --git a/.docs/api/data-service.md b/.docs/api/data-service.md index 186732a472..64f0397613 100644 --- a/.docs/api/data-service.md +++ b/.docs/api/data-service.md @@ -6,7 +6,7 @@ author: Martin Weise !!! debug "Debug Information" - Image: [`registry.datalab.tuwien.ac.at/dbrepo/data-service:1.4.5`](https://hub.docker.com/r/dbrepo/data-service) + Image: [`registry.datalab.tuwien.ac.at/dbrepo/data-service:1.4.7`](https://hub.docker.com/r/dbrepo/data-service) * Ports: 9093/tcp * Info: `http://<hostname>:9093/actuator/info` @@ -14,7 +14,13 @@ author: Martin Weise - Readiness: `http://<hostname>:9093/actuator/health/readiness` - Liveness: `http://<hostname>:9093/actuator/health/liveness` * Prometheus: `http://<hostname>:9093/actuator/prometheus` - * Swagger UI: `http://<hostname>:9093/swagger-ui/index.html` <a href="./swagger/data" target="_blank">:fontawesome-solid-square-up-right: view online</a> + * Swagger UI: `http://<hostname>:9093/swagger-ui/index.html` <a href="../../rest/" target="_blank">:fontawesome-solid-square-up-right: view online</a> + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/data-service 9093:80 + ``` ## Overview diff --git a/.docs/api/identity-service.md b/.docs/api/identity-service.md index fc075be448..3a1ae2bb55 100644 --- a/.docs/api/identity-service.md +++ b/.docs/api/identity-service.md @@ -10,6 +10,12 @@ author: Martin Weise * Ports: 1389/tcp, 1636/tcp + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/identity-service 1389:389 + ``` + ## Overview This optional service holds the user identities which we simply call identities in the following. It is integrated into diff --git a/.docs/api/metadata-db.md b/.docs/api/metadata-db.md index 61a56ed1ac..ba93d051d0 100644 --- a/.docs/api/metadata-db.md +++ b/.docs/api/metadata-db.md @@ -9,6 +9,12 @@ author: Martin Weise * Ports: 3306/tcp * JDBC: `jdbc://mariadb:<hostname>:3306` + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/metadata-db 3306:3306 + ``` + ## Overview The metadata database is the single, central source of truth within DBRepo and holds all metadata information for diff --git a/.docs/api/metadata-service.md b/.docs/api/metadata-service.md index 9d9c39ee25..a9218b4733 100644 --- a/.docs/api/metadata-service.md +++ b/.docs/api/metadata-service.md @@ -6,7 +6,7 @@ author: Martin Weise !!! debug "Debug Information" - Image: [`registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.4.5`](https://hub.docker.com/r/dbrepo/metadata-service) + Image: [`registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.4.7`](https://hub.docker.com/r/dbrepo/metadata-service) * Ports: 9099/tcp * Info: `http://<hostname>:9099/actuator/info` @@ -14,7 +14,13 @@ author: Martin Weise - Readiness: `http://<hostname>:9099/actuator/health/readiness` - Liveness: `http://<hostname>:9099/actuator/health/liveness` * Prometheus: `http://<hostname>:9099/actuator/prometheus` - * Swagger UI: `http://<hostname>:9099/swagger-ui/index.html` + * Swagger UI: `http://<hostname>:9099/swagger-ui/index.html` <a href="../../rest/" target="_blank">:fontawesome-solid-square-up-right: view online</a> + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/metadata-service 9099:80 + ``` ## Overview diff --git a/.docs/api/metric-db.md b/.docs/api/metric-db.md index 8ac9b611d9..f1fe9c11ab 100644 --- a/.docs/api/metric-db.md +++ b/.docs/api/metric-db.md @@ -8,6 +8,14 @@ author: Martin Weise Image: [`bitnami/prometheus:2.54.1-debian-12-r4`](https://hub.docker.com/r/bitnami/prometheus) + * Ports: 8080/tcp + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine on port `8080`: + + ```shell + kubectl [-n namespace] port-forward svc/data-db 8080:80 + ``` + ## Overview The Metric Database is responsible for saving time-series data for the [Dashboard Service](../../api/dashboard-service). @@ -140,8 +148,6 @@ The [Data Database Sidecar](#) metrics are: | `dbrepo_search_update_database` | Time needed to update a database in the search database | | `dbrepo_search_delete_database` | Time needed to delete a database in the search database | - - ## Limitations !!! question "Do you miss functionality? Do these limitations affect you?" diff --git a/.docs/api/search-service.md b/.docs/api/search-service.md index 5c16b49955..ede6eefd65 100644 --- a/.docs/api/search-service.md +++ b/.docs/api/search-service.md @@ -6,12 +6,18 @@ author: Martin Weise !!! debug "Debug Information" - Image: [`registry.datalab.tuwien.ac.at/dbrepo/search-service:1.4.5`](https://hub.docker.com/r/dbrepo/search-service) + Image: [`registry.datalab.tuwien.ac.at/dbrepo/search-service:1.4.7`](https://hub.docker.com/r/dbrepo/search-service) * Ports: 4000/tcp * Health: `http://<hostname>:4000/api/search/health` * Prometheus: `http://<hostname>:4000/metrics` - * Swagger UI: `http://<hostname>:4000/swagger-ui/` + * Swagger UI: `http://<hostname>:4000/swagger-ui/` <a href="../../rest/" target="_blank">:fontawesome-solid-square-up-right: view online</a> + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/search-service 4000:80 + ``` ## Overview diff --git a/.docs/api/storage-service.md b/.docs/api/storage-service.md index a8da4f0721..939e3dbbcb 100644 --- a/.docs/api/storage-service.md +++ b/.docs/api/storage-service.md @@ -8,8 +8,15 @@ author: Martin Weise Image: [`docker.io/chrislusf/seaweedfs:3.59`](https://hub.docker.com/r/chrislusf/seaweedfs) - * Ports: 9000/tcp + * Ports: 8888/tcp, 9000/tcp * Prometheus: `http://<hostname>:9091/metrics` + * Filer UI: `http://<hostname>:8888` + + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/storage-service-s3 9000:8333 + ``` ## Overview diff --git a/.docs/api/ui.md b/.docs/api/ui.md index 1f957bb9c7..8753060f63 100644 --- a/.docs/api/ui.md +++ b/.docs/api/ui.md @@ -10,6 +10,12 @@ author: Martin Weise * Ports: 3000/tcp + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/ui 3000:80 + ``` + The User Interface is configured in the `runtimeConfig` section of the `nuxt.config.ts` file during build time. For the runtime, you need to override those values through environment variables or by mounting a `.env` file. As a small example, you can configure the logo :material-numeric-1-circle-outline: in Figure 2. Make sure you mount the logo as diff --git a/.docs/api/upload-service.md b/.docs/api/upload-service.md index f8ad58ebcb..97ca74d14b 100644 --- a/.docs/api/upload-service.md +++ b/.docs/api/upload-service.md @@ -12,6 +12,12 @@ author: Martin Weise * Prometheus: `http://<hostname>:1080/api/upload/metrics` * API: `http://<hostname>:1080/api/upload` + To directly access in Kubernetes (for e.g. debugging), forward the svc port to your local machine: + + ```shell + kubectl [-n namespace] port-forward svc/upload-service 1080:80 + ``` + ## Overview We use the [TUS](https://tus.io/) open protocol for resume-able file uploads which based entirely on HTTP. Even though diff --git a/.docs/changelog.md b/.docs/changelog.md index 94a39ff64a..9a373f7275 100644 --- a/.docs/changelog.md +++ b/.docs/changelog.md @@ -19,6 +19,7 @@ author: Martin Weise #### Changes +* Remove the Data Database Sidecar and replace it with Apache Spark 4. * Allow anonymous users to create subsets for public databases in [#449](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/449). * Show file upload progress diff --git a/.docs/index.md b/.docs/index.md index f24d5c598e..aa26e3b40c 100644 --- a/.docs/index.md +++ b/.docs/index.md @@ -31,11 +31,12 @@ Installing DBRepo is very easy or ## Who is using DBRepo? - [TU Wien](https://dbrepo1.ec.tuwien.ac.at) +- TU Graz - TU Darmstadt - [Universität Hamburg](https://dbrepo.fdm.uni-hamburg.de/) - [Universiti Teknikal Malaysia Melaka](https://dbrepo.utem.edu.my/) - University of the Philippines -- [Universiti Sains Malaysia](https://dbrepo.wrfexpress.com/) +- [Universiti Sains Malaysia](https://atmosfera.usm.my/dbrepo/) ## How can I try DBRepo? diff --git a/.docs/installation.md b/.docs/installation.md index 024d39bcd4..4a0c6c6f43 100644 --- a/.docs/installation.md +++ b/.docs/installation.md @@ -29,7 +29,6 @@ settings. - min. 8 vCPU cores - min. 8GB free RAM memory - min. 200GB free SSD storage -- min. 100Mbit/s connection Since DBRepo is intended to be a publicly available repository, an optional fixed/static IP-address with optional SSL/TLS certificate is recommended. Follow the [secure install](#secure-install) guide. diff --git a/.docs/kubernetes.md b/.docs/kubernetes.md index 2384f61d04..bd80e6ccee 100644 --- a/.docs/kubernetes.md +++ b/.docs/kubernetes.md @@ -26,6 +26,15 @@ helm upgrade --install dbrepo \ * Kubernetes 3.8.0+ * PV provisioner support in the underlying infrastructure +### Resource Quota + +* `requests.cpu=8` +* `requests.memory=8Gi` +* `requests.storage` >= 25 +* `pods` >= 50 +* `services` >= 50 +* `secrets` >= 50 + ## Limitations 1. The entire Helm deployment is rootless (=`runAsNonRoot=true`) except for diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f571fba1d1..d6c97103ae 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,15 +59,6 @@ build-analyse-service: - "pip install pipenv" - "pipenv install gunicorn && pipenv install --dev --system --deploy" -build-data-db-sidecar: - image: docker.io/python:3.11-alpine - stage: build - variables: - PIPENV_PIPFILE: "./dbrepo-data-db/sidecar/Pipfile" - script: - - "pip install pipenv" - - "pipenv install gunicorn && pipenv install --dev --system --deploy" - build-lib: image: docker.io/python:3.11-alpine stage: build @@ -147,7 +138,6 @@ lint-docker-compose: - "IGNORE_IMAGE=1 IGNORE_PORTS=1 bash .scripts/check-service.sh 'dbrepo-broker-service'" - "IGNORE_PORTS=1 bash .scripts/check-service.sh 'dbrepo-dashboard-service'" - "bash .scripts/check-service.sh 'dbrepo-data-db'" - - "IGNORE_IMAGE=1 IGNORE_PORTS=1 bash .scripts/check-service.sh 'dbrepo-data-db-sidecar'" - "IGNORE_IMAGE=1 IGNORE_PORTS=1 bash .scripts/check-service.sh 'dbrepo-data-service'" - "IGNORE_VOLUMES=1 bash .scripts/check-service.sh 'dbrepo-gateway-service'" - "IGNORE_VOLUMES=1 bash .scripts/check-service.sh 'dbrepo-identity-service'" diff --git a/README.md b/README.md index 06f03b6010..f01d3f7d78 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ - +       +  <img src="./dbrepo-ui/public/logo.png" width="200" alt="DBRepo — Repository for Data in Databases" /> diff --git a/dbrepo-analyse-service/Dockerfile b/dbrepo-analyse-service/Dockerfile index 97b181c76e..c71b3ed4ef 100644 --- a/dbrepo-analyse-service/Dockerfile +++ b/dbrepo-analyse-service/Dockerfile @@ -1,9 +1,11 @@ FROM python:3.11-alpine LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" -RUN apk add bash curl - -WORKDIR /home/alpine +RUN apk --no-cache \ + add \ + bash \ + curl \ + openjdk8-jre COPY Pipfile Pipfile.lock ./ @@ -13,14 +15,16 @@ RUN pip install pipenv && \ pipenv install gunicorn && \ pipenv install --system --deploy -USER 1001 +RUN adduser -D analyse-service --uid 1000 WORKDIR /app -COPY --chown=1001 ./api ./api -COPY --chown=1001 ./as-yml ./as-yml -COPY --chown=1001 ./clients ./clients -COPY --chown=1001 ./*.py ./ +USER 1000 + +COPY --chown=1000 ./api ./api +COPY --chown=1000 ./as-yml ./as-yml +COPY --chown=1000 ./clients ./clients +COPY --chown=1000 ./*.py ./ # non-root port EXPOSE 8080 diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock index bcff34a23e..5b3e18df9a 100644 --- a/dbrepo-analyse-service/Pipfile.lock +++ b/dbrepo-analyse-service/Pipfile.lock @@ -190,20 +190,20 @@ }, "boto3": { "hashes": [ - "sha256:5970b62c1ec8177501e02520f0d41839ca5fc549b30bac4e8c0c0882ae776217", - "sha256:670f811c65e3c5fe4ed8c8d69be0b44b1d649e992c0fc16de43816d1188f88f1" + "sha256:2d5e160b614db55fbee7981001c54476cb827c441cef65b2fcb2c52a62019909", + "sha256:7d9c359bbbc858a60b51c86328db813353c8bd1940212cdbd0a7da835291c2e1" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.39" + "version": "==1.35.54" }, "botocore": { "hashes": [ - "sha256:781c547eb6a79c0e4b0bedd87b81fbfed957816b4841d33e20c8f1989c7c19ce", - "sha256:cb7f851933b5ccc2fba4f0a8b846252410aa0efac5bfbe93b82d10801f5f8e90" + "sha256:131bb59ce59c8a939b31e8e647242d70cf11d32d4529fa4dca01feea1e891a76", + "sha256:9cca1811094b6cdc144c2c063a3ec2db6d7c88194b04d4277cd34fc8e3473aff" ], "markers": "python_version >= '3.8'", - "version": "==1.35.39" + "version": "==1.35.54" }, "certifi": { "hashes": [ @@ -407,42 +407,41 @@ }, "cryptography": { "hashes": [ - "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", - "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", - "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", - "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", - "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2", - "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", - "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", - "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", - "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", - "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", - "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d", - "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", - "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2", - "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", - "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", - "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", - "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", - "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", - "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", - "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", - "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", - "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", - "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", - "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", - "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", - "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", - "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289" + "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", + "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa", + "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83", + "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff", + "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", + "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664", + "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08", + "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", + "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", + "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", + "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", + "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", + "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", + "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3", + "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", + "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", + "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c", + "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", + "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7", + "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", + "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7" ], "markers": "python_version >= '3.7'", - "version": "==43.0.1" + "version": "==43.0.3" }, "dbrepo": { "hashes": [ - "sha256:84607677b0826bb9b2fa120aacdf56d16c8d9ae423f435b2bd2c22b1c965a33c" + "sha256:36316d520c23dcbd249b779ad596a979fe574321882a7d4b6c6934c62a5de57b" ], - "markers": "python_version >= '3.11'", "path": "./lib/dbrepo-1.4.7.tar.gz" }, "events": { @@ -503,131 +502,146 @@ }, "frozenlist": { "hashes": [ - "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", - "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", - "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", - "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", - "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", - "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", - "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", - "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", - "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", - "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", - "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", - "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", - "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", - "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", - "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", - "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", - "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", - "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", - "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", - "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", - "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", - "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", - "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", - "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", - "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", - "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", - "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", - "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", - "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", - "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", - "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", - "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", - "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", - "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", - "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", - "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", - "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", - "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", - "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", - "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", - "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", - "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", - "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", - "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", - "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", - "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", - "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", - "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", - "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", - "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", - "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", - "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", - "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", - "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", - "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", - "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", - "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", - "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", - "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", - "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", - "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", - "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", - "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", - "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", - "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", - "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", - "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", - "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", - "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", - "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", - "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", - "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", - "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", - "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", - "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", - "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", - "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" + "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", + "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", + "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6", + "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", + "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", + "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f", + "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", + "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", + "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", + "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", + "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", + "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2", + "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c", + "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336", + "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", + "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", + "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b", + "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c", + "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10", + "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08", + "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", + "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", + "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f", + "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10", + "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", + "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", + "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", + "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", + "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d", + "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923", + "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", + "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", + "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", + "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0", + "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", + "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", + "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", + "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", + "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0", + "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", + "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", + "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", + "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3", + "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", + "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", + "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604", + "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", + "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", + "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", + "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", + "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", + "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", + "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", + "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", + "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3", + "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", + "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", + "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", + "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf", + "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", + "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", + "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171", + "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", + "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", + "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", + "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972", + "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", + "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", + "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9", + "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411", + "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723", + "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", + "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b", + "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99", + "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e", + "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", + "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", + "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", + "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", + "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", + "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca", + "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", + "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", + "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", + "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", + "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307", + "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e", + "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", + "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", + "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", + "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", + "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a" ], "markers": "python_version >= '3.8'", - "version": "==1.4.1" + "version": "==1.5.0" }, "gevent": { "hashes": [ - "sha256:013150cc0f00f0a06dd898463ad9ebc43bd9c70c7fe35555c77d83fe6f758225", - "sha256:0814a5a7084e0bd357392e44e2a8bd72fc56fbdc3da0ff492ebb310c10fc95e6", - "sha256:103097b39764a0a02f1a051225ea6b4c64a53dd37603424ca8a1e09be63a460b", - "sha256:16bf432b274795b360d88b38cbffe0a6410450c94bfa172548bf1f512cf448c2", - "sha256:1a5012b7d047b16470063f0b8d003530e77362809f38cd7e601efb625c7ca71e", - "sha256:22bc6efb0f9fbb1c2e005ef1b94374568945c711bfb92f85916f66a819a5e6d0", - "sha256:377c02d0ddae3ebf843d6f453943602102bb186b09f1c78a2247e5dbf0e07b1c", - "sha256:421cfeacae2555b11318c6ee11f34bc0a9517657068d8911c916d55a85362ce2", - "sha256:44174aa4dae4db158e6f11a4ea696f1991d43ccc1634aa0c189daf03a9ced5d7", - "sha256:44dd79cfefea24f9bb630844a25047c3807e02722436e826ef2aed3d646190c1", - "sha256:4e3fbaf484ee68437f0ec589bdb1dd6f1dccc01fd6b72eac707e858b407521fa", - "sha256:4f0e6c49aac1c182be15a43d94e3b58c253d830c5b54dc93d6130e6987278611", - "sha256:539af6b66c6b9faca2cdd903f0a7564c85053f1faf95e9a37702df578ac37085", - "sha256:562b66d8b061b9cfae1bc704b0cd5d2b255628d86c3639ddc16e4ffa3ebf6e7a", - "sha256:5bb80c88f572a11156f258333c0e7b1f80d0746a03784600017901a2f1aa584a", - "sha256:5d1db7bc758455e6f6406d66e8b276b80dda5645877392a100d1ed7dda6aa7ad", - "sha256:618c4869e8140fd955b4620b10bc5a92ef1d62ae20aef38c1af7d892ee1bd996", - "sha256:6a93f249a40bda8c42cbeefff9582b22bb1dd769da56b4cbb824038366c4202c", - "sha256:6b9da562d7d7707d5561ecf4a27a361fd9f4856f39b8491a0753c89d8f39674c", - "sha256:73b65ee9a73a35fb68d96899895162beef19d86c1bcbe6f8f92eb0bd18c1d891", - "sha256:7b5f10ac866d3432a829a3a4446489be1fa3648f3140f9373fe99440a2e05682", - "sha256:81b4915081d148a31b64ad0314d2f609920b8ae6a24d9a7e4ddaab7c1fe998e7", - "sha256:90f9bc542f76efc56e5e76b420abaff42baf585db48a9fc0ac8edd6a16d9e60f", - "sha256:96e7bab9de56e0aca3858b8bc9c71f4eb0c0e12b7cf3cbfd170b62ce68cf71d7", - "sha256:975699ac5701d7ec1c633f2067deecea8711dc2a8683530aed260dd641274791", - "sha256:9f74faefea1acb398f057ed31ee9333e100bdae978b1e4c3b6a27d05df66e588", - "sha256:a11db551555c58606ed3dfe359a9a502e44350ed3ecbd59cbe7b0093bd020418", - "sha256:a6a04df4732bb7fdf9969ddee9a16a829e7971692fefdcb5baca760976d23e04", - "sha256:a72a7cb67764adafbac7ddeeffe539a738309068e2b2ac89cbd2f498383ce537", - "sha256:aabffb8b86fb95cb1ee5dffa315c9bd68fe20a7fe7260c0328679723b0257b7c", - "sha256:bc181db59d53e407650ebf44e63ff429c7bc25f9c346edddce1bdff1af436617", - "sha256:dd9c966e5fd8d7b0a54a130c5ad38ef581fd93ff4c44b6e73767519860da6ebe", - "sha256:ec800c25f09a7e031f2fbc3b17b4a4a0b54085c7532ac51b4c7ecef6d3ff8fc3", - "sha256:f0d6cfff74be4efcafecd374e094a8fed9e0d68efe90109d374ef5d8f18aa21a", - "sha256:f57b7a02e83d6e4a205cace6dd63e16b61a641a1da9366d9ec4f2b849430700f", - "sha256:fa190663f964583c8dbbab06bc863966e6f7eceaac8aa67c3ac0fae0a0a73b80", - "sha256:fa4cba4a8acbb71dd4215be8517879e4217c0746f7af2637330e7269694f53f2", - "sha256:fd9b670da1b7160e660cbba7f52e206892b97f61d8ff1872ce99dfaa9b475420" + "sha256:051b22e2758accfddb0457728bfc9abf8c3f2ce6bca43f1ff6e07b5ed9e49bf4", + "sha256:0de6eb3d55c03138fda567d9bfed28487ce5d0928c5107549767a93efdf2be26", + "sha256:18e6984ec96fc95fd67488555c38ece3015be1f38b1bcceb27b7d6c36b343008", + "sha256:1c3a828b033fb02b7c31da4d75014a1f82e6c072fc0523456569a57f8b025861", + "sha256:1ce6dab94c0b0d24425ba55712de2f8c9cb21267150ca63f5bb3a0e1f165da99", + "sha256:1e24ffea72e27987979c009536fd0868e52239b44afe6cf7135ce8aafd0f108e", + "sha256:26ca7a6b42d35129617025ac801135118333cad75856ffc3217b38e707383eba", + "sha256:34aea15f9c79f27a8faeaa361bc1e72c773a9b54a1996a2ec4eefc8bcd59a824", + "sha256:385710355eadecdb70428a5ae3e7e5a45dcf888baa1426884588be9d25ac4290", + "sha256:3ac83b74304487afa211a01909c7dd257e574db0cd429d866c298e21df7aeedf", + "sha256:3ad8fb70aa0ebc935729c9699ac31b210a49b689a7b27b7ac9f91676475f3f53", + "sha256:40ea3e40e8bb4fdb143c2a8edf2ccfdebd56016c7317c341ce8094c7bee08818", + "sha256:57a5c4e0bdac482c5f02f240d0354e61362df73501ef6ebafce8ef635cad7527", + "sha256:5d850a453d66336272be4f1d3a8126777f3efdaea62d053b4829857f91e09755", + "sha256:68c3a0d8402755eba7f69022e42e8021192a721ca8341908acc222ea597029b6", + "sha256:7021e26d70189b33c27173d4173f27bf4685d6b6f1c0ea50e5335f8491cb110c", + "sha256:70e9ed7ecb70e0df7dc97c3bc420de9a45a7c76bd5861c6cfec8c549700e681e", + "sha256:89c4115e3f5ada55f92b61701a46043fe42f702b5af863b029e4c1a76f6cc2d4", + "sha256:8af65a4d4feaec6042c666d22c322a310fba3b47e841ad52f724b9c3ce5da48e", + "sha256:8e58ee3723f1fbe07d66892f1caa7481c306f653a6829b6fd16cb23d618a5915", + "sha256:9ca2266e08f43c0e22c028801dff7d92a0b102ef20e4caeb6a46abfb95f6a328", + "sha256:9e1210334a9bc9f76c3d008e0785ca62214f8a54e1325f6c2ecab3b6a572a015", + "sha256:a9a89d6e396ef6f1e3968521bf56e8c4bee25b193bbf5d428b7782d582410822", + "sha256:aa7ee1bd5cabb2b7ef35105f863b386c8d5e332f754b60cfc354148bd70d35d1", + "sha256:b52382124eca13135a3abe4f65c6bd428656975980a48e51b17aeab68bdb14db", + "sha256:c1d80090485da1ea3d99205fe97908b31188c1f4857f08b333ffaf2de2e89d18", + "sha256:ce417bcaaab496bc9c77f75566531e9d93816262037b8b2dbb88b0fdcd66587c", + "sha256:d67daed8383326dc8b5e58d88e148d29b6b52274a489e383530b0969ae7b9cb9", + "sha256:d758f0d4dbf32502ec87bb9b536ca8055090a16f8305f0ada3ce6f34e70f2fd7", + "sha256:d7a1ad0f2da582f5bd238bca067e1c6c482c30c15a6e4d14aaa3215cbb2232f3", + "sha256:e534e6a968d74463b11de6c9c67f4b4bf61775fb00f2e6e0f7fcdd412ceade18", + "sha256:eb5edb6433764119a664bbb148d2aea9990950aa89cc3498f475c2408d523ea3", + "sha256:f0c129f81d60cda614acb4b0c5731997ca05b031fb406fcb58ad53a7ade53b13", + "sha256:f147e38423fbe96e8731f60a63475b3d2cab2f3d10578d8ee9d10c507c58a2ff", + "sha256:f18689f7a70d2ed0e75bad5036ec3c89690a493d4cfac8d7cdb258ac04b132bd", + "sha256:f2ae3efbbd120cdf4a68b7abc27a37e61e6f443c5a06ec2c6ad94c37cd8471ec", + "sha256:f4e526fdc279c655c1e809b0c34b45844182c2a6b219802da5e411bd2cf5a8ad", + "sha256:f7f4f171d4d2018170454d84c934842e1b5f6ce7468ba298f6e7f7cff15000a3" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==24.10.2" + "version": "==24.10.3" }, "greenlet": { "hashes": [ @@ -776,79 +790,79 @@ }, "markupsafe": { "hashes": [ - "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", - "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", - "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", - "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", - "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", - "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", - "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", - "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", - "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", - "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", - "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", - "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", - "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", - "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", - "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", - "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", - "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", - "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", - "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", - "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", - "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", - "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", - "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", - "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", - "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", - "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", - "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", - "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", - "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", - "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", - "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", - "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", - "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", - "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", - "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", - "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", - "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", - "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", - "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", - "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", - "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", - "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", - "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", - "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", - "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", - "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", - "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", - "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", - "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", - "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", - "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", - "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", - "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", - "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", - "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", - "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", - "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", - "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", - "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", - "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", - "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" ], "markers": "python_version >= '3.9'", - "version": "==3.0.1" + "version": "==3.0.2" }, "minio": { "hashes": [ - "sha256:a83c2fcd981944602a8dc11e8e07543ed9cda0a9462264e3f46a13171c56bccb", - "sha256:fe5523d9c4a4d6cfc07e96905852841bccdb22b22770e1efca4bf5ae8b65774b" + "sha256:418c31ac79346a580df04a0e14db1becbc548a6e7cca61f9bc4ef3bcd336c449", + "sha256:5961c58192b1d70d3a2a362064b8e027b8232688998a6d1251dadbb02ab57a7d" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.2.9" + "version": "==7.2.10" }, "mistune": { "hashes": [ @@ -958,63 +972,65 @@ }, "numpy": { "hashes": [ - "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", - "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", - "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", - "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", - "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", - "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", - "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", - "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", - "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", - "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", - "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", - "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", - "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", - "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", - "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", - "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", - "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", - "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", - "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", - "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", - "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", - "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", - "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", - "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", - "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", - "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", - "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", - "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", - "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", - "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", - "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", - "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", - "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", - "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", - "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", - "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", - "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", - "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", - "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", - "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", - "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", - "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", - "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", - "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", - "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", - "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", - "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", - "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", - "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", - "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", - "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", - "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", - "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe", + "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", + "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48", + "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", + "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", + "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", + "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17", + "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", + "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", + "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", + "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4", + "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", + "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6", + "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4", + "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", + "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", + "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f", + "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f", + "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56", + "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", + "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", + "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", + "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed", + "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", + "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", + "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", + "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", + "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f", + "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", + "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f", + "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", + "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", + "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0", + "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", + "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef", + "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", + "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e", + "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", + "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", + "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43", + "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", + "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", + "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", + "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408", + "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", + "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", + "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57", + "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", + "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", + "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", + "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a", + "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", + "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", + "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598", + "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==2.1.2" + "version": "==2.1.3" }, "opensearch-py": { "hashes": [ @@ -1373,7 +1389,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "pytz": { @@ -1461,112 +1477,112 @@ }, "rpds-py": { "hashes": [ - "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", - "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", - "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", - "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", - "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", - "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", - "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", - "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", - "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", - "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", - "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", - "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", - "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", - "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", - "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", - "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", - "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", - "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", - "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", - "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", - "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", - "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", - "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", - "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", - "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", - "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", - "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", - "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", - "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", - "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", - "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", - "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", - "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", - "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", - "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", - "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", - "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", - "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", - "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", - "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", - "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", - "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", - "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", - "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", - "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", - "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", - "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", - "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", - "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", - "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", - "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", - "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", - "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", - "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", - "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", - "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", - "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", - "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", - "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", - "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", - "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", - "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", - "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", - "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", - "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", - "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", - "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", - "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", - "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", - "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", - "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", - "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", - "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", - "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", - "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", - "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", - "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", - "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", - "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", - "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", - "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", - "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", - "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", - "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", - "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", - "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", - "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", - "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", - "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", - "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", - "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", - "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", - "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", - "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", - "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", - "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", - "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", - "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", - "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", - "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", - "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", - "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", - "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + "sha256:02a0629ec053fc013808a85178524e3cb63a61dbc35b22499870194a63578fb9", + "sha256:07924c1b938798797d60c6308fa8ad3b3f0201802f82e4a2c41bb3fafb44cc28", + "sha256:07f59760ef99f31422c49038964b31c4dfcfeb5d2384ebfc71058a7c9adae2d2", + "sha256:0a3a1e9ee9728b2c1734f65d6a1d376c6f2f6fdcc13bb007a08cc4b1ff576dc5", + "sha256:0a90c373ea2975519b58dece25853dbcb9779b05cc46b4819cb1917e3b3215b6", + "sha256:0ad56edabcdb428c2e33bbf24f255fe2b43253b7d13a2cdbf05de955217313e6", + "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712", + "sha256:0f8f741b6292c86059ed175d80eefa80997125b7c478fb8769fd9ac8943a16c0", + "sha256:0fc212779bf8411667234b3cdd34d53de6c2b8b8b958e1e12cb473a5f367c338", + "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86", + "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c", + "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c", + "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f", + "sha256:16d4477bcb9fbbd7b5b0e4a5d9b493e42026c0bf1f06f723a9353f5153e75d30", + "sha256:1791ff70bc975b098fe6ecf04356a10e9e2bd7dc21fa7351c1742fdeb9b4966f", + "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd", + "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e", + "sha256:2249280b870e6a42c0d972339e9cc22ee98730a99cd7f2f727549af80dd5a963", + "sha256:2b431c777c9653e569986ecf69ff4a5dba281cded16043d348bf9ba505486f36", + "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2", + "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e", + "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d", + "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17", + "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb", + "sha256:3aea7eed3e55119635a74bbeb80b35e776bafccb70d97e8ff838816c124539f1", + "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5", + "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163", + "sha256:3d089d0b88996df627693639d123c8158cff41c0651f646cd8fd292c7da90eaf", + "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356", + "sha256:3e310838a5801795207c66c73ea903deda321e6146d6f282e85fa7e3e4854804", + "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93", + "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a", + "sha256:4888e117dd41b9d34194d9e31631af70d3d526efc363085e3089ab1a62c32ed1", + "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496", + "sha256:4a5a844f68776a7715ecb30843b453f07ac89bad393431efbf7accca3ef599c1", + "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0", + "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899", + "sha256:518d2ca43c358929bf08f9079b617f1c2ca6e8848f83c1225c88caeac46e6cbc", + "sha256:5265505b3d61a0f56618c9b941dc54dc334dc6e660f1592d112cd103d914a6db", + "sha256:55cd1fa4ecfa6d9f14fbd97ac24803e6f73e897c738f771a9fe038f2f11ff07c", + "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8", + "sha256:59240685e7da61fb78f65a9f07f8108e36a83317c53f7b276b4175dc44151684", + "sha256:5b48e790e0355865197ad0aca8cde3d8ede347831e1959e158369eb3493d2191", + "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06", + "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff", + "sha256:653647b8838cf83b2e7e6a0364f49af96deec64d2a6578324db58380cff82aca", + "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8", + "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc", + "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a", + "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7", + "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4", + "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751", + "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e", + "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b", + "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75", + "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e", + "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74", + "sha256:7dca7081e9a0c3b6490a145593f6fe3173a94197f2cb9891183ef75e9d64c425", + "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84", + "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d", + "sha256:83cba698cfb3c2c5a7c3c6bac12fe6c6a51aae69513726be6411076185a8b24a", + "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a", + "sha256:84b8382a90539910b53a6307f7c35697bc7e6ffb25d9c1d4e998a13e842a5e83", + "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535", + "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb", + "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd", + "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979", + "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d", + "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d", + "sha256:9c4cb04a16b0f199a8c9bf807269b2f63b7b5b11425e4a6bd44bd6961d28282c", + "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782", + "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad", + "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75", + "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4", + "sha256:b41b6321805c472f66990c2849e152aff7bc359eb92f781e3f606609eac877ad", + "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e", + "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c", + "sha256:bb63804105143c7e24cee7db89e37cb3f3941f8e80c4379a0b355c52a52b6780", + "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01", + "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf", + "sha256:c14937af98c4cc362a1d4374806204dd51b1e12dded1ae30645c298e5a5c4cb1", + "sha256:ca449520e7484534a2a44faf629362cae62b660601432d04c482283c47eaebab", + "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732", + "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa", + "sha256:d126b52e4a473d40232ec2052a8b232270ed1f8c9571aaf33f73a14cc298c24f", + "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3", + "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711", + "sha256:da584ff96ec95e97925174eb8237e32f626e7a1a97888cdd27ee2f1f24dd0ad8", + "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a", + "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d", + "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c", + "sha256:e13de156137b7095442b288e72f33503a469aa1980ed856b43c353ac86390519", + "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350", + "sha256:e75ba609dba23f2c95b776efb9dd3f0b78a76a151e96f96cc5b6b1b0004de66f", + "sha256:e79059d67bea28b53d255c1437b25391653263f0e69cd7dec170d778fdbca95e", + "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb", + "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc", + "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f", + "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977", + "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311", + "sha256:fa41a64ac5b08b292906e248549ab48b69c5428f3987b09689ab2441f267d04d", + "sha256:fbf15aff64a163db29a91ed0868af181d6f68ec1a3a7d5afcfe4501252840bad", + "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982" ], "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "version": "==0.20.1" }, "s3transfer": { "hashes": [ @@ -1578,18 +1594,18 @@ }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", + "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686" ], "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "version": "==75.3.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "tinydb": { @@ -1634,115 +1650,99 @@ }, "werkzeug": { "hashes": [ - "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c", - "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306" + "sha256:8cd39dfbdfc1e051965f156163e2974e52c210f130810e9ad36858f0fd3edad4", + "sha256:a71124d1ef06008baafa3d266c02f56e1836a5984afd6dd6c9230669d60d9fb5" ], - "markers": "python_version >= '3.8'", - "version": "==3.0.4" + "markers": "python_version >= '3.9'", + "version": "==3.1.1" }, "yarl": { "hashes": [ - "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e", - "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c", - "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747", - "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179", - "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a", - "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936", - "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19", - "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8", - "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed", - "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2", - "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33", - "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057", - "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548", - "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c", - "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b", - "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f", - "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9", - "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f", - "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a", - "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04", - "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50", - "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2", - "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46", - "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01", - "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5", - "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf", - "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935", - "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84", - "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d", - "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5", - "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c", - "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7", - "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9", - "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367", - "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad", - "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d", - "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d", - "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea", - "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7", - "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf", - "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b", - "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036", - "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc", - "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec", - "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b", - "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627", - "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368", - "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810", - "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94", - "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50", - "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6", - "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb", - "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b", - "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7", - "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931", - "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178", - "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d", - "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f", - "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2", - "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5", - "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc", - "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84", - "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b", - "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172", - "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644", - "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f", - "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776", - "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd", - "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04", - "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956", - "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4", - "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7", - "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8", - "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb", - "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053", - "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe", - "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a", - "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b", - "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb", - "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417", - "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c", - "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980", - "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47", - "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b", - "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904", - "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8", - "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0", - "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611", - "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2", - "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d", - "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715", - "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897", - "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046", - "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b", - "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e", - "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16", - "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d", - "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75" + "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", + "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", + "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", + "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", + "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", + "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", + "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", + "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", + "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5", + "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", + "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", + "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", + "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", + "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", + "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", + "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", + "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", + "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", + "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", + "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", + "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", + "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", + "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", + "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", + "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", + "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857", + "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", + "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", + "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", + "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", + "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", + "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", + "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934", + "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473", + "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", + "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", + "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", + "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", + "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71", + "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", + "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", + "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", + "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", + "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6", + "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", + "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", + "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", + "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", + "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", + "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", + "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f", + "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", + "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", + "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", + "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95", + "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383", + "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e", + "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", + "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", + "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55", + "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", + "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", + "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", + "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", + "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", + "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", + "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", + "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", + "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", + "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c", + "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29", + "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", + "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", + "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", + "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", + "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138", + "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", + "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004", + "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159", + "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", + "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", + "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75" ], - "markers": "python_version >= '3.8'", - "version": "==1.15.2" + "markers": "python_version >= '3.9'", + "version": "==1.17.1" }, "zope.event": { "hashes": [ @@ -1754,46 +1754,46 @@ }, "zope.interface": { "hashes": [ - "sha256:07add15de0cc7e69917f7d286b64d54125c950aeb43efed7a5ea7172f000fbc1", - "sha256:0ac20581fc6cd7c754f6dff0ae06fedb060fa0e9ea6309d8be8b2701d9ea51c4", - "sha256:124149e2d42067b9c6597f4dafdc7a0983d0163868f897b7bb5dc850b14f9a87", - "sha256:27cfb5205d68b12682b6e55ab8424662d96e8ead19550aad0796b08dd2c9a45e", - "sha256:2a29ac607e970b5576547f0e3589ec156e04de17af42839eedcf478450687317", - "sha256:2b6a4924f5bad9fe21d99f66a07da60d75696a136162427951ec3cb223a5570d", - "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a", - "sha256:3bcff5c09d0215f42ba64b49205a278e44413d9bf9fa688fd9e42bfe472b5f4f", - "sha256:3f005869a1a05e368965adb2075f97f8ee9a26c61898a9e52a9764d93774f237", - "sha256:4a00ead2e24c76436e1b457a5132d87f83858330f6c923640b7ef82d668525d1", - "sha256:4af4a12b459a273b0b34679a5c3dc5e34c1847c3dd14a628aa0668e19e638ea2", - "sha256:5501e772aff595e3c54266bc1bfc5858e8f38974ce413a8f1044aae0f32a83a3", - "sha256:5e28ea0bc4b084fc93a483877653a033062435317082cdc6388dec3438309faf", - "sha256:5e956b1fd7f3448dd5e00f273072e73e50dfafcb35e4227e6d5af208075593c9", - "sha256:5fcf379b875c610b5a41bc8a891841533f98de0520287d7f85e25386cd10d3e9", - "sha256:6159e767d224d8f18deff634a1d3722e68d27488c357f62ebeb5f3e2f5288b1f", - "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef", - "sha256:711eebc77f2092c6a8b304bad0b81a6ce3cf5490b25574e7309fbc07d881e3af", - "sha256:80a3c00b35f6170be5454b45abe2719ea65919a2f09e8a6e7b1362312a872cd3", - "sha256:848b6fa92d7c8143646e64124ed46818a0049a24ecc517958c520081fd147685", - "sha256:91b6c30689cfd87c8f264acb2fc16ad6b3c72caba2aec1bf189314cf1a84ca33", - "sha256:9733a9a0f94ef53d7aa64661811b20875b5bc6039034c6e42fb9732170130573", - "sha256:9940d5bc441f887c5f375ec62bcf7e7e495a2d5b1da97de1184a88fb567f06af", - "sha256:9e3e48f3dea21c147e1b10c132016cb79af1159facca9736d231694ef5a740a8", - "sha256:a14c9decf0eb61e0892631271d500c1e306c7b6901c998c7035e194d9150fdd1", - "sha256:a735f82d2e3ed47ca01a20dfc4c779b966b16352650a8036ab3955aad151ed8a", - "sha256:a99240b1d02dc469f6afbe7da1bf617645e60290c272968f4e53feec18d7dce8", - "sha256:b7b25db127db3e6b597c5f74af60309c4ad65acd826f89609662f0dc33a54728", - "sha256:b936d61dbe29572fd2cfe13e30b925e5383bed1aba867692670f5a2a2eb7b4e9", - "sha256:bec001798ab62c3fc5447162bf48496ae9fba02edc295a9e10a0b0c639a6452e", - "sha256:cc8a318162123eddbdf22fcc7b751288ce52e4ad096d3766ff1799244352449d", - "sha256:d0a45b5af9f72c805ee668d1479480ca85169312211bed6ed18c343e39307d5f", - "sha256:e53c291debef523b09e1fe3dffe5f35dde164f1c603d77f770b88a1da34b7ed6", - "sha256:ec1ef1fdb6f014d5886b97e52b16d0f852364f447d2ab0f0c6027765777b6667", - "sha256:ec59fe53db7d32abb96c6d4efeed84aab4a7c38c62d7a901a9b20c09dd936e7a", - "sha256:f245d039f72e6f802902375755846f5de1ee1e14c3e8736c078565599bcab621", - "sha256:ff115ef91c0eeac69cd92daeba36a9d8e14daee445b504eeea2b1c0b55821984" + "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f", + "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e", + "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616", + "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3", + "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67", + "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8", + "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b", + "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585", + "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446", + "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd", + "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a", + "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3", + "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c", + "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853", + "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f", + "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5", + "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8", + "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501", + "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd", + "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029", + "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e", + "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f", + "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580", + "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c", + "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9", + "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0", + "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2", + "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d", + "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73", + "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16", + "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a", + "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267", + "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b", + "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d", + "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053", + "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25", + "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770" ], "markers": "python_version >= '3.8'", - "version": "==7.1.0" + "version": "==7.1.1" } }, "develop": { @@ -2026,72 +2026,72 @@ }, "coverage": { "hashes": [ - "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6", - "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2", - "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba", - "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb", - "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6", - "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4", - "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0", - "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6", - "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990", - "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3", - "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43", - "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175", - "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a", - "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6", - "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97", - "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b", - "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e", - "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39", - "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd", - "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d", - "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f", - "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc", - "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976", - "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549", - "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c", - "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5", - "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4", - "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b", - "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e", - "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3", - "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6", - "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e", - "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929", - "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234", - "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13", - "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007", - "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3", - "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167", - "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d", - "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d", - "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40", - "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181", - "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054", - "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd", - "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2", - "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91", - "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3", - "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b", - "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38", - "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd", - "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f", - "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2", - "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba", - "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f", - "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83", - "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce", - "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38", - "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c", - "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f", - "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21", - "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4", - "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92" + "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", + "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", + "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", + "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", + "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", + "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", + "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", + "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", + "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", + "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", + "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", + "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", + "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", + "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", + "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", + "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", + "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", + "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", + "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", + "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", + "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", + "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", + "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", + "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", + "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", + "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", + "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", + "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", + "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", + "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", + "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", + "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", + "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", + "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", + "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", + "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", + "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", + "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", + "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", + "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", + "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", + "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", + "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", + "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", + "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", + "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", + "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", + "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", + "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", + "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", + "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", + "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", + "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", + "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", + "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", + "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", + "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", + "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", + "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", + "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", + "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", + "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.6.3" + "version": "==7.6.4" }, "docker": { "hashes": [ @@ -2125,12 +2125,12 @@ }, "minio": { "hashes": [ - "sha256:a83c2fcd981944602a8dc11e8e07543ed9cda0a9462264e3f46a13171c56bccb", - "sha256:fe5523d9c4a4d6cfc07e96905852841bccdb22b22770e1efca4bf5ae8b65774b" + "sha256:418c31ac79346a580df04a0e14db1becbc548a6e7cca61f9bc4ef3bcd336c449", + "sha256:5961c58192b1d70d3a2a362064b8e027b8232688998a6d1251dadbb02ab57a7d" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.2.9" + "version": "==7.2.10" }, "opensearch-py": { "hashes": [ @@ -2217,7 +2217,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "requests": { @@ -2243,7 +2243,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "testcontainers-core": { diff --git a/dbrepo-analyse-service/api/dto.py b/dbrepo-analyse-service/api/dto.py index c3c6a22c04..319b06efa2 100644 --- a/dbrepo-analyse-service/api/dto.py +++ b/dbrepo-analyse-service/api/dto.py @@ -27,6 +27,7 @@ class DataTypeDto(str, Enum): MEDIUMINT = "mediumint" MEDIUMTEXT = "mediumtext" SET = "set" + SERIAL = "serial" SMALLINT = "smallint" TEXT = "text" TIMESTAMP = "timestamp" diff --git a/dbrepo-analyse-service/app.py b/dbrepo-analyse-service/app.py index aa9a42096c..99f1de1a16 100644 --- a/dbrepo-analyse-service/app.py +++ b/dbrepo-analyse-service/app.py @@ -218,14 +218,19 @@ swagger = Swagger(app, config=swagger_config, template=template) app.config["JWT_ALGORITHM"] = "HS256" app.config["JWT_PUBKEY"] = '-----BEGIN PUBLIC KEY-----\n' + os.getenv("JWT_PUBKEY", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB") + '\n-----END PUBLIC KEY-----' +app.config["ANALYSE_NROWS"] = int(os.getenv('ANALYSE_NROWS', '10000')) app.config["AUTH_SERVICE_ENDPOINT"] = os.getenv("AUTH_SERVICE_ENDPOINT", "http://localhost/api/auth") app.config["AUTH_SERVICE_CLIENT"] = os.getenv("AUTH_SERVICE_CLIENT", "dbrepo-client") app.config["AUTH_SERVICE_CLIENT_SECRET"] = os.getenv("AUTH_SERVICE_CLIENT_SECRET", "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG") app.config["S3_ACCESS_KEY_ID"] = os.getenv('S3_ACCESS_KEY_ID', 'seaweedfsadmin') app.config["S3_BUCKET"] = os.getenv('S3_BUCKET', 'dbrepo') -app.config["S3_ENDPOINT"] = os.getenv('S3_ENDPOINT', 'http://localhost:9000') +app.config["S3_ENDPOINT"] = os.getenv('S3_ENDPOINT', 'localhost:9000') +app.config["S3_PROTO"] = os.getenv('S3_PROTO', 'http') app.config["S3_SECRET_ACCESS_KEY"] = os.getenv('S3_SECRET_ACCESS_KEY', 'seaweedfsadmin') -app.config["ANALYSE_NROWS"] = int(os.getenv('ANALYSE_NROWS', '10000')) +app.config["SPARK_ENDPOINT"] = os.getenv('SPARK_ENDPOINT', 'local[2]') +app.config["METADATA_SERVICE_ENDPOINT"] = os.getenv('METADATA_SERVICE_ENDPOINT', 'http://localhost') +app.config["SYSTEM_USERNAME"] = os.getenv('SYSTEM_USERNAME', 'admin') +app.config["SYSTEM_PASSWORD"] = os.getenv('SYSTEM_PASSWORD', 'admin') app.json_encoder = LazyJSONEncoder diff --git a/dbrepo-analyse-service/as-yml/import_dataset.yml b/dbrepo-analyse-service/as-yml/import_dataset.yml new file mode 100644 index 0000000000..78f84f9e27 --- /dev/null +++ b/dbrepo-analyse-service/as-yml/import_dataset.yml @@ -0,0 +1,62 @@ +tags: + - analyse-endpoint +summary: "Determine datatypes" +operationId: analyse_datatypes +description: "Determines MySQL 8 datatypes of a given dataset. Requires role `table-semantic-analyse`." +consumes: + - "application/json" +produces: + - "application/json" +parameters: + - name: filename + in: query + required: true + example: filename_s3_key + schema: + type: string + - name: separator + in: query + required: true + example: "," + schema: + type: string + - name: enum + in: query + required: false + example: "false" + schema: + type: boolean + - name: enum_tol + in: query + required: false + example: "2.5" + schema: + type: float +responses: + 202: + description: Determined data types successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AnalysisDto' + 400: + description: "Failed to determine data types" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + 404: + description: "Failed to find file in Storage Service" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + 500: + description: "Unexpected system error" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' +security: + - bearerAuth: [ ] + - basicAuth: [ ] diff --git a/dbrepo-analyse-service/clients/s3_client.py b/dbrepo-analyse-service/clients/s3_client.py index e9f58ea407..18cdba1ec3 100644 --- a/dbrepo-analyse-service/clients/s3_client.py +++ b/dbrepo-analyse-service/clients/s3_client.py @@ -13,9 +13,8 @@ class S3Client: endpoint_url = current_app.config['S3_ENDPOINT'] aws_access_key_id = current_app.config['S3_ACCESS_KEY_ID'] aws_secret_access_key = current_app.config['S3_SECRET_ACCESS_KEY'] - logging.info("retrieve file from S3, endpoint_url=%s, aws_access_key_id=%s, aws_secret_access_key=(hidden)", - endpoint_url, aws_access_key_id) - self.client = boto3.client(service_name='s3', endpoint_url=endpoint_url, aws_access_key_id=aws_access_key_id, + logging.info(f"retrieve file from S3, endpoint_url={current_app.config['S3_PROTO']}://{endpoint_url}, aws_access_key_id={aws_access_key_id}, aws_secret_access_key=(hidden)") + self.client = boto3.client(service_name='s3', endpoint_url=f"{current_app.config['S3_PROTO']}://{endpoint_url}", aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) self.bucket_exists_or_exit(current_app.config['S3_BUCKET']) diff --git a/dbrepo-analyse-service/determine_dt.py b/dbrepo-analyse-service/determine_dt.py index fe3e6a0279..0358929165 100644 --- a/dbrepo-analyse-service/determine_dt.py +++ b/dbrepo-analyse-service/determine_dt.py @@ -2,14 +2,13 @@ """ @author: Martin Weise """ -import json import logging import io import pandas from numpy import dtype, max, min from flask import current_app -from pandas import DataFrame +from pandas import DataFrame, NaT from pandas.errors import EmptyDataError, ParserError from api.dto import ColumnAnalysisDto, DataTypeDto, AnalysisDto @@ -67,14 +66,14 @@ def determine_datatypes(filename, enum=False, enum_tol=0.0001, separator=',') -> r = {} for name, dataType in df.dtypes.items(): + # trim leading/trailing whitespaces + column_name = name.strip() col = ColumnAnalysisDto(type=DataTypeDto.TEXT, null_allowed=contains_null(df[name])) - r[name] = col + r[column_name] = col if dataType == dtype('float64'): if pandas.to_numeric(df[name], errors='coerce').notnull().all(): logging.debug(f"mapped column {name} from float64 to decimal") col.type = DataTypeDto.DECIMAL - col.size = 40 - col.d = 10 else: logging.debug(f"mapped column {name} from float64 to text") col.type = DataTypeDto.TEXT @@ -87,12 +86,15 @@ def determine_datatypes(filename, enum=False, enum_tol=0.0001, separator=',') -> continue logging.debug(f"mapped column {name} from int64 to bigint") col.type = DataTypeDto.BIGINT - col.size = 255 elif dataType == dtype('O'): try: pandas.to_datetime(df[name], format='mixed') - logging.debug(f"mapped column {name} from O to timestamp") - col.type = DataTypeDto.TIMESTAMP + if df[name].str.contains(':').any(): + logging.debug(f"mapped column {name} from O to timestamp") + col.type = DataTypeDto.TIMESTAMP + continue + logging.debug(f"mapped column {name} from O to date") + col.type = DataTypeDto.DATE continue except ValueError: pass diff --git a/dbrepo-analyse-service/lib/dbrepo-1.4.7.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.4.7.tar.gz index c652dbae4a60aae708eb6fe4e751977b97b72344..c85b1225ee9cc1f5386e58bced9b979ff160e982 100644 GIT binary patch literal 39237 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	>r}O$?3gP# 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 Sy?E7M`$e<9sWVitG5`S0lLKx5 literal 39442 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⋘a6uI?z25G^_MT;Y$Tki)wr6C?uqjn_+S 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 XgZy<LNMo{F{Ii#Ry6FbP0#*h9Jtb_G diff --git a/dbrepo-analyse-service/test/conftest.py b/dbrepo-analyse-service/test/conftest.py index 424588bdfd..3418998a94 100644 --- a/dbrepo-analyse-service/test/conftest.py +++ b/dbrepo-analyse-service/test/conftest.py @@ -31,12 +31,7 @@ def session(request, app_context): logging.debug("[fixture] starting container") container.start() # set the environment for the client - endpoint = ( - "http://" - + container.get_container_host_ip() - + ":" - + container.get_exposed_port(9000) - ) + endpoint = f"{container.get_container_host_ip()}:{container.get_exposed_port(9000)}" logging.debug(f"[fixture] setting s3 endpoint {endpoint}") app.config["S3_ENDPOINT"] = endpoint client = container.get_client() diff --git a/dbrepo-analyse-service/test/test_determine_dt.py b/dbrepo-analyse-service/test/test_determine_dt.py index 0ac9dc4b8a..4be9e331d6 100644 --- a/dbrepo-analyse-service/test/test_determine_dt.py +++ b/dbrepo-analyse-service/test/test_determine_dt.py @@ -7,7 +7,7 @@ from determine_dt import determine_datatypes class DetermineDatatypesTest(unittest.TestCase): - # @Test + def test_determine_datatypesDateTime_succeeds(self): exp = AnalysisDto(separator=",", line_termination="\n", columns={ "Datum": { @@ -36,8 +36,6 @@ class DetermineDatatypesTest(unittest.TestCase): }, "Wert": { "type": "decimal", - "size": 40, - "d": 10, "null_allowed": False, }, "Status": { @@ -47,6 +45,7 @@ class DetermineDatatypesTest(unittest.TestCase): }, }) + # mock S3Client().upload_file("datetime.csv", './data/test_dt/', 'dbrepo') @@ -54,8 +53,6 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="datetime.csv", separator=",") self.assertEqual(exp, response) - # @Test - def test_determine_datatypesDateTimeWithTimezone_succeeds(self): exp = AnalysisDto(separator=",", line_termination="\n", columns={ "Datum": { @@ -84,8 +81,6 @@ class DetermineDatatypesTest(unittest.TestCase): }, "Wert": { "type": "decimal", - "size": 40, - "d": 10, "null_allowed": False, }, "Status": { @@ -102,8 +97,6 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="datetime_tz.csv", separator=",") self.assertEqual(exp, response) - # @Test - def test_determine_datatypesDateTimeWithT_succeeds(self): exp = AnalysisDto(separator=",", line_termination="\n", columns={ "Datum": { @@ -132,8 +125,6 @@ class DetermineDatatypesTest(unittest.TestCase): }, "Wert": { "type": "decimal", - "size": 40, - "d": 10, "null_allowed": False, }, "Status": { @@ -150,18 +141,14 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="datetime_t.csv", separator=",") self.assertEqual(exp, response) - # @Test def test_determine_datatypes_succeeds(self): exp = AnalysisDto(separator=",", line_termination="\n", columns={ "int": { "type": "bigint", - "size": 255, "null_allowed": False, }, "float": { "type": "decimal", - "size": 40, - "d": 10, "null_allowed": False, }, "string": { @@ -171,7 +158,6 @@ class DetermineDatatypesTest(unittest.TestCase): }, "boolean": { "type": "bool", - "size": None, "null_allowed": False, }, "bool": { @@ -179,7 +165,7 @@ class DetermineDatatypesTest(unittest.TestCase): "null_allowed": False, }, "date": { - "type": "timestamp", + "type": "date", "null_allowed": False, }, "time": { @@ -200,7 +186,6 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="datatypes.csv", separator=",") self.assertEqual(exp, response) - # @Test def test_determine_datatypes_fileDoesNotExist_fails(self): # test @@ -213,7 +198,6 @@ class DetermineDatatypesTest(unittest.TestCase): else: self.fail("ExpectedException not raised") - # @Test def test_determine_datatypes_fileEmpty_succeeds(self): # mock @@ -224,7 +208,6 @@ class DetermineDatatypesTest(unittest.TestCase): self.assertEqual({}, response.columns) self.assertEqual(",", response.separator) - # @Test def test_determine_datatypes_separatorSemicolon_succeeds(self): # mock @@ -234,7 +217,6 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="separator.csv", separator=";") self.assertEqual(";", response.separator) - # @Test def test_determine_datatypes_separatorGuess_succeeds(self): # mock @@ -244,7 +226,6 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="separator.csv") self.assertEqual(";", response.separator) - # @Test def test_determine_datatypes_separatorGuessLargeDataset_succeeds(self): # mock @@ -254,12 +235,10 @@ class DetermineDatatypesTest(unittest.TestCase): response = determine_datatypes(filename="large.csv") self.assertEqual(",", response.separator) - # @Test def test_determine_datatypes_separatorGuessText_succeeds(self): exp = AnalysisDto(separator=";", line_termination="\n", columns={ "id": { "type": "bigint", - "size": 255, "null_allowed": False }, "author": { diff --git a/dbrepo-data-db/.gitignore b/dbrepo-data-db/.gitignore deleted file mode 100644 index 78db1b98b3..0000000000 --- a/dbrepo-data-db/.gitignore +++ /dev/null @@ -1,127 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# SQLite db -*.db - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ diff --git a/dbrepo-data-db/README.md b/dbrepo-data-db/README.md deleted file mode 100644 index c2dfb1b0c6..0000000000 --- a/dbrepo-data-db/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Data Database - -S3 Import - -https://mariadb.com/kb/en/s3-storage-engine-system-variables/ \ No newline at end of file diff --git a/dbrepo-data-db/sidecar/Dockerfile b/dbrepo-data-db/sidecar/Dockerfile deleted file mode 100644 index 3f849019a4..0000000000 --- a/dbrepo-data-db/sidecar/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM python:3.11-alpine -LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" - -RUN apk add bash curl jq mariadb-client - -ENV PYTHONFAULTHANDLER=1 - -COPY Pipfile Pipfile.lock ./ - -RUN pip install pipenv && \ - pipenv install gunicorn && \ - pipenv install --system --deploy - -USER 1001 - -WORKDIR /app - -COPY --chown=1001 ./clients ./clients -COPY --chown=1001 ./ds-yml ./ds-yml -COPY --chown=1001 ./app.py ./app.py - -EXPOSE 8080 - -ENTRYPOINT [ "gunicorn", "--log-level", "DEBUG", "--workers", "4", "--bind", ":8080", "app:app" ] diff --git a/dbrepo-data-db/sidecar/Pipfile b/dbrepo-data-db/sidecar/Pipfile deleted file mode 100644 index 2bd2967cf6..0000000000 --- a/dbrepo-data-db/sidecar/Pipfile +++ /dev/null @@ -1,27 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -boto3 = "*" -flasgger = "*" -flask = "~=2.0" -flask-cors = "~=4.0" -flask-jwt-extended = "~=4.5" -requests = "*" -prometheus-flask-exporter = "*" -flask-sqlalchemy = "~=3.0" -python-dotenv = "~=1.0" -sqlalchemy-utils = "*" -gunicorn = "*" -flask_httpauth = "*" -jwt = "~=1.3" -dataclasses = "*" - -[dev-packages] -coverage = "*" -pytest = "*" - -[requires] -python_version = "3.11" diff --git a/dbrepo-data-db/sidecar/Pipfile.lock b/dbrepo-data-db/sidecar/Pipfile.lock deleted file mode 100644 index 12afdd0636..0000000000 --- a/dbrepo-data-db/sidecar/Pipfile.lock +++ /dev/null @@ -1,945 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "3b1a231fb0354d787188ca7fb2a4c8de795a9e0767381deb7473682c54aae945" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "attrs": { - "hashes": [ - "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", - "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" - ], - "markers": "python_version >= '3.7'", - "version": "==23.2.0" - }, - "blinker": { - "hashes": [ - "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", - "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" - ], - "markers": "python_version >= '3.8'", - "version": "==1.7.0" - }, - "boto3": { - "hashes": [ - "sha256:e0940e43810fe82f5b77442c751491fcc2768af7e7c3e8c15ea158e1ca9b586c", - "sha256:f9166f485d64b012d46acd212fb29a45b195a85ff66a645b05b06d9f7572af36" - ], - "index": "pypi", - "version": "==1.34.89" - }, - "botocore": { - "hashes": [ - "sha256:35205ed7db13058a3f7114c28e93058a8ff1490dfc6a5b5dff9c581c738fbf59", - "sha256:6624b69bcdf2c5d0568b7bc9cbac13e605f370e7ea06710c61e2e2dc76831141" - ], - "markers": "python_version >= '3.8'", - "version": "==1.34.89" - }, - "certifi": { - "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" - ], - "markers": "python_version >= '3.6'", - "version": "==2024.2.2" - }, - "cffi": { - "hashes": [ - "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", - "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", - "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", - "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", - "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", - "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", - "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", - "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", - "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", - "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", - "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", - "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", - "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", - "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", - "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", - "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", - "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", - "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", - "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", - "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", - "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", - "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", - "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", - "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", - "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", - "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", - "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", - "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", - "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", - "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", - "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", - "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", - "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", - "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", - "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", - "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", - "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", - "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", - "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", - "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", - "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", - "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", - "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", - "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", - "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", - "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", - "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", - "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", - "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", - "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", - "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", - "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" - ], - "markers": "platform_python_implementation != 'PyPy'", - "version": "==1.16.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" - }, - "click": { - "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.7" - }, - "cryptography": { - "hashes": [ - "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", - "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", - "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", - "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", - "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", - "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", - "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", - "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", - "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", - "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", - "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", - "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", - "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", - "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", - "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", - "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", - "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", - "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", - "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", - "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", - "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", - "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", - "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", - "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", - "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", - "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", - "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", - "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", - "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", - "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", - "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", - "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" - ], - "markers": "python_version >= '3.7'", - "version": "==42.0.5" - }, - "dataclasses": { - "hashes": [ - "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f", - "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84" - ], - "index": "pypi", - "version": "==0.6" - }, - "flasgger": { - "hashes": [ - "sha256:ca098e10bfbb12f047acc6299cc70a33851943a746e550d86e65e60d4df245fb" - ], - "index": "pypi", - "version": "==0.9.7.1" - }, - "flask": { - "hashes": [ - "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc", - "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b" - ], - "index": "pypi", - "version": "==2.3.3" - }, - "flask-cors": { - "hashes": [ - "sha256:bc3492bfd6368d27cfe79c7821df5a8a319e1a6d5eab277a3794be19bdc51783", - "sha256:f268522fcb2f73e2ecdde1ef45e2fd5c71cc48fe03cffb4b441c6d1b40684eb0" - ], - "index": "pypi", - "version": "==4.0.0" - }, - "flask-httpauth": { - "hashes": [ - "sha256:66568a05bc73942c65f1e2201ae746295816dc009edd84b482c44c758d75097a", - "sha256:a58fedd09989b9975448eef04806b096a3964a7feeebc0a78831ff55685b62b0" - ], - "index": "pypi", - "version": "==4.8.0" - }, - "flask-jwt-extended": { - "hashes": [ - "sha256:63a28fc9731bcc6c4b8815b6f954b5904caa534fc2ae9b93b1d3ef12930dca95", - "sha256:9215d05a9413d3855764bcd67035e75819d23af2fafb6b55197eb5a3313fdfb2" - ], - "index": "pypi", - "version": "==4.6.0" - }, - "flask-sqlalchemy": { - "hashes": [ - "sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0", - "sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312" - ], - "index": "pypi", - "version": "==3.1.1" - }, - "greenlet": { - "hashes": [ - "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67", - "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6", - "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257", - "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4", - "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676", - "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61", - "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc", - "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca", - "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7", - "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728", - "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305", - "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6", - "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379", - "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414", - "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04", - "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a", - "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf", - "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491", - "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559", - "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e", - "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274", - "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb", - "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b", - "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9", - "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b", - "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be", - "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506", - "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405", - "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113", - "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f", - "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5", - "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230", - "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d", - "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f", - "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a", - "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e", - "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61", - "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6", - "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d", - "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71", - "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22", - "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2", - "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3", - "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067", - "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc", - "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881", - "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3", - "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e", - "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac", - "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53", - "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0", - "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b", - "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83", - "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41", - "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c", - "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf", - "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da", - "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33" - ], - "markers": "platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==3.0.3" - }, - "gunicorn": { - "hashes": [ - "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9", - "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63" - ], - "index": "pypi", - "version": "==22.0.0" - }, - "idna": { - "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" - ], - "markers": "python_version >= '3.5'", - "version": "==3.7" - }, - "itsdangerous": { - "hashes": [ - "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", - "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" - ], - "markers": "python_version >= '3.8'", - "version": "==2.2.0" - }, - "jinja2": { - "hashes": [ - "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", - "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.3" - }, - "jmespath": { - "hashes": [ - "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", - "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" - ], - "markers": "python_version >= '3.7'", - "version": "==1.0.1" - }, - "jsonschema": { - "hashes": [ - "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f", - "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5" - ], - "markers": "python_version >= '3.8'", - "version": "==4.21.1" - }, - "jsonschema-specifications": { - "hashes": [ - "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", - "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" - ], - "markers": "python_version >= '3.8'", - "version": "==2023.12.1" - }, - "jwt": { - "hashes": [ - "sha256:61c9170f92e736b530655e75374681d4fcca9cfa8763ab42be57353b2b203494" - ], - "index": "pypi", - "version": "==1.3.1" - }, - "markupsafe": { - "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" - }, - "mistune": { - "hashes": [ - "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", - "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.2" - }, - "packaging": { - "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" - ], - "markers": "python_version >= '3.7'", - "version": "==24.0" - }, - "prometheus-client": { - "hashes": [ - "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89", - "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7" - ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" - }, - "prometheus-flask-exporter": { - "hashes": [ - "sha256:7a026b4fdd54ebeddb77589333efe3a1ec43c7c717468825b0b3e9b6c33f7e9e", - "sha256:e4e6beb1b8e1e164da6d70fe1edefc95ef184f113b5047f66f4b7262233da9c0" - ], - "index": "pypi", - "version": "==0.23.0" - }, - "pycparser": { - "hashes": [ - "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", - "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" - ], - "markers": "python_version >= '3.8'", - "version": "==2.22" - }, - "pyjwt": { - "hashes": [ - "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", - "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" - ], - "markers": "python_version >= '3.7'", - "version": "==2.8.0" - }, - "python-dateutil": { - "hashes": [ - "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", - "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.0.post0" - }, - "python-dotenv": { - "hashes": [ - "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", - "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" - ], - "index": "pypi", - "version": "==1.0.1" - }, - "pyyaml": { - "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" - }, - "referencing": { - "hashes": [ - "sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844", - "sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4" - ], - "markers": "python_version >= '3.8'", - "version": "==0.34.0" - }, - "requests": { - "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" - ], - "index": "pypi", - "version": "==2.31.0" - }, - "rpds-py": { - "hashes": [ - "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f", - "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c", - "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76", - "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e", - "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157", - "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f", - "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5", - "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05", - "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24", - "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1", - "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8", - "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b", - "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb", - "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07", - "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1", - "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6", - "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e", - "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e", - "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1", - "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab", - "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4", - "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17", - "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594", - "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d", - "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d", - "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3", - "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c", - "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66", - "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f", - "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80", - "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33", - "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f", - "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c", - "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022", - "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e", - "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f", - "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da", - "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1", - "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688", - "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795", - "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c", - "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98", - "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1", - "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20", - "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307", - "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4", - "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18", - "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294", - "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66", - "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467", - "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948", - "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e", - "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1", - "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0", - "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7", - "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd", - "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641", - "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d", - "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9", - "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1", - "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da", - "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3", - "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa", - "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7", - "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40", - "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496", - "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124", - "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836", - "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434", - "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984", - "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f", - "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6", - "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e", - "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461", - "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c", - "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432", - "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73", - "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58", - "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88", - "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337", - "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7", - "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863", - "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475", - "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3", - "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51", - "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf", - "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024", - "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40", - "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9", - "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec", - "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb", - "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7", - "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861", - "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880", - "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f", - "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd", - "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca", - "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58", - "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e" - ], - "markers": "python_version >= '3.8'", - "version": "==0.18.0" - }, - "s3transfer": { - "hashes": [ - "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19", - "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d" - ], - "markers": "python_version >= '3.8'", - "version": "==0.10.1" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sqlalchemy": { - "hashes": [ - "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb", - "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c", - "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d", - "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a", - "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003", - "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699", - "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e", - "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93", - "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de", - "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513", - "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380", - "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567", - "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586", - "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b", - "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673", - "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d", - "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b", - "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e", - "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c", - "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03", - "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e", - "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec", - "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72", - "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c", - "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41", - "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0", - "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba", - "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b", - "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930", - "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7", - "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1", - "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1", - "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9", - "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c", - "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f", - "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520", - "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b", - "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0", - "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552", - "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907", - "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e", - "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f", - "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5", - "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305", - "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01", - "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44", - "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd", - "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5", - "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.29" - }, - "sqlalchemy-utils": { - "hashes": [ - "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e", - "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990" - ], - "index": "pypi", - "version": "==0.41.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", - "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" - ], - "markers": "python_version >= '3.8'", - "version": "==4.11.0" - }, - "urllib3": { - "hashes": [ - "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", - "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" - ], - "markers": "python_version >= '3.8'", - "version": "==2.2.1" - }, - "werkzeug": { - "hashes": [ - "sha256:3aac3f5da756f93030740bc235d3e09449efcf65f2f55e3602e1d851b8f48795", - "sha256:e39b645a6ac92822588e7b39a692e7828724ceae0b0d702ef96701f90e70128d" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.2" - } - }, - "develop": { - "coverage": { - "hashes": [ - "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c", - "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63", - "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7", - "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f", - "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8", - "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf", - "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0", - "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384", - "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76", - "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7", - "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d", - "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70", - "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f", - "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818", - "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b", - "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d", - "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec", - "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083", - "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2", - "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9", - "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd", - "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade", - "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e", - "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a", - "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227", - "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87", - "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c", - "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e", - "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c", - "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e", - "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd", - "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec", - "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562", - "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8", - "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677", - "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357", - "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c", - "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd", - "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49", - "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286", - "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1", - "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf", - "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51", - "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409", - "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384", - "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e", - "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978", - "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57", - "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e", - "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2", - "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48", - "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4" - ], - "index": "pypi", - "version": "==7.4.4" - }, - "iniconfig": { - "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "packaging": { - "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" - ], - "markers": "python_version >= '3.7'", - "version": "==24.0" - }, - "pluggy": { - "hashes": [ - "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", - "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" - ], - "markers": "python_version >= '3.8'", - "version": "==1.5.0" - }, - "pytest": { - "hashes": [ - "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7", - "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044" - ], - "index": "pypi", - "version": "==8.1.1" - } - } -} diff --git a/dbrepo-data-db/sidecar/README.md b/dbrepo-data-db/sidecar/README.md deleted file mode 100644 index 83815a632f..0000000000 --- a/dbrepo-data-db/sidecar/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Data Database Sidecar - -Sidecar that downloads the .csv from the Upload Service to deposit on the same pod as the data-database. - -## Endpoints - -* Prometheus metrics [`/metrics`](http://localhost:8080/metrics) -* Health check [`/health`](http://localhost:8080/health) -* Swagger API [`/swagger-ui/`](http://localhost:8080/swagger-ui/) \ No newline at end of file diff --git a/dbrepo-data-db/sidecar/app.py b/dbrepo-data-db/sidecar/app.py deleted file mode 100644 index 955e3d9c3d..0000000000 --- a/dbrepo-data-db/sidecar/app.py +++ /dev/null @@ -1,198 +0,0 @@ -import json -import os -import logging -import requests - -from typing import Any, List -from flasgger import LazyJSONEncoder, Swagger -from flask import Flask, request, Response -from flask_httpauth import HTTPBasicAuth, MultiAuth, HTTPTokenAuth -from flasgger.utils import swag_from -from json import dumps - -from clients.keycloak_client import KeycloakClient, User -from clients.s3_client import S3Client -from prometheus_flask_exporter import PrometheusMetrics - -logging.basicConfig(level=logging.DEBUG) - -from logging.config import dictConfig - -# logging configuration -dictConfig({ - 'version': 1, - 'formatters': { - 'default': { - 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s', - }, - 'simple': { - 'format': '[%(asctime)s] %(levelname)s: %(message)s', - }, - }, - 'handlers': {'wsgi': { - 'class': 'logging.StreamHandler', - 'stream': 'ext://flask.logging.wsgi_errors_stream', - 'formatter': 'simple' # default - }}, - 'root': { - 'level': 'DEBUG', - 'handlers': ['wsgi'] - } -}) - -# create app object -app = Flask(__name__) - -token_auth = HTTPTokenAuth(scheme='Bearer') -basic_auth = HTTPBasicAuth() -auth = MultiAuth(token_auth, basic_auth) - -metrics = PrometheusMetrics(app) -metrics.info("app_info", "Application info", version="__APPVERSION__") -app.config["SWAGGER"] = {"openapi": "3.0.1", "title": "Swagger UI", "uiversion": 3} - -swagger_config = { - "headers": [], - "specs": [ - { - "endpoint": "api-sidecar", - "route": "/api-sidecar.json", - "rule_filter": lambda rule: rule.endpoint.startswith('actuator') or rule.endpoint.startswith('sidecar'), - "model_filter": lambda tag: True, # all in - } - ], - "static_url_path": "/flasgger_static", - "swagger_ui": True, - "specs_route": "/swagger-ui/", -} - -template = { - "openapi": "3.0.0", - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "in": "header" - }, - "basicAuth": { - "type": "http", - "scheme": "basic", - "in": "header" - } - }, - }, - "info": { - "title": "Database Repository Data Database sidecar API", - "description": "Sidecar that downloads the import .csv file", - "version": "__APPVERSION__", - "contact": { - "name": "Prof. Andreas Rauber", - "email": "andreas.rauber@tuwien.ac.at" - }, - "license": { - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0" - }, - }, - "externalDocs": { - "description": "Sourcecode Documentation", - "url": "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/__APPVERSION__/" - }, - "servers": [ - { - "url": "http://localhost:8080", - "description": "Generated server url" - }, - { - "url": "https://test.dbrepo.tuwien.ac.at", - "description": "Sandbox" - } - ] -} - -swagger = Swagger(app, config=swagger_config, template=template) -app.config["JWT_ALGORITHM"] = "HS256" -app.config["JWT_PUBKEY"] = '-----BEGIN PUBLIC KEY-----\n' + os.getenv("JWT_PUBKEY", - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB") + '\n-----END PUBLIC KEY-----' -app.config["AUTH_SERVICE_ENDPOINT"] = os.getenv("AUTH_SERVICE_ENDPOINT", "http://localhost/api/auth") -app.config["AUTH_SERVICE_CLIENT"] = os.getenv("AUTH_SERVICE_CLIENT", "dbrepo-client") -app.config["AUTH_SERVICE_CLIENT_SECRET"] = os.getenv("AUTH_SERVICE_CLIENT_SECRET", "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG") -app.config["S3_ACCESS_KEY_ID"] = os.getenv('S3_ACCESS_KEY_ID', 'seaweedfsadmin') -app.config["S3_ENDPOINT"] = os.getenv('S3_ENDPOINT', 'http://localhost:9000') -app.config["S3_FILE_PATH"] = os.getenv('S3_FILE_PATH', '/tmp') -app.config["S3_SECRET_ACCESS_KEY"] = os.getenv('S3_SECRET_ACCESS_KEY', 'seaweedfsadmin') -app.config["S3_BUCKET"] = os.getenv('S3_BUCKET', 'dbrepo') - -app.json_encoder = LazyJSONEncoder - - -@token_auth.verify_token -def verify_token(token: str): - if token is None or token == "": - return False - try: - client = KeycloakClient() - return client.verify_jwt(access_token=token) - except AssertionError: - return False - - -@basic_auth.verify_password -def verify_password(username: str, password: str) -> Any: - if username is None or username == "" or password is None or password == "": - return False - client = KeycloakClient() - try: - return client.verify_jwt(access_token=client.obtain_user_token(username=username, password=password)) - except AssertionError as error: - logging.error(error) - return False - except requests.exceptions.ConnectionError as error: - logging.error(f"Failed to connect to Authentication Service {error}") - return False - - -@token_auth.get_user_roles -def get_user_roles(user: User) -> List[str]: - return user.roles - - -@basic_auth.get_user_roles -def get_user_roles(user: User) -> List[str]: - return user.roles - - -@app.route("/health", methods=["GET"], endpoint="actuator_health") -def health(): - logging.debug("endpoint health, body=%s", request) - res = dumps({"status": "UP", "message": "Application is up and running"}) - return Response(res, mimetype="application/json"), 200 - - -@app.route("/sidecar/import/<string:filename>", methods=["POST"], endpoint="sidecar_import") -@metrics.gauge(name='dbrepo_sidecar_import_dataset', description='Time needed to import dataset from S3') -@auth.login_required(role=['import-database-data']) -@swag_from("ds-yml/import.yml") -def import_csv(filename): - auth.current_user() - logging.debug('endpoint import csv, filename=%s, body=%s', filename, request) - s3_client = S3Client() - response = s3_client.download_file(filename, app.config["S3_FILE_PATH"], app.config['S3_BUCKET']) - if response is False: - return Response(), 400 - return Response(json.dumps(response)), 202 - - -@app.route("/sidecar/export/<string:filename>", methods=["POST"], endpoint="sidecar_export") -@metrics.gauge(name='dbrepo_sidecar_export_dataset', description='Time needed to export dataset to S3') -@auth.login_required(role=['export-query-data', 'export-table-data']) -@swag_from("ds-yml/export.yml") -def import_csv(filename): - logging.debug('endpoint export csv, filename=%s, body=%s', filename, request) - s3_client = S3Client() - response = s3_client.upload_file(filename, app.config["S3_FILE_PATH"], app.config['S3_BUCKET']) - if response is False: - return Response(), 400 - return Response(), 202 diff --git a/dbrepo-data-db/sidecar/clients/keycloak_client.py b/dbrepo-data-db/sidecar/clients/keycloak_client.py deleted file mode 100644 index 9bd0b273bf..0000000000 --- a/dbrepo-data-db/sidecar/clients/keycloak_client.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging -from dataclasses import dataclass -import requests -from flask import current_app -from typing import List - -from jwt import jwk_from_pem, JWT - - -@dataclass(init=True, eq=True) -class User: - username: str - roles: List[str] - - -class KeycloakClient: - - def obtain_user_token(self, username: str, password: str) -> str: - response = requests.post(f"{current_app.config['KEYCLOAK_HOST']}/realms/dbrepo/protocol/openid-connect/token", - data={ - "username": username, - "password": password, - "grant_type": "password", - "client_id": current_app.config["AUTH_SERVICE_CLIENT"], - "client_secret": current_app.config["KEYCLOAK_CLIENT_SECRET"] - }) - body = response.json() - if "access_token" not in body: - raise AssertionError("Failed to obtain user token(s)") - return response.json()["access_token"] - - def verify_jwt(self, access_token: str) -> User: - public_key = jwk_from_pem(str(current_app.config["JWT_PUBKEY"]).encode('utf-8')) - payload = JWT().decode(message=access_token, key=public_key, do_time_check=True) - return User(username=payload.get('client_id'), roles=payload.get('realm_access')["roles"]) diff --git a/dbrepo-data-db/sidecar/clients/s3_client.py b/dbrepo-data-db/sidecar/clients/s3_client.py deleted file mode 100644 index d34760f623..0000000000 --- a/dbrepo-data-db/sidecar/clients/s3_client.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import boto3 -import logging -import sys - -from flask import current_app -from botocore.exceptions import ClientError - - -class S3Client: - - def __init__(self): - endpoint_url = current_app.config['S3_ENDPOINT'] - aws_access_key_id = current_app.config['S3_ACCESS_KEY_ID'] - aws_secret_access_key = current_app.config['S3_SECRET_ACCESS_KEY'] - logging.info( - f"retrieve file from S3, endpoint_url={endpoint_url}, aws_access_key_id={aws_access_key_id}, aws_secret_access_key=(hidden)") - self.client = boto3.client(service_name='s3', endpoint_url=endpoint_url, aws_access_key_id=aws_access_key_id, - aws_secret_access_key=aws_secret_access_key) - self.bucket_exists_or_exit(current_app.config['S3_BUCKET']) - - def upload_file(self, filename, path, bucket) -> bool: - """ - Uploads a file to the blob storage. - Follows the official API https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html. - :param filename: The filename. - :param path: The path. - :param bucket: The bucket. - :return: True if the file was uploaded. - """ - filepath = os.path.join(path, filename) - try: - self.client.upload_file(filepath, bucket, filename) - logging.info(f"Uploaded .csv {filepath} with key {filename} into bucket {bucket}") - return True - except ClientError as e: - logging.error(e) - return False - - def download_file(self, filename, path, bucket) -> bool: - """ - Downloads a file from the blob storage. - Follows the official API https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-example-download-file.html - :param filename: The filename. - :param path: The path. - :param bucket: The bucket. - :return: True if the file was downloaded and saved. - """ - self.file_exists(bucket, filename) - filepath = os.path.join(path, filename) - try: - self.client.download_file(bucket, filename, filepath) - logging.info(f"Downloaded .csv with key {filename} into {filepath} from bucket {bucket}") - return True - except ClientError as e: - logging.error(e) - return False - - def file_exists(self, bucket, filename): - try: - self.client.head_object(Bucket=bucket, Key=filename) - logging.debug(f"file with name {filename} exists in bucket with name {bucket}") - except ClientError as e: - if e.response["Error"]["Code"] == "404": - logging.error(f"Failed to find key {filename} in bucket {bucket}") - else: - logging.error( - f"Unexpected error when finding key {filename} in bucket {bucket}: {e.response['Error']['Code']}") - raise e - - def bucket_exists_or_exit(self, bucket): - try: - self.client.head_bucket(Bucket=bucket) - logging.debug(f"bucket {bucket} exists.") - except ClientError as e: - if e.response["Error"]["Code"] == "404": - logging.error(f"Failed to find bucket {bucket}") - else: - logging.error(f"Unexpected error when finding bucket {bucket}: {e.response['Error']['Code']}") - sys.exit(1) diff --git a/dbrepo-data-db/sidecar/ds-yml/export.yml b/dbrepo-data-db/sidecar/ds-yml/export.yml deleted file mode 100644 index 50b9e5710f..0000000000 --- a/dbrepo-data-db/sidecar/ds-yml/export.yml +++ /dev/null @@ -1,32 +0,0 @@ -summary: Exports a .csv to the Storage Service -description: | - Exports a specific .csv file to the Storage Service via S3 -consumes: - - application/json -produces: - - application/json -parameters: - - in: path - name: filename - description: Name of the object file to export to the Storage Service - required: true -security: - - bearerAuth: [ ] - - basicAuth: [ ] -responses: - 202: - description: Exported the .csv - content: { } - 400: - description: The Storage Service could not be contacted or .csv was not found. -tags: - - sidecar -components: - securitySchemes: - basicAuth: - type: http - scheme: basic - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT \ No newline at end of file diff --git a/dbrepo-data-db/sidecar/ds-yml/health.yml b/dbrepo-data-db/sidecar/ds-yml/health.yml deleted file mode 100644 index 6032625c66..0000000000 --- a/dbrepo-data-db/sidecar/ds-yml/health.yml +++ /dev/null @@ -1,32 +0,0 @@ -summary: Return a healthcheck -description: | - Return UP if the instance is ready to serve connections. -consumes: - - application/json -produces: - - application/json -parameters: [ ] - -responses: - 200: - description: OK, service is up and running - content: - application/json: - schema: - $ref: "#/components/schemas/Health" - 404: - description: Service is not yet ready -tags: - - actuator - -components: - schemas: - Health: - title: Status object - type: object - properties: - status: - type: string - example: UP - required: - - status \ No newline at end of file diff --git a/dbrepo-data-db/sidecar/ds-yml/import.yml b/dbrepo-data-db/sidecar/ds-yml/import.yml deleted file mode 100644 index 87c6777127..0000000000 --- a/dbrepo-data-db/sidecar/ds-yml/import.yml +++ /dev/null @@ -1,32 +0,0 @@ -summary: Imports a .csv from the Storage Service -description: | - Imports a specific .csv file from the Storage Service via S3 -consumes: - - application/json -produces: - - application/json -parameters: - - in: path - name: filename - description: Name of the object file to import from the Storage Service - required: true -security: - - bearerAuth: [ ] - - basicAuth: [ ] -responses: - 202: - description: Imported the .csv - content: { } - 400: - description: The Storage Service could not be contacted or .csv was not found. -tags: - - sidecar -components: - securitySchemes: - basicAuth: - type: http - scheme: basic - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT \ No newline at end of file diff --git a/dbrepo-data-db/sidecar/metrics.md b/dbrepo-data-db/sidecar/metrics.md deleted file mode 100644 index 0aaa9e332b..0000000000 --- a/dbrepo-data-db/sidecar/metrics.md +++ /dev/null @@ -1,4 +0,0 @@ -| **Metric** | **Description** | -|---------------------------------|---------------------------------------| -| `dbrepo_sidecar_import_dataset` | Time needed to import dataset from S3 | -| `dbrepo_sidecar_export_dataset` | Time needed to export dataset to S3 | \ No newline at end of file diff --git a/dbrepo-data-service/Dockerfile b/dbrepo-data-service/Dockerfile index bd6d428695..f4e2be5b96 100644 --- a/dbrepo-data-service/Dockerfile +++ b/dbrepo-data-service/Dockerfile @@ -3,7 +3,7 @@ FROM dbrepo-metadata-service:build AS dependency LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" ###### SECOND STAGE ###### -FROM maven:3-openjdk-17 AS build +FROM maven:3-amazoncorretto-17 AS build LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" COPY ./pom.xml ./ @@ -28,6 +28,8 @@ RUN apk add --no-cache curl bash jq WORKDIR /app +RUN adduser -S -u 1001 data-service + USER 1001 COPY --from=build --chown=1001 ./rest-service/target/rest-service-*.jar ./data-service.jar @@ -35,4 +37,6 @@ COPY --from=build --chown=1001 ./rest-service/target/rest-service-*.jar ./data-s # non-root port EXPOSE 8080 -ENTRYPOINT ["java", "-Dlog4j2.formatMsgNoLookups=true", "-jar", "./data-service.jar"] \ No newline at end of file +ENV JAVA_OPTS="-XX:+IgnoreUnrecognizedVMOptions --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/jdk.internal.ref=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.cs=ALL-UNNAMED --add-opens=java.base/sun.security.action=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED -Djdk.reflect.useDirectMethodHandle=false -Dio.netty.tryReflectionSetAccessible=true" + +ENTRYPOINT exec java $JAVA_OPTS -jar ./data-service.jar \ No newline at end of file diff --git a/dbrepo-data-service/metrics.md b/dbrepo-data-service/metrics.md index 8219898284..6d8a93935c 100644 --- a/dbrepo-data-service/metrics.md +++ b/dbrepo-data-service/metrics.md @@ -16,4 +16,5 @@ | `dbrepo_table_schema_list` | Find tables | | `dbrepo_table_statistic` | Get table statistic | | `dbrepo_view_data` | Get view data | +| `dbrepo_view_data_export` | Get view data | | `dbrepo_view_schema_list` | Find views | diff --git a/dbrepo-data-service/pom.xml b/dbrepo-data-service/pom.xml index 6517de4746..a6012b573b 100644 --- a/dbrepo-data-service/pom.xml +++ b/dbrepo-data-service/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>3.0.13</version> + <version>3.3.5</version> </parent> <groupId>at.tuwien</groupId> @@ -23,7 +23,7 @@ <module>report</module> </modules> - <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/</url> + <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.4.7/</url> <developers> <developer> <name>Martin Weise</name> @@ -34,11 +34,11 @@ <properties> <java.version>17</java.version> - <spring-cloud.version>4.0.2</spring-cloud.version> + <spring-cloud.version>4.1.4</spring-cloud.version> <mapstruct.version>1.5.5.Final</mapstruct.version> <rabbitmq.version>5.20.0</rabbitmq.version> <jackson-datatype.version>2.15.0</jackson-datatype.version> - <commons-io.version>2.15.0</commons-io.version> + <commons-io.version>2.17.0</commons-io.version> <commons-validator.version>1.8.0</commons-validator.version> <jacoco.version>0.8.12</jacoco.version> <jwt.version>4.3.0</jwt.version> @@ -54,13 +54,16 @@ <aws-s3.version>2.25.23</aws-s3.version> <minio.version>8.5.7</minio.version> <guava.version>33.3.0-jre</guava.version> + <spark.version>4.0.0-preview2</spark.version> + <scala.version>2.13</scala.version> + <antlr-runtime.version>3.5.2</antlr-runtime.version> + <micrometer.version>1.10.0</micrometer.version> + <!-- see https://github.com/apache/spark/blob/cde8e4a82e20a363861f451ebd5138efb3194ab8/pom.xml --> + <hadoop.version>3.4.0</hadoop.version> + <jakarta-servlet.version>5.0.0</jakarta-servlet.version> </properties> <dependencies> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> - </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> @@ -92,6 +95,44 @@ <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> + <!-- Spark --> + <dependency> + <groupId>org.apache.spark</groupId> + <artifactId>spark-core_${scala.version}</artifactId> + <version>${spark.version}</version> + <exclusions> + <exclusion> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j2-impl</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr-runtime</artifactId> + <version>${antlr-runtime.version}</version> + </dependency> + <dependency> + <groupId>org.apache.spark</groupId> + <artifactId>spark-sql_${scala.version}</artifactId> + <version>${spark.version}</version> + <exclusions> + <exclusion> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j2-impl</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + <version>${jakarta-servlet.version}</version> + </dependency> + <dependency> + <groupId>org.apache.hadoop</groupId> + <artifactId>hadoop-aws</artifactId> + <version>${hadoop.version}</version> + </dependency> <!-- Open API --> <dependency> <groupId>org.springdoc</groupId> @@ -167,6 +208,11 @@ <artifactId>jackson-datatype-hibernate6</artifactId> <version>${jackson-datatype.version}</version> </dependency> + <dependency> + <groupId>com.github.jsqlparser</groupId> + <artifactId>jsqlparser</artifactId> + <version>${jsql.version}</version> + </dependency> <!-- Authentication --> <dependency> <groupId>com.auth0</groupId> @@ -202,11 +248,6 @@ <version>${aws-s3.version}</version> </dependency> <!-- Testing --> - <dependency> - <groupId>com.github.jsqlparser</groupId> - <artifactId>jsqlparser</artifactId> - <version>${jsql.version}</version> - </dependency> <dependency> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service-test</artifactId> @@ -240,11 +281,13 @@ <groupId>org.testcontainers</groupId> <artifactId>minio</artifactId> <version>${testcontainers.version}</version> + <scope>test</scope> </dependency> <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> + <scope>test</scope> </dependency> </dependencies> @@ -255,6 +298,7 @@ <filtering>true</filtering> <includes> <include>**/application*.yml</include> + <include>**/jars/*.jar</include> </includes> </resource> </resources> diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 4059a37a92..e5a25f174e 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -16,6 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -75,8 +76,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> create(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<Void> create(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @Valid @RequestBody UpdateDatabaseAccessDto data) throws NotAllowedException, DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, DatabaseMalformedException, MetadataServiceException { @@ -131,8 +132,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> update(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<Void> update(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @Valid @RequestBody UpdateDatabaseAccessDto access) throws NotAllowedException, DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, DatabaseMalformedException, MetadataServiceException { @@ -188,8 +189,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> revoke(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId) throws NotAllowedException, + public ResponseEntity<Void> revoke(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId) throws NotAllowedException, DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, DatabaseMalformedException, MetadataServiceException { log.debug("endpoint revoke access to database, databaseId={}, userId={}", databaseId, userId); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 9cefc57fa2..50c503852b 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -131,7 +132,7 @@ public class DatabaseEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> update(@NotBlank @PathVariable("databaseId") Long databaseId, + public ResponseEntity<Void> update(@NotNull @PathVariable("databaseId") Long databaseId, @Valid @RequestBody UpdateUserPasswordDto data) throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, DatabaseMalformedException, MetadataServiceException { diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java index 1637878a67..63962694f1 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java @@ -146,7 +146,8 @@ public class SubsetEndpoint { @RequestParam(required = false) Instant timestamp) throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, QueryNotFoundException, FormatNotAvailableException, StorageUnavailableException, QueryMalformedException, - SidecarExportException, StorageNotFoundException, UserNotFoundException, MetadataServiceException { + StorageNotFoundException, UserNotFoundException, MetadataServiceException, ViewNotFoundException, + MalformedException { String accept = httpServletRequest.getHeader("Accept"); log.debug("endpoint find subset in database, databaseId={}, subsetId={}, accept={}, timestamp={}", databaseId, subsetId, accept, timestamp); @@ -173,9 +174,8 @@ public class SubsetEndpoint { return ResponseEntity.ok(query); case "text/csv": log.trace("accept header matches csv"); - final String filename = RandomStringUtils.randomAlphabetic(20).toLowerCase(); try { - final ExportResourceDto resource = subsetService.export(database, query, timestamp, filename); + final ExportResourceDto resource = subsetService.export(database, query, timestamp); final HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); log.trace("export table resulted in resource {}", resource); @@ -240,9 +240,9 @@ public class SubsetEndpoint { @RequestParam(required = false) Long size, @RequestParam(required = false) Instant timestamp) throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, - QueryNotFoundException, StorageUnavailableException, QueryMalformedException, SidecarExportException, - StorageNotFoundException, QueryStoreInsertException, TableMalformedException, PaginationException, - QueryNotSupportedException, NotAllowedException, UserNotFoundException, MetadataServiceException { + QueryNotFoundException, StorageUnavailableException, QueryMalformedException, StorageNotFoundException, + QueryStoreInsertException, TableMalformedException, PaginationException, QueryNotSupportedException, + NotAllowedException, UserNotFoundException, MetadataServiceException { log.debug("endpoint create subset in database, databaseId={}, data.statement={}, page={}, size={}, " + "timestamp={}", databaseId, data.getStatement(), page, size, timestamp); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 06afef015d..677e181b0a 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -144,8 +144,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> delete(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId) + public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, QueryMalformedException, MetadataServiceException { log.debug("endpoint delete table, databaseId={}, tableId={}", databaseId, tableId); @@ -194,8 +194,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<QueryResultDto> getData(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<QueryResultDto> getData(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @RequestParam(required = false) Instant timestamp, @RequestParam(required = false) Long page, @RequestParam(required = false) Long size, @@ -237,7 +237,7 @@ public class TableEndpoint { .headers(headers) .build(); } - final QueryResultDto dto = tableService.getData(table, timestamp, page, size); + final QueryResultDto dto = tableService.getPaginatedData(table, timestamp, page, size); return ResponseEntity.ok() .body(dto); } catch (SQLException e) { @@ -276,8 +276,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> insertRawTuple(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<Void> insertRawTuple(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @Valid @RequestBody TupleDto data, @NotNull Principal principal) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, @@ -328,8 +328,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> updateRawTuple(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<Void> updateRawTuple(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @Valid @RequestBody TupleUpdateDto data, @NotNull Principal principal) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, @@ -380,8 +380,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> deleteRawTuple(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<Void> deleteRawTuple(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @Valid @RequestBody TupleDeleteDto data, @NotNull Principal principal) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, @@ -503,7 +503,7 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<List<TableDto>> getSchema(@NotBlank @PathVariable("databaseId") Long databaseId) + public ResponseEntity<List<TableDto>> getSchema(@NotNull @PathVariable("databaseId") Long databaseId) throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, DatabaseMalformedException, TableNotFoundException, MetadataServiceException { log.debug("endpoint inspect table schemas, databaseId={}", databaseId); @@ -548,13 +548,12 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<InputStreamResource> exportDataset(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<InputStreamResource> exportDataset(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @RequestParam(required = false) Instant timestamp, Principal principal) - throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - NotAllowedException, StorageUnavailableException, QueryMalformedException, SidecarExportException, - StorageNotFoundException, MetadataServiceException { + throws RemoteUnavailableException, TableNotFoundException, NotAllowedException, StorageUnavailableException, + QueryMalformedException, MetadataServiceException, MalformedException { log.debug("endpoint export table data, databaseId={}, tableId={}, timestamp={}", databaseId, tableId, timestamp); /* parameters */ if (timestamp == null) { @@ -569,19 +568,13 @@ public class TableEndpoint { } metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal)); } - try { - final HttpHeaders headers = new HttpHeaders(); - final ExportResourceDto resource = tableService.exportDataset(table, timestamp); - headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); - log.trace("export table resulted in resource {}", resource); - return ResponseEntity.ok() - .headers(headers) - .body(resource.getResource()); - - } catch (SQLException e) { - log.error("Failed to establish connection to database: {}", e.getMessage()); - throw new DatabaseUnavailableException("Failed to establish connection to database", e); - } + final HttpHeaders headers = new HttpHeaders(); + final ExportResourceDto resource = tableService.exportDataset(table, timestamp); + headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); + log.trace("export table resulted in resource {}", resource); + return ResponseEntity.ok() + .headers(headers) + .body(resource.getResource()); } @PostMapping("/{tableId}/data/import") @@ -614,13 +607,13 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> importDataset(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId, + public ResponseEntity<Void> importDataset(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, @Valid @RequestBody ImportDto data, @NotNull Principal principal) - throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - QueryMalformedException, StorageNotFoundException, SidecarImportException, NotAllowedException, - MetadataServiceException { + throws RemoteUnavailableException, TableNotFoundException, NotAllowedException, MetadataServiceException, + StorageNotFoundException, MalformedException, StorageUnavailableException, QueryMalformedException, + DatabaseUnavailableException { log.debug("endpoint insert table data, databaseId={}, tableId={}, data.location={}", databaseId, tableId, data.getLocation()); final PrivilegedTableDto table = metadataServiceGateway.getTableById(databaseId, tableId); final DatabaseAccessDto access = metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal)); @@ -631,13 +624,13 @@ public class TableEndpoint { } try { tableService.importDataset(table, data); - metadataServiceGateway.updateTableStatistics(databaseId, tableId); - return ResponseEntity.accepted() - .build(); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); throw new DatabaseUnavailableException("Failed to establish connection to database", e); } + metadataServiceGateway.updateTableStatistics(databaseId, tableId); + return ResponseEntity.accepted() + .build(); } @GetMapping("/{tableId}/statistic") @@ -666,8 +659,8 @@ public class TableEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<TableStatisticDto> statistic(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("tableId") Long tableId) + public ResponseEntity<TableStatisticDto> statistic(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, MetadataServiceException, TableMalformedException, DatabaseNotFoundException { log.debug("endpoint generate table statistic, databaseId={}, tableId={}", databaseId, tableId); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 9d0bd3b6ad..f0b1b891e7 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -6,7 +6,6 @@ import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.internal.PrivilegedViewDto; import at.tuwien.api.database.query.QueryResultDto; -import at.tuwien.api.database.table.internal.PrivilegedTableDto; import at.tuwien.api.error.ApiErrorDto; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; @@ -94,7 +93,7 @@ public class ViewEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<List<ViewDto>> getSchema(@NotBlank @PathVariable("databaseId") Long databaseId) + public ResponseEntity<List<ViewDto>> getSchema(@NotNull @PathVariable("databaseId") Long databaseId) throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, ViewNotFoundException, DatabaseMalformedException, MetadataServiceException { log.debug("endpoint inspect view schemas, databaseId={}", databaseId); @@ -182,8 +181,8 @@ public class ViewEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> delete(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("viewId") Long viewId) + public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("viewId") Long viewId) throws DatabaseUnavailableException, RemoteUnavailableException, ViewNotFoundException, ViewMalformedException, MetadataServiceException { log.debug("endpoint delete view, databaseId={}, viewId={}", databaseId, viewId); @@ -237,8 +236,8 @@ public class ViewEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<QueryResultDto> getData(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("viewId") Long viewId, + public ResponseEntity<QueryResultDto> getData(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("viewId") Long viewId, @RequestParam(required = false) Long page, @RequestParam(required = false) Long size, @RequestParam(required = false) Instant timestamp, @@ -318,12 +317,11 @@ public class ViewEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<InputStreamResource> exportDataset(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("viewId") Long viewId, + public ResponseEntity<InputStreamResource> exportDataset(@NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("viewId") Long viewId, Principal principal) - throws DatabaseUnavailableException, RemoteUnavailableException, ViewNotFoundException, - NotAllowedException, MetadataServiceException, StorageUnavailableException, QueryMalformedException, - SidecarExportException, StorageNotFoundException { + throws RemoteUnavailableException, ViewNotFoundException, NotAllowedException, MetadataServiceException, + StorageUnavailableException, QueryMalformedException, MalformedException { log.debug("endpoint export view data, databaseId={}, viewId={}", databaseId, viewId); /* parameters */ final PrivilegedViewDto view = metadataServiceGateway.getViewById(databaseId, viewId); @@ -334,19 +332,13 @@ public class ViewEndpoint { } metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal)); } - try { - final HttpHeaders headers = new HttpHeaders(); - final ExportResourceDto resource = viewService.exportDataset(view); - headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); - log.trace("export table resulted in resource {}", resource); - return ResponseEntity.ok() - .headers(headers) - .body(resource.getResource()); - - } catch (SQLException e) { - log.error("Failed to establish connection to database: {}", e.getMessage()); - throw new DatabaseUnavailableException("Failed to establish connection to database", e); - } + final HttpHeaders headers = new HttpHeaders(); + final ExportResourceDto resource = viewService.exportDataset(view); + headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); + log.trace("export table resulted in resource {}", resource); + return ResponseEntity.ok() + .headers(headers) + .body(resource.getResource()); } } diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java index 6aa48b1570..cf3f25fd26 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java @@ -45,6 +45,13 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } + @Hidden + @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) + @ExceptionHandler(AnalyseServiceException.class) + public ResponseEntity<ApiErrorDto> handle(AnalyseServiceException e) { + return generic_handle(e.getClass(), e.getLocalizedMessage()); + } + @Hidden @ResponseStatus(code = HttpStatus.BAD_GATEWAY) @ExceptionHandler(AuthServiceConnectionException.class) @@ -374,20 +381,6 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } - @Hidden - @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) - @ExceptionHandler(SidecarExportException.class) - public ResponseEntity<ApiErrorDto> handle(SidecarExportException e) { - return generic_handle(e.getClass(), e.getLocalizedMessage()); - } - - @Hidden - @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) - @ExceptionHandler(SidecarImportException.class) - public ResponseEntity<ApiErrorDto> handle(SidecarImportException e) { - return generic_handle(e.getClass(), e.getLocalizedMessage()); - } - @Hidden @ResponseStatus(code = HttpStatus.BAD_REQUEST) @ExceptionHandler(SortException.class) diff --git a/dbrepo-data-service/rest-service/src/main/resources/application-local.yml b/dbrepo-data-service/rest-service/src/main/resources/application-local.yml index 43cea9b9a5..e12f578bdd 100644 --- a/dbrepo-data-service/rest-service/src/main/resources/application-local.yml +++ b/dbrepo-data-service/rest-service/src/main/resources/application-local.yml @@ -49,16 +49,18 @@ logging: org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver: debug dbrepo: endpoints: - metadataService: http://localhost - storageService: http://localhost/api/storage - authService: http://localhost/api/auth + metadataService: "http://localhost:9099" + analyseService: "http://localhost" + storageService: "http://localhost:9000" + authService: "http://localhost:8080" + computeService: "local[2]" s3: - accessKeyId: seaweedfsadmin - secretAccessKey: seaweedfsadmin - bucket: dbrepo + accessKeyId: "seaweedfsadmin" + secretAccessKey: "seaweedfsadmin" + bucket: "dbrepo" system: - username: admin - password: admin + username: "admin" + password: "admin" jwt: public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB keycloak: @@ -66,6 +68,3 @@ dbrepo: password: admin client: dbrepo-client clientSecret: MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG - defaultDateFormatId: 1 - defaultTimeFormatId: 4 - defaultTimestampFormatId: 3 diff --git a/dbrepo-data-service/rest-service/src/main/resources/application.yml b/dbrepo-data-service/rest-service/src/main/resources/application.yml index 32eb758b4b..9bd16e6089 100644 --- a/dbrepo-data-service/rest-service/src/main/resources/application.yml +++ b/dbrepo-data-service/rest-service/src/main/resources/application.yml @@ -51,13 +51,14 @@ logging: dbrepo: endpoints: metadataService: "${METADATA_SERVICE_ENDPOINT:http://metadata-service:8080}" + analyseService: "${ANALYSE_SERVICE_ENDPOINT:http://analyse-service:8080}" storageService: "${S3_ENDPOINT:http://storage-service:9000}" authService: "${AUTH_SERVICE_ENDPOINT:http://auth-service:8080}" + computeService: "${COMPUTE_SERVICE_ENDPOINT:local[2]}" s3: accessKeyId: "${S3_ACCESS_KEY_ID:seaweedfsadmin}" secretAccessKey: "${S3_SECRET_ACCESS_KEY:seaweedfsadmin}" bucket: "${S3_BUCKET:dbrepo}" - filePath: "${S3_FILE_PATH:/tmp}" system: username: "${SYSTEM_USERNAME:admin}" password: "${SYSTEM_PASSWORD:admin}" @@ -81,6 +82,3 @@ dbrepo: exchangeName: "${BROKER_EXCHANGE_NAME:dbrepo}" routingKey: "${BROKER_ROUTING_KEY:#}" connectionTimeout: ${CONNECTION_TIMEOUT:10000} - defaultDateFormatId: "${DEFAULT_DATE_FORMAT_ID:3}" - defaultTimeFormatId: "${DEFAULT_TIME_FORMAT_ID:4}" - defaultTimestampFormatId: "${DEFAULT_TIMESTAMP_FORMAT_ID:1}" diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java index 691d96006b..38b33c4713 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java @@ -6,7 +6,7 @@ import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; import at.tuwien.api.database.table.internal.PrivilegedTableDto; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; @@ -17,7 +17,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -@Slf4j +@Log4j2 @Configuration public class MariaDbConfig { diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java index 531f8a387c..5f302368ee 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java @@ -107,9 +107,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, - DatabaseUnavailableException, StorageUnavailableException, NotAllowedException, QueryMalformedException, - QueryNotFoundException, SidecarExportException, FormatNotAvailableException, StorageNotFoundException, - SQLException, MetadataServiceException { + DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotFoundException, + FormatNotAvailableException, StorageNotFoundException, SQLException, MetadataServiceException, + ViewNotFoundException, MalformedException { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_3_ID)) @@ -124,7 +124,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_format_fails() throws DatabaseNotFoundException, RemoteUnavailableException, SQLException, - UserNotFoundException, NotAllowedException, QueryNotFoundException, MetadataServiceException { + UserNotFoundException, QueryNotFoundException, MetadataServiceException { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_3_ID)) @@ -141,9 +141,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_acceptCsv_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, - UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException, NotAllowedException, - QueryMalformedException, QueryNotFoundException, SidecarExportException, FormatNotAvailableException, - StorageNotFoundException, SQLException, MetadataServiceException { + UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, + QueryNotFoundException, FormatNotAvailableException, StorageNotFoundException, SQLException, + MetadataServiceException, ViewNotFoundException, MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("deadbeef") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -154,7 +154,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); - when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class), anyString())) + when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class))) .thenReturn(mock); /* test */ @@ -164,9 +164,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_timestamp_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, - UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException, NotAllowedException, - QueryMalformedException, QueryNotFoundException, SidecarExportException, FormatNotAvailableException, - StorageNotFoundException, SQLException, MetadataServiceException { + UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, + QueryNotFoundException, FormatNotAvailableException, StorageNotFoundException, SQLException, + MetadataServiceException, ViewNotFoundException, MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("deadbeef") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -177,7 +177,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); - when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class), anyString())) + when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class))) .thenReturn(mock); /* test */ @@ -202,7 +202,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_unavailable_fails() throws DatabaseNotFoundException, RemoteUnavailableException, - MetadataServiceException, SQLException, UserNotFoundException, NotAllowedException, QueryNotFoundException { + MetadataServiceException, SQLException, UserNotFoundException, QueryNotFoundException { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_3_ID)) @@ -221,8 +221,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @WithAnonymousUser public void findById_unavailableExport_fails() throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException, SQLException, StorageUnavailableException, QueryMalformedException, - SidecarExportException, StorageNotFoundException, UserNotFoundException, NotAllowedException, - QueryNotFoundException { + StorageNotFoundException, UserNotFoundException, QueryNotFoundException, ViewNotFoundException, MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("deadbeef") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -233,11 +232,11 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); - when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class), anyString())) + when(subsetService.export(any(PrivilegedDatabaseDto.class), any(QueryDto.class), any(Instant.class))) .thenReturn(mock); doThrow(SQLException.class) .when(subsetService) - .export(eq(DATABASE_3_PRIVILEGED_DTO), eq(QUERY_5_DTO), any(Instant.class), anyString()); + .export(eq(DATABASE_3_PRIVILEGED_DTO), eq(QUERY_5_DTO), any(Instant.class)); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -247,8 +246,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query"}) - public void create_noAccess_succeeds() throws UserNotFoundException, QueryStoreInsertException, TableMalformedException, - NotAllowedException, SidecarExportException, QueryNotSupportedException, PaginationException, + public void create_noAccess_succeeds() throws UserNotFoundException, QueryStoreInsertException, + TableMalformedException, NotAllowedException, QueryNotSupportedException, PaginationException, StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException, SQLException, MetadataServiceException { @@ -282,7 +281,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query"}) public void create_noPageSize_succeeds() throws UserNotFoundException, QueryStoreInsertException, - TableMalformedException, NotAllowedException, SidecarExportException, QueryNotSupportedException, + TableMalformedException, NotAllowedException, QueryNotSupportedException, PaginationException, StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException, SQLException, MetadataServiceException { @@ -343,7 +342,11 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) - public void create_noRole_fails() throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, SidecarExportException, QueryNotSupportedException, PaginationException, StorageNotFoundException { + public void create_noRole_fails() throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, + NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, + StorageUnavailableException, QueryMalformedException, QueryNotSupportedException, PaginationException, + StorageNotFoundException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_5_STATEMENT) .build(); @@ -360,7 +363,11 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void create_anonymous_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, SidecarExportException, QueryNotSupportedException, PaginationException, StorageNotFoundException { + public void create_anonymous_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, + NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, + StorageUnavailableException, QueryMalformedException, QueryNotSupportedException, PaginationException, + StorageNotFoundException { final ExecuteStatementDto request = ExecuteStatementDto.builder() .statement(QUERY_5_STATEMENT) .build(); @@ -645,9 +652,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { } protected void generic_findById(Long subsetId, MediaType accept, Instant timestamp) throws UserNotFoundException, - DatabaseUnavailableException, StorageUnavailableException, NotAllowedException, QueryMalformedException, - QueryNotFoundException, DatabaseNotFoundException, SidecarExportException, RemoteUnavailableException, - FormatNotAvailableException, StorageNotFoundException, MetadataServiceException { + DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotFoundException, + DatabaseNotFoundException, RemoteUnavailableException, FormatNotAvailableException, + StorageNotFoundException, MetadataServiceException, ViewNotFoundException, MalformedException { /* mock */ when(mockHttpServletRequest.getHeader("Accept")) diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java index cc4b957226..29b7dfa67c 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java @@ -2,6 +2,7 @@ package at.tuwien.endpoint; import at.tuwien.ExportResourceDto; import at.tuwien.api.database.DatabaseAccessDto; +import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.*; @@ -276,7 +277,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getTableById(DATABASE_3_ID, TABLE_8_ID)) .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(tableService.getData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) + when(tableService.getPaginatedData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) .thenReturn(TABLE_8_DATA_DTO); /* test */ @@ -299,7 +300,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .thenReturn("HEAD"); when(tableService.getCount(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class))) .thenReturn(3L); - when(tableService.getData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) + when(tableService.getPaginatedData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) .thenReturn(TABLE_8_DATA_DTO); /* test */ @@ -355,7 +356,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .thenReturn(TABLE_8_PRIVILEGED_DTO); doThrow(SQLException.class) .when(tableService) - .getData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L)); + .getPaginatedData(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L)); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -393,7 +394,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .thenReturn(TABLE_1_PRIVILEGED_DTO); when(metadataServiceGateway.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(access); - when(tableService.getData(eq(TABLE_1_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) + when(tableService.getPaginatedData(eq(TABLE_1_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L))) .thenReturn(TABLE_1_DATA_DTO); /* test */ @@ -1126,8 +1127,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void exportData_succeeds() throws DatabaseUnavailableException, TableNotFoundException, NotAllowedException, - StorageUnavailableException, QueryMalformedException, SidecarExportException, RemoteUnavailableException, - StorageNotFoundException, SQLException, MetadataServiceException { + StorageUnavailableException, QueryMalformedException, RemoteUnavailableException, StorageNotFoundException, + SQLException, MetadataServiceException, MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("deadbeef") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -1148,9 +1149,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @ParameterizedTest @WithMockUser(username = USER_2_USERNAME) @MethodSource("anyAccess_parameters") - public void exportData_private_succeeds(String name, DatabaseAccessDto access) throws DatabaseUnavailableException, TableNotFoundException, NotAllowedException, - StorageUnavailableException, QueryMalformedException, SidecarExportException, RemoteUnavailableException, - StorageNotFoundException, SQLException, MetadataServiceException { + public void exportData_private_succeeds(String name, DatabaseAccessDto access) throws TableNotFoundException, + NotAllowedException, StorageUnavailableException, QueryMalformedException, RemoteUnavailableException, + MetadataServiceException, MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("deadbeef") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -1188,25 +1189,6 @@ public class TableEndpointUnitTest extends AbstractUnitTest { }); } - @Test - @WithMockUser(username = USER_1_USERNAME) - public void exportData_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException, StorageUnavailableException, SQLException, QueryMalformedException, - SidecarExportException, StorageNotFoundException { - - /* mock */ - when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); - doThrow(SQLException.class) - .when(tableService) - .exportDataset(eq(TABLE_1_PRIVILEGED_DTO), any(Instant.class)); - - /* test */ - assertThrows(DatabaseUnavailableException.class, () -> { - tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_1_ID, null, USER_1_PRINCIPAL); - }); - } - @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"system"}) public void getSchema_succeeds() throws DatabaseUnavailableException, TableNotFoundException, @@ -1264,11 +1246,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) - public void importDataset_succeeds() throws DatabaseUnavailableException, TableNotFoundException, - SidecarImportException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, - StorageNotFoundException, SQLException, MetadataServiceException { + public void importDataset_succeeds() throws TableNotFoundException, NotAllowedException, RemoteUnavailableException, + MetadataServiceException, StorageNotFoundException, MalformedException, StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, SQLException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination(null) .location("deadbeef") .build(); @@ -1294,7 +1275,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_4_USERNAME) public void importDataset_noRole_fails() { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1310,7 +1291,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, MetadataServiceException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1328,11 +1309,11 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) - public void importDataset_unavailable_fails() throws RemoteUnavailableException, SidecarImportException, - SQLException, QueryMalformedException, StorageNotFoundException, TableNotFoundException, - MetadataServiceException, NotAllowedException { + public void importDataset_unavailable_fails() throws RemoteUnavailableException, TableNotFoundException, + MetadataServiceException, NotAllowedException, StorageNotFoundException, MalformedException, + StorageUnavailableException, SQLException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1354,11 +1335,11 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) - public void importDataset_writeOwnAccess_fails() throws RemoteUnavailableException, SidecarImportException, - SQLException, QueryMalformedException, StorageNotFoundException, TableNotFoundException, - MetadataServiceException, NotAllowedException { + public void importDataset_writeOwnAccess_fails() throws RemoteUnavailableException, TableNotFoundException, + MetadataServiceException, NotAllowedException, StorageNotFoundException, MalformedException, + StorageUnavailableException, SQLException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1383,7 +1364,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1403,10 +1384,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeOwnAccess_succeeds() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, - StorageNotFoundException, MetadataServiceException { + NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1426,7 +1407,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1445,11 +1426,11 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) - public void importDataset_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, - StorageNotFoundException, MetadataServiceException { + public void importDataset_writeAllAccessForeign_succeeds() throws TableNotFoundException, + RemoteUnavailableException, NotAllowedException, MetadataServiceException, StorageNotFoundException, + MalformedException, StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1467,10 +1448,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, - StorageNotFoundException, MetadataServiceException { + NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1488,10 +1469,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_private_succeeds() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, DatabaseUnavailableException, SidecarImportException, QueryMalformedException, - StorageNotFoundException, MetadataServiceException { + NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1511,7 +1492,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_privateForeign_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); @@ -1533,7 +1514,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { public void importDataset_privateReadAccess_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException { final ImportDto request = ImportDto.builder() - .skipLines(1L) + .header(true) .lineTermination("\\n") .location("deadbeef") .build(); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java index fd1030c17b..1f4beb8afa 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java @@ -383,4 +383,56 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { }); } + @Test + @WithMockUser(username = USER_3_USERNAME, authorities = {"view-database-view-data"}) + public void exportDataset_privateNoAccess_fails() throws RemoteUnavailableException, ViewNotFoundException, + NotAllowedException, MetadataServiceException { + + /* mock */ + when(metadataServiceGateway.getViewById(DATABASE_1_ID, VIEW_3_ID)) + .thenReturn(VIEW_3_PRIVILEGED_DTO); + doThrow(NotAllowedException.class) + .when(metadataServiceGateway) + .getAccess(DATABASE_1_ID, USER_3_ID); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_3_ID, USER_3_PRINCIPAL); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"}) + public void exportDataset_viewNotFound_fails() throws RemoteUnavailableException, ViewNotFoundException, + MetadataServiceException { + + /* mock */ + doThrow(ViewNotFoundException.class) + .when(metadataServiceGateway) + .getViewById(DATABASE_1_ID, VIEW_1_ID); + + /* test */ + assertThrows(ViewNotFoundException.class, () -> { + viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_1_ID, USER_4_PRINCIPAL); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"}) + public void exportDataset_privateNoAccess_succeeds() throws RemoteUnavailableException, ViewNotFoundException, + NotAllowedException, MetadataServiceException { + + /* mock */ + when(metadataServiceGateway.getViewById(DATABASE_1_ID, VIEW_3_ID)) + .thenReturn(VIEW_3_PRIVILEGED_DTO); + doThrow(NotAllowedException.class) + .when(metadataServiceGateway) + .getAccess(DATABASE_1_ID, USER_1_ID); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + viewEndpoint.exportDataset(DATABASE_1_ID, VIEW_3_ID, USER_1_PRINCIPAL); + }); + } + } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/DataDatabaseGatewayUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/AnalyseServiceGatewayUnitTest.java similarity index 68% rename from dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/DataDatabaseGatewayUnitTest.java rename to dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/AnalyseServiceGatewayUnitTest.java index b00f871d5c..f0a7346ae7 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/DataDatabaseGatewayUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/AnalyseServiceGatewayUnitTest.java @@ -16,7 +16,6 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -26,14 +25,14 @@ import static org.mockito.Mockito.when; @Log4j2 @SpringBootTest @ExtendWith(SpringExtension.class) -public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { +public class AnalyseServiceGatewayUnitTest extends AbstractUnitTest { @MockBean @Qualifier("restTemplate") private RestTemplate restTemplate; @Autowired - private DataDatabaseSidecarGateway dataDatabaseSidecarGateway; + private AnalyseServiceGateway dataDatabaseSidecarGateway; @BeforeEach public void beforeEach() { @@ -41,8 +40,8 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { } @Test - public void importFile_succeeds() throws RemoteUnavailableException, StorageNotFoundException, - SidecarImportException { + public void importDataset_succeeds() throws RemoteUnavailableException, StorageNotFoundException, + AnalyseServiceException { /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), eq(HttpEntity.EMPTY), eq(Void.class))) @@ -50,11 +49,11 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { .build()); /* test */ - dataDatabaseSidecarGateway.importFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.importDataset(DATABASE_1_ID, TABLE_1_ID, "filename"); } @Test - public void importFile_unavailable_fails() { + public void importDataset_unavailable_fails() { /* mock */ doThrow(HttpServerErrorException.class) @@ -63,12 +62,12 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(RemoteUnavailableException.class, () -> { - dataDatabaseSidecarGateway.importFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.importDataset(DATABASE_1_ID, TABLE_1_ID, "filename"); }); } @Test - public void importFile_statusCode_fails() { + public void importDataset_statusCode_fails() { /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), eq(HttpEntity.EMPTY), eq(Void.class))) @@ -76,13 +75,13 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { .build()); /* test */ - assertThrows(SidecarImportException.class, () -> { - dataDatabaseSidecarGateway.importFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + assertThrows(AnalyseServiceException.class, () -> { + dataDatabaseSidecarGateway.importDataset(DATABASE_1_ID, TABLE_1_ID, "filename"); }); } @Test - public void importFile_s3_fails() { + public void importDataset_s3_fails() { /* mock */ doThrow(HttpClientErrorException.BadRequest.class) @@ -91,13 +90,13 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(StorageNotFoundException.class, () -> { - dataDatabaseSidecarGateway.importFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.importDataset(DATABASE_1_ID, TABLE_1_ID, "filename"); }); } @Test - public void exportFile_succeeds() throws RemoteUnavailableException, StorageNotFoundException, - SidecarExportException { + public void exportTable_succeeds() throws RemoteUnavailableException, StorageNotFoundException, + AnalyseServiceException { /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), eq(HttpEntity.EMPTY), eq(Void.class))) @@ -105,11 +104,11 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { .build()); /* test */ - dataDatabaseSidecarGateway.exportFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.exportTable(DATABASE_1_ID, TABLE_1_ID); } @Test - public void exportFile_unavailable_fails() { + public void exportTable_unavailable_fails() { /* mock */ doThrow(HttpServerErrorException.class) @@ -118,12 +117,12 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(RemoteUnavailableException.class, () -> { - dataDatabaseSidecarGateway.exportFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.exportTable(DATABASE_1_ID, TABLE_1_ID); }); } @Test - public void exportFile_statusCode_fails() { + public void exportTable_statusCode_fails() { /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), eq(HttpEntity.EMPTY), eq(Void.class))) @@ -131,13 +130,13 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { .build()); /* test */ - assertThrows(SidecarExportException.class, () -> { - dataDatabaseSidecarGateway.exportFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + assertThrows(AnalyseServiceException.class, () -> { + dataDatabaseSidecarGateway.exportTable(DATABASE_1_ID, TABLE_1_ID); }); } @Test - public void exportFile_s3_fails() { + public void exportTable_s3_fails() { /* mock */ doThrow(HttpClientErrorException.BadRequest.class) @@ -146,7 +145,7 @@ public class DataDatabaseGatewayUnitTest extends AbstractUnitTest { /* test */ assertThrows(StorageNotFoundException.class, () -> { - dataDatabaseSidecarGateway.exportFile(CONTAINER_1_HOST, CONTAINER_1_PORT, "filename"); + dataDatabaseSidecarGateway.exportTable(DATABASE_1_ID, TABLE_1_ID); }); } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java index 44b01b1e9e..2730e94d9c 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java @@ -62,8 +62,7 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { headers.set("X-Username", CONTAINER_1_PRIVILEGED_USERNAME); headers.set("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD); headers.set("X-Database", DATABASE_1_INTERNALNAME); - headers.set("X-Sidecar-Host", CONTAINER_1_SIDECAR_HOST); - headers.set("X-Sidecar-Port", "" + CONTAINER_1_SIDECAR_PORT); + headers.set("X-Table", TABLE_1_INTERNALNAME); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(TableDto.class))) @@ -79,8 +78,7 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { assertEquals(CONTAINER_1_PRIVILEGED_USERNAME, response.getDatabase().getContainer().getUsername()); assertEquals(CONTAINER_1_PRIVILEGED_PASSWORD, response.getDatabase().getContainer().getPassword()); assertEquals(DATABASE_1_INTERNALNAME, response.getDatabase().getInternalName()); - assertEquals(CONTAINER_1_SIDECAR_HOST, response.getDatabase().getContainer().getSidecarHost()); - assertEquals(CONTAINER_1_SIDECAR_PORT, response.getDatabase().getContainer().getSidecarPort()); + assertEquals(TABLE_1_INTERNALNAME, response.getInternalName()); } @Test @@ -155,8 +153,7 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { headers.set("X-Username", CONTAINER_1_PRIVILEGED_USERNAME); headers.set("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD); headers.set("X-Database", DATABASE_1_INTERNALNAME); - headers.set("X-Sidecar-Host", CONTAINER_1_SIDECAR_HOST); - headers.set("X-Sidecar-Port", "" + CONTAINER_1_SIDECAR_PORT); + headers.set("X-Table", TABLE_1_INTERNALNAME); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(TableDto.class))) @@ -450,6 +447,7 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { headers.set("X-Username", CONTAINER_1_PRIVILEGED_USERNAME); headers.set("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD); headers.set("X-Database", DATABASE_1_INTERNALNAME); + headers.set("X-View", VIEW_1_INTERNAL_NAME); /* mock */ when(restTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(ViewDto.class))) diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java index ce56ce82da..7dcb0343ac 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java @@ -114,6 +114,24 @@ public class ApiExceptionHandlerTest extends AbstractUnitTest { } + @Test + public void handle_AnalyseServiceException_succeeds() { + final AnalyseServiceException request = new AnalyseServiceException("msg"); + + /* test */ + final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(request); + assertNotNull(response); + assertNotNull(request.getClass().getDeclaredAnnotation(ResponseStatus.class).code()); + final HttpStatus httpStatus = request.getClass().getDeclaredAnnotation(ResponseStatus.class).code(); + Assertions.assertNotEquals(httpStatus, HttpStatus.INTERNAL_SERVER_ERROR); + assertEquals(httpStatus, response.getStatusCode()); + assertNotNull(response.getBody()); + assertNotNull(response.getBody().getCode()); + assertEquals(httpStatus, response.getBody().getStatus()); + assertEquals("msg", response.getBody().getMessage()); + } + + @Test public void handle_AuthServiceConnectionException_succeeds() { final AuthServiceConnectionException request = new AuthServiceConnectionException("msg"); @@ -942,42 +960,6 @@ public class ApiExceptionHandlerTest extends AbstractUnitTest { } - @Test - public void handle_SidecarExportException_succeeds() { - final SidecarExportException request = new SidecarExportException("msg"); - - /* test */ - final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(request); - assertNotNull(response); - assertNotNull(request.getClass().getDeclaredAnnotation(ResponseStatus.class).code()); - final HttpStatus httpStatus = request.getClass().getDeclaredAnnotation(ResponseStatus.class).code(); - Assertions.assertNotEquals(httpStatus, HttpStatus.INTERNAL_SERVER_ERROR); - assertEquals(httpStatus, response.getStatusCode()); - assertNotNull(response.getBody()); - assertNotNull(response.getBody().getCode()); - assertEquals(httpStatus, response.getBody().getStatus()); - assertEquals("msg", response.getBody().getMessage()); - } - - - @Test - public void handle_SidecarImportException_succeeds() { - final SidecarImportException request = new SidecarImportException("msg"); - - /* test */ - final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(request); - assertNotNull(response); - assertNotNull(request.getClass().getDeclaredAnnotation(ResponseStatus.class).code()); - final HttpStatus httpStatus = request.getClass().getDeclaredAnnotation(ResponseStatus.class).code(); - Assertions.assertNotEquals(httpStatus, HttpStatus.INTERNAL_SERVER_ERROR); - assertEquals(httpStatus, response.getStatusCode()); - assertNotNull(response.getBody()); - assertNotNull(response.getBody().getCode()); - assertEquals(httpStatus, response.getBody().getStatus()); - assertEquals("msg", response.getBody().getMessage()); - } - - @Test public void handle_SortException_succeeds() { final SortException request = new SortException("msg"); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/StorageServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/StorageServiceIntegrationTest.java index d3432ad78b..7e7ec4a775 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/StorageServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/StorageServiceIntegrationTest.java @@ -1,19 +1,22 @@ package at.tuwien.service; import at.tuwien.ExportResourceDto; -import at.tuwien.api.database.AccessTypeDto; -import at.tuwien.config.MariaDbConfig; -import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.config.S3Config; -import at.tuwien.exception.DatabaseMalformedException; +import at.tuwien.exception.MalformedException; import at.tuwien.exception.StorageNotFoundException; import at.tuwien.exception.StorageUnavailableException; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.BeforeAll; +import org.apache.commons.io.FileUtils; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SparkSession; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.DynamicPropertyRegistry; @@ -27,9 +30,14 @@ import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.CreateBucketRequest; import software.amazon.awssdk.services.s3.model.PutObjectRequest; -import java.io.File; -import java.io.InputStream; +import java.io.*; +import java.nio.charset.Charset; import java.sql.SQLException; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -48,6 +56,16 @@ public class StorageServiceIntegrationTest extends AbstractUnitTest { @Autowired private S3Config s3Config; + @Autowired + private SparkSession sparkSession; + + public static Stream<Arguments> loadDataset_arguments() { + return Stream.of( + Arguments.arguments("withHeader", true, 4968), + Arguments.arguments("withoutHeader", false, 4969) + ); + } + @Container private static final MinIOContainer minIOContainer = new MinIOContainer("minio/minio:RELEASE.2024-06-06T09-36-42Z"); @@ -165,4 +183,82 @@ public class StorageServiceIntegrationTest extends AbstractUnitTest { }); } + @Test + public void transformDataset_succeeds() throws StorageUnavailableException, IOException { + final Dataset<Row> request = sparkSession.read() + .option("header", "true") + .csv("./src/test/resources/csv/keyboard.csv"); + final List<String> fileLines = FileUtils.readLines(new File("./src/test/resources/csv/keyboard.csv"), Charset.defaultCharset()); + + /* test */ + final ExportResourceDto response = storageService.transformDataset(request); + assertNotNull(response.getFilename()); + assertEquals("dataset.csv", response.getFilename()); + assertNotNull(response.getResource()); + final List<String> lines = new BufferedReader(new InputStreamReader(response.getResource().getInputStream())) + .lines() + .parallel() + .toList(); + final String[] columNames = lines.get(0).split(","); + assertEquals(10, columNames.length); + assertArrayEquals(new String[]{"Shift key time", "Esc key time", "Ctrl key time", "Alt key time", "User ID", "Test date", "Gender", "Right hand", "Birth year", "Computer skill level"}, columNames); + assertEquals(4969, lines.size()); + for (int i = 0; i < 4969; i++) { + assertEquals(fileLines.get(i), lines.get(i)); + } + } + + @Test + public void transformDataset_empty_succeeds() throws StorageUnavailableException, IOException { + final Dataset<Row> request = sparkSession.emptyDataFrame(); + + /* test */ + final ExportResourceDto response = storageService.transformDataset(request); + assertNotNull(response.getFilename()); + assertEquals("dataset.csv", response.getFilename()); + assertNotNull(response.getResource()); + final List<String> lines = new BufferedReader(new InputStreamReader(response.getResource().getInputStream())) + .lines() + .parallel() + .toList(); + assertEquals(1, lines.size()); + assertEquals("", lines.get(0)); + } + + @ParameterizedTest + @MethodSource("loadDataset_arguments") + public void generic_loadDataset(String name, Boolean withHeader, Integer expectedRows) + throws StorageUnavailableException, StorageNotFoundException, IOException, MalformedException { + final List<String> fileLines = FileUtils.readLines(new File("./src/test/resources/csv/keyboard.csv"), Charset.defaultCharset()); + final String[] requestHeaders = new String[]{"Shift key time", "Esc key time", "Ctrl key time", "Alt key time", "User ID", "Test date", "Gender", "Right hand", "Birth year", "Computer skill level"}; + + /* mock */ + s3Client.putObject(PutObjectRequest.builder() + .key("s3key") + .bucket(s3Config.getS3Bucket()) + .build(), RequestBody.fromFile(new File("src/test/resources/csv/keyboard.csv"))); + + /* test */ + final Dataset<Row> response = storageService.loadDataset(Arrays.asList(requestHeaders), "s3key", withHeader); + final List<Map<String, String>> rows = datasetToRows(response); + assertEquals(expectedRows, rows.size()); + for (int i = 0; i < expectedRows; i++) { + assertEquals(fileLines.get(i + (withHeader ? 1 : 0)), String.join(",", rows.get(i).values())); + } + } + + public List<Map<String, String>> datasetToRows(Dataset<Row> data) { + return data.collectAsList() + .stream() + .map(row -> { + final Map<String, String> map = new LinkedHashMap<>(); + for (int i = 0; i < data.columns().length; i++) { + final String value = row.getString(i); + map.put(data.columns()[i], row.get(i) != null ? value : ""); + } + return map; + }) + .toList(); + } + } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java index dd36d2eb8f..63f69734f3 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java @@ -8,11 +8,13 @@ import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.config.S3Config; import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; +import at.tuwien.gateway.AnalyseServiceGateway; import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -49,7 +51,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { private MetadataServiceGateway metadataServiceGateway; @MockBean - private DataDatabaseSidecarGateway dataDatabaseSidecarGateway; + private AnalyseServiceGateway dataDatabaseSidecarGateway; @MockBean private StorageService storageService; @@ -201,8 +203,8 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { } @Test - public void findAll_succeeds() throws SQLException, QueryNotFoundException, NotAllowedException, - RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { + public void findAll_succeeds() throws SQLException, QueryNotFoundException, RemoteUnavailableException, + MetadataServiceException, DatabaseNotFoundException, InterruptedException { /* test */ final List<QueryDto> response = findAll_generic(null); @@ -212,7 +214,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { } @Test - public void findAll_onlyPersisted_succeeds() throws SQLException, QueryNotFoundException, NotAllowedException, + public void findAll_onlyPersisted_succeeds() throws SQLException, QueryNotFoundException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { /* test */ @@ -222,7 +224,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { } @Test - public void findAll_onlyNonPersisted_succeeds() throws SQLException, QueryNotFoundException, NotAllowedException, + public void findAll_onlyNonPersisted_succeeds() throws SQLException, QueryNotFoundException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { /* test */ @@ -233,8 +235,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { @Test public void findById_succeeds() throws SQLException, QueryNotFoundException, UserNotFoundException, - NotAllowedException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, - InterruptedException { + RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { /* test */ findById_generic(QUERY_1_ID); @@ -251,8 +252,8 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { @Test public void persist_succeeds() throws SQLException, QueryStorePersistException, QueryNotFoundException, - UserNotFoundException, NotAllowedException, RemoteUnavailableException, MetadataServiceException, - DatabaseNotFoundException, InterruptedException { + UserNotFoundException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, + InterruptedException { /* mock */ when(metadataServiceGateway.getUserById(QUERY_2_CREATED_BY)) @@ -267,8 +268,8 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { @Test public void persist_unPersist_succeeds() throws SQLException, QueryStorePersistException, QueryNotFoundException, - UserNotFoundException, NotAllowedException, RemoteUnavailableException, MetadataServiceException, - DatabaseNotFoundException, InterruptedException { + UserNotFoundException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, + InterruptedException { /* mock */ when(metadataServiceGateway.getUserById(QUERY_1_CREATED_BY)) @@ -302,8 +303,8 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { @Test public void export_succeeds() throws SQLException, StorageUnavailableException, QueryMalformedException, - SidecarExportException, MetadataServiceException, RemoteUnavailableException, IOException, - StorageNotFoundException, InterruptedException { + RemoteUnavailableException, IOException, StorageNotFoundException, InterruptedException, + AnalyseServiceException, ViewNotFoundException, MalformedException { /* mock */ MariaDbConfig.dropQueryStore(DATABASE_1_PRIVILEGED_DTO); @@ -312,7 +313,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { export_generic(); } - protected void findById_generic(Long queryId) throws NotAllowedException, RemoteUnavailableException, SQLException, + protected void findById_generic(Long queryId) throws RemoteUnavailableException, SQLException, UserNotFoundException, QueryNotFoundException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { @@ -333,7 +334,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { } protected List<QueryDto> findAll_generic(Boolean filterPersisted) throws SQLException, QueryNotFoundException, - NotAllowedException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, + RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { /* pre-condition */ @@ -378,9 +379,9 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { assertEquals(0, response.size()); } - protected void export_generic() throws StorageUnavailableException, SQLException, - QueryMalformedException, SidecarExportException, MetadataServiceException, RemoteUnavailableException, - StorageNotFoundException, IOException, InterruptedException { + protected void export_generic() throws StorageUnavailableException, SQLException, RemoteUnavailableException, + QueryMalformedException, StorageNotFoundException, IOException, InterruptedException, + AnalyseServiceException, ViewNotFoundException, MalformedException { final String filename = RandomStringUtils.randomAlphanumeric(40).toLowerCase() + ".tmp"; EXPORT_RESOURCE_DTO.setFilename(filename); @@ -390,12 +391,12 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { /* mock */ doNothing() .when(dataDatabaseSidecarGateway) - .exportFile(anyString(), anyInt(), eq(filename)); - when(storageService.getResource(anyString())) + .exportTable(anyLong(), anyLong()); + when(storageService.transformDataset(any(Dataset.class))) .thenReturn(EXPORT_RESOURCE_DTO); /* test */ - final ExportResourceDto response = queryService.export(DATABASE_1_PRIVILEGED_DTO, QUERY_1_DTO, Instant.now(), filename); + final ExportResourceDto response = queryService.export(DATABASE_1_PRIVILEGED_DTO, QUERY_1_DTO, Instant.now()); assertEquals(filename, response.getFilename()); assertNotNull(response.getResource().getInputStream()); } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java index 7413b20462..e24af574cb 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java @@ -18,7 +18,7 @@ import at.tuwien.api.database.table.internal.TableCreateDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; +import at.tuwien.gateway.AnalyseServiceGateway; import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; @@ -59,7 +59,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { private MetadataServiceGateway metadataServiceGateway; @MockBean - private DataDatabaseSidecarGateway dataDatabaseSidecarGateway; + private AnalyseServiceGateway dataDatabaseSidecarGateway; @MockBean private StorageService storageService; @@ -675,10 +675,10 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { } @Test - public void getData_succeeds() throws SQLException, TableMalformedException { + public void getPaginatedData_succeeds() throws SQLException, TableMalformedException { /* test */ - final QueryResultDto response = tableService.getData(TABLE_1_PRIVILEGED_DTO, null, 0L, 10L); + final QueryResultDto response = tableService.getPaginatedData(TABLE_1_PRIVILEGED_DTO, null, 0L, 10L); assertEquals(TABLE_1_ID, response.getId()); final List<Map<String, Integer>> headers = response.getHeaders(); assertEquals(5, headers.size()); @@ -706,14 +706,14 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { } @Test - public void getData_notFound_fails() throws SQLException { + public void getPaginatedData_notFound_fails() throws SQLException { /* mock */ MariaDbConfig.createDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_2_INTERNALNAME); /* test */ assertThrows(TableMalformedException.class, () -> { - tableService.getData(TABLE_5_PRIVILEGED_DTO, null, 0L, 10L); + tableService.getPaginatedData(TABLE_5_PRIVILEGED_DTO, null, 0L, 10L); }); } @@ -742,8 +742,9 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { } @Test - public void exportDataset_succeeds() throws SQLException, QueryMalformedException, RemoteUnavailableException, - StorageNotFoundException, StorageUnavailableException, SidecarExportException { + public void exportTable_succeeds() throws QueryMalformedException, RemoteUnavailableException, + StorageNotFoundException, StorageUnavailableException, AnalyseServiceException, TableNotFoundException, + MalformedException { final ExportResourceDto mock = ExportResourceDto.builder() .filename("weather_aus.csv") .resource(new InputStreamResource(InputStream.nullInputStream())) @@ -752,7 +753,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* mock */ doNothing() .when(dataDatabaseSidecarGateway) - .exportFile(anyString(), anyInt(), eq("weather_aus.csv")); + .exportTable(anyLong(), anyLong()); when(storageService.getResource("weather_aus.csv")) .thenReturn(mock); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java index 5f20464eb9..670c9c66a5 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java @@ -105,8 +105,7 @@ public class ViewServiceIntegrationTest extends AbstractUnitTest { } @Test - public void getSchemas_succeeds() throws ViewMalformedException, SQLException, ViewNotFoundException, - DatabaseMalformedException, ViewSchemaException { + public void getSchemas_succeeds() throws SQLException, ViewNotFoundException, DatabaseMalformedException { /* test */ final List<ViewDto> response = viewService.getSchemas(DATABASE_1_PRIVILEGED_DTO); diff --git a/dbrepo-data-service/services/pom.xml b/dbrepo-data-service/services/pom.xml index ab57ee97af..ad3fcee0e0 100644 --- a/dbrepo-data-service/services/pom.xml +++ b/dbrepo-data-service/services/pom.xml @@ -14,11 +14,6 @@ <version>1.4.7</version> <dependencies> - <dependency> - <groupId>software.amazon.awssdk</groupId> - <artifactId>auth</artifactId> - <version>2.25.23</version> - </dependency> <dependency> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service-querystore</artifactId> diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java index 35e55797eb..3140f77cb5 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java @@ -11,7 +11,7 @@ import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -31,7 +31,7 @@ import java.util.Arrays; import java.util.Base64; import java.util.stream.Collectors; -@Slf4j +@Log4j2 public class AuthTokenFilter extends OncePerRequestFilter { @Value("${dbrepo.jwt.public_key}") diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 6ebd674457..4bdb9cb89f 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -19,6 +19,9 @@ public class GatewayConfig { @Value("${dbrepo.endpoints.metadataService}") private String metadataEndpoint; + @Value("${dbrepo.endpoints.analyseService}") + private String analyseEndpoint; + @Value("${dbrepo.system.username}") private String systemUsername; diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/JacksonConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/JacksonConfig.java index d6a30b5250..94acf727d5 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/JacksonConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/JacksonConfig.java @@ -5,13 +5,13 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.hibernate6.Hibernate6Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.TimeZone; -@Slf4j +@Log4j2 @Configuration public class JacksonConfig { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java index 55888bda1a..b636391170 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java @@ -13,13 +13,4 @@ public class QueryConfig { @Value("${dbrepo.sql.forbidden}") private String[] forbiddenKeywords; - @Value("${dbrepo.defaultDateFormatId}") - private Long defaultDateFormatId; - - @Value("${dbrepo.defaultTimeFormatId}") - private Long defaultTimeFormatId; - - @Value("${dbrepo.defaultTimestampFormatId}") - private Long defaultTimestampFormatId; - } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/S3Config.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/S3Config.java index 10630c717f..c5aeb968d5 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/S3Config.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/S3Config.java @@ -1,7 +1,7 @@ package at.tuwien.config; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; +import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -13,7 +13,7 @@ import software.amazon.awssdk.services.s3.S3Client; import java.net.URI; -@Slf4j +@Log4j2 @Getter @Configuration public class S3Config { @@ -30,9 +30,6 @@ public class S3Config { @Value("${dbrepo.s3.bucket}") private String s3Bucket; - @Value("${dbrepo.s3.filePath}") - private String s3FilePath; - @Bean public S3Client s3client() { final AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/SparkConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/SparkConfig.java new file mode 100644 index 0000000000..2a5ea780ba --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/SparkConfig.java @@ -0,0 +1,71 @@ +package at.tuwien.config; + +import lombok.Getter; +import lombok.extern.log4j.Log4j2; +import org.apache.spark.SparkConf; +import org.apache.spark.sql.SparkSession; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.LinkedHashMap; +import java.util.Map; + +@Log4j2 +@Getter +@Configuration +public class SparkConfig { + + @Value("${dbrepo.endpoints.computeService}") + private String computeEndpoint; + + @Value("${dbrepo.endpoints.storageService}") + private String s3Endpoint; + + @Value("${dbrepo.s3.accessKeyId}") + private String s3AccessKeyId; + + @Value("${dbrepo.s3.secretAccessKey}") + private String s3SecretAccessKey; + + @Bean + public Map<String, String> sparkOptions() { + return new LinkedHashMap<>() {{ + put("spark.driver.extraJavaOptions", "-Divy.cache.dir=/tmp -Divy.home=/tmp"); + put("spark.ui.enabled", "false"); + }}; + } + + @Bean + public Map<String, String> hadoopOptions() { + return new LinkedHashMap<>() {{ + put("fs.s3a.path.style.access", "true"); + put("fs.s3a.endpoint", s3Endpoint); + put("fs.s3a.access.key", s3AccessKeyId); + put("fs.s3a.secret.key", s3SecretAccessKey); + }}; + } + + @Bean + public SparkConf sparkConf() { + final SparkConf config = new SparkConf() + .setMaster(computeEndpoint) + .setAppName("dbrepo-data-service"); + sparkOptions() + .forEach(config::set); + return config; + } + + @Bean + public SparkSession sparkSession() { + final SparkSession spark = SparkSession.builder() + .config(sparkConf()) + .getOrCreate(); + hadoopOptions() + .forEach((key, value) -> spark.sparkContext() + .hadoopConfiguration() + .set(key, value)); + return spark; + } + +} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/AnalyseServiceGateway.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/AnalyseServiceGateway.java new file mode 100644 index 0000000000..0257f0b2c7 --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/AnalyseServiceGateway.java @@ -0,0 +1,31 @@ +package at.tuwien.gateway; + +import at.tuwien.exception.*; + +public interface AnalyseServiceGateway { + + /** + * Imports a given dataset name into the given database. + * + * @param databaseId The database id. + * @param tableId The table id. + * @param filename The dataset name. + * @throws StorageNotFoundException The dataset name was not found in the storage service. + * @throws RemoteUnavailableException Connection to the sidecar could not be established. + * @throws AnalyseServiceException The analyse service failed to import the dataset. + */ + void importDataset(Long databaseId, Long tableId, String filename) throws StorageNotFoundException, + RemoteUnavailableException, AnalyseServiceException; + + /** + * Exports a given dataset name from the given database. + * + * @param databaseId The database id. + * @param tableId The table id. + * @throws StorageNotFoundException The dataset name was not found in the storage service. + * @throws RemoteUnavailableException Connection to the sidecar could not be established. + * @throws AnalyseServiceException The analyse service failed to export the dataset. + */ + void exportTable(Long databaseId, Long tableId) throws StorageNotFoundException, + RemoteUnavailableException, AnalyseServiceException; +} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/DataDatabaseSidecarGateway.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/DataDatabaseSidecarGateway.java deleted file mode 100644 index 23dc08a55d..0000000000 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/DataDatabaseSidecarGateway.java +++ /dev/null @@ -1,30 +0,0 @@ -package at.tuwien.gateway; - -import at.tuwien.exception.*; - -public interface DataDatabaseSidecarGateway { - - /** - * Imports a given dataset name into the given database. - * @param hostname The database hostname. - * @param port The database port. - * @param filename The dataset name. - * @throws StorageNotFoundException The dataset name was not found in the storage service. - * @throws RemoteUnavailableException Connection to the sidecar could not be established. - * @throws SidecarImportException The sidecar failed to import the dataset. - */ - void importFile(String hostname, Integer port, String filename) throws StorageNotFoundException, - RemoteUnavailableException, SidecarImportException; - - /** - * Exports a given dataset name from the given database. - * @param hostname The database hostname. - * @param port The database port. - * @param filename The dataset name. - * @throws StorageNotFoundException The dataset name was not found in the storage service. - * @throws RemoteUnavailableException Connection to the sidecar could not be established. - * @throws SidecarExportException The sidecar failed to export the dataset. - */ - void exportFile(String hostname, Integer port, String filename) throws StorageNotFoundException, - SidecarExportException, RemoteUnavailableException; -} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/AnalyseServiceGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/AnalyseServiceGatewayImpl.java new file mode 100644 index 0000000000..2ab9d0a018 --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/AnalyseServiceGatewayImpl.java @@ -0,0 +1,85 @@ +package at.tuwien.gateway.impl; + +import at.tuwien.config.GatewayConfig; +import at.tuwien.exception.AnalyseServiceException; +import at.tuwien.exception.RemoteUnavailableException; +import at.tuwien.exception.StorageNotFoundException; +import at.tuwien.gateway.AnalyseServiceGateway; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestTemplate; + +@Log4j2 +@Service +public class AnalyseServiceGatewayImpl implements AnalyseServiceGateway { + + private final RestTemplate restTemplate; + private final GatewayConfig gatewayConfig; + + @Autowired + public AnalyseServiceGatewayImpl(RestTemplate restTemplate, GatewayConfig gatewayConfig) { + this.restTemplate = restTemplate; + this.gatewayConfig = gatewayConfig; + } + + @Override + public void importDataset(Long databaseId, Long tableId, String filename) throws StorageNotFoundException, + RemoteUnavailableException, AnalyseServiceException { + final ResponseEntity<Void> response; + final String url = new StringBuilder(gatewayConfig.getAnalyseEndpoint()) + .append("/api/analyse/import?database_id=") + .append(databaseId) + .append("&table_id=") + .append(tableId) + .append("&filename=") + .append(filename) + .toString(); + log.debug("import file into data database: {}", url); + try { + response = restTemplate.exchange(url, HttpMethod.POST, HttpEntity.EMPTY, Void.class); + } catch (HttpServerErrorException e) { + log.error("Failed to import dataset with filename: {}: {}", filename, e.getMessage()); + throw new RemoteUnavailableException("Failed to import dataset: " + e.getMessage(), e); + } catch (HttpClientErrorException.BadRequest e) { + log.error("Failed to import dataset with filename: {}: not found: {}", filename, e.getMessage()); + throw new StorageNotFoundException("Failed to import dataset: not found: " + e.getMessage(), e); + } + if (!response.getStatusCode().equals(HttpStatus.ACCEPTED)) { + log.error("Failed to import dataset with filename: {}: service responded unsuccessful: {}", filename, response.getStatusCode()); + throw new AnalyseServiceException("Failed to import dataset: service responded unsuccessful: " + response.getStatusCode()); + } + } + + @Override + public void exportTable(Long databaseId, Long tableId) throws StorageNotFoundException, RemoteUnavailableException, + AnalyseServiceException { + final ResponseEntity<Void> response; + final String url = new StringBuilder(gatewayConfig.getAnalyseEndpoint()) + .append("/api/analyse/export?database_id=") + .append(databaseId) + .append("&table_id=") + .append(tableId) + .toString(); + log.debug("export file from data database: {}", url); + try { + response = restTemplate.exchange(url, HttpMethod.POST, HttpEntity.EMPTY, Void.class); + } catch (HttpServerErrorException e) { + log.error("Failed to export dataset: {}", e.getMessage()); + throw new RemoteUnavailableException("Failed to export dataset: " + e.getMessage(), e); + } catch (HttpClientErrorException.BadRequest e) { + log.error("Failed to export dataset: not found: {}", e.getMessage()); + throw new StorageNotFoundException("Failed to export dataset: not found: " + e.getMessage(), e); + } + if (!response.getStatusCode().equals(HttpStatus.ACCEPTED)) { + log.error("Failed to export dataset: service responded unsuccessful: {}", response.getStatusCode()); + throw new AnalyseServiceException("Failed to export dataset: service responded unsuccessful: " + response.getStatusCode()); + } + } +} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/DataDatabaseSidecarGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/DataDatabaseSidecarGatewayImpl.java deleted file mode 100644 index 841aace474..0000000000 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/DataDatabaseSidecarGatewayImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package at.tuwien.gateway.impl; - -import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.*; -import org.springframework.stereotype.Service; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.ResourceAccessException; -import org.springframework.web.client.RestTemplate; - -@Slf4j -@Service -public class DataDatabaseSidecarGatewayImpl implements DataDatabaseSidecarGateway { - - private final RestTemplate restTemplate; - - @Autowired - public DataDatabaseSidecarGatewayImpl(RestTemplate restTemplate) { - this.restTemplate = restTemplate; - } - - @Override - public void importFile(String hostname, Integer port, String filename) throws StorageNotFoundException, - RemoteUnavailableException, SidecarImportException { - final ResponseEntity<Void> response; - final String url = "http://" + hostname + ":" + port + "/sidecar/import/" + filename; - log.debug("import file into data database sidecar"); - try { - response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(null), Void.class); - } catch (HttpServerErrorException e) { - log.error("Failed to import dataset with filename: {}: {}", filename, e.getMessage()); - throw new RemoteUnavailableException("Failed to import dataset: " + e.getMessage(), e); - } catch (HttpClientErrorException.BadRequest e) { - log.error("Failed to import dataset with filename: {}: not found: {}", filename, e.getMessage()); - throw new StorageNotFoundException("Failed to import dataset: not found: " + e.getMessage(), e); - } - if (!response.getStatusCode().equals(HttpStatus.ACCEPTED)) { - log.error("Failed to import dataset with filename: {}: service responded unsuccessful: {}", filename, response.getStatusCode()); - throw new SidecarImportException("Failed to import dataset: service responded unsuccessful: " + response.getStatusCode()); - } - } - - @Override - public void exportFile(String hostname, Integer port, String filename) throws StorageNotFoundException, - RemoteUnavailableException, SidecarExportException { - final ResponseEntity<Void> response; - final String url = "http://" + hostname + ":" + port + "/sidecar/export/" + filename; - log.debug("export file from data database sidecar: {}", url); - try { - response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(null), Void.class); - } catch (HttpServerErrorException e) { - log.error("Failed to export dataset with filename: {}: {}", filename, e.getMessage()); - throw new RemoteUnavailableException("Failed to export dataset: " + e.getMessage(), e); - } catch (HttpClientErrorException.BadRequest e) { - log.error("Failed to export dataset with filename: {}: not found: {}", filename, e.getMessage()); - throw new StorageNotFoundException("Failed to export dataset: not found: " + e.getMessage(), e); - } - if (!response.getStatusCode().equals(HttpStatus.ACCEPTED)) { - log.error("Failed to export dataset with filename: {}: service responded unsuccessful: {}", filename, response.getStatusCode()); - throw new SidecarExportException("Failed to export dataset: service responded unsuccessful: " + response.getStatusCode()); - } - } -} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java index 1d73f6219a..fe1b2e3611 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java @@ -61,10 +61,10 @@ public class KeycloakGatewayImpl implements KeycloakGateway { throw new AuthServiceConnectionException("Failed to obtain user token: " + e.getMessage(), e); } catch (HttpClientErrorException.BadRequest e) { if (e.getResponseBodyAsByteArray() != null && e.getResponseBodyAsByteArray().length > 0) { - final KeycloakErrorDto error = e.getResponseBodyAs(KeycloakErrorDto.class); - if (error != null && error.getError().equals("invalid_grant")) { - log.error("Failed to obtain user token: {}", error.getErrorDescription()); - throw new AccountNotSetupException("Failed to obtain user token: " + error.getErrorDescription(), e); + final String error = e.getResponseBodyAsString(); + if (error != null && error.contains("invalid_grant")) { + log.error("Failed to obtain user token: {}", error); + throw new AccountNotSetupException("Failed to obtain user token: " + error, e); } } log.error("Failed to obtain user token: bad request"); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java index 11a90afde7..3c03f022b3 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java @@ -87,8 +87,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { public PrivilegedDatabaseDto getDatabaseById(Long id) throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException { final ResponseEntity<PrivilegedDatabaseDto> response; + final String url = "/api/database/" + id; + log.debug("find privileged database from url: {}", url); try { - response = restTemplate.exchange("/api/database/" + id, HttpMethod.GET, HttpEntity.EMPTY, + response = restTemplate.exchange(url, HttpMethod.GET, HttpEntity.EMPTY, PrivilegedDatabaseDto.class); } catch (ResourceAccessException | HttpServerErrorException e) { log.error("Failed to find database with id {}: {}", id, e.getMessage()); @@ -123,8 +125,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { public PrivilegedDatabaseDto getDatabaseByInternalName(String internalName) throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException { final ResponseEntity<PrivilegedDatabaseDto[]> response; + final String url = "/api/database/"; + log.debug("find privileged database from url: {}", url); try { - response = restTemplate.exchange("/api/database/", HttpMethod.GET, HttpEntity.EMPTY, PrivilegedDatabaseDto[].class); + response = restTemplate.exchange(url, HttpMethod.GET, HttpEntity.EMPTY, PrivilegedDatabaseDto[].class); } catch (ResourceAccessException | HttpServerErrorException e) { log.error("Failed to find database with internal name {}: {}", internalName, e.getMessage()); throw new RemoteUnavailableException("Failed to find database: " + e.getMessage(), e); @@ -152,8 +156,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { public PrivilegedTableDto getTableById(Long databaseId, Long id) throws TableNotFoundException, RemoteUnavailableException, MetadataServiceException { final ResponseEntity<TableDto> response; + final String url = "/api/database/" + databaseId + "/table/" + id; + log.debug("find privileged table from url: {}", url); try { - response = restTemplate.exchange("/api/database/" + databaseId + "/table/" + id, HttpMethod.GET, HttpEntity.EMPTY, TableDto.class); + response = restTemplate.exchange(url, HttpMethod.GET, HttpEntity.EMPTY, TableDto.class); } catch (ResourceAccessException | HttpServerErrorException e) { log.error("Failed to find table with id {}: {}", id, e.getMessage()); throw new RemoteUnavailableException("Failed to find table: " + e.getMessage(), e); @@ -165,7 +171,7 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find table with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find table: service responded unsuccessful: " + response.getStatusCode()); } - final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database", "X-Sidecar-Host", "X-Sidecar-Port"); + final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database", "X-Table"); if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged table headers"); log.debug("expected headers: {}", expectedHeaders); @@ -183,8 +189,7 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { table.getDatabase().getContainer().setUsername(response.getHeaders().get("X-Username").get(0)); table.getDatabase().getContainer().setPassword(response.getHeaders().get("X-Password").get(0)); table.getDatabase().setInternalName(response.getHeaders().get("X-Database").get(0)); - table.getDatabase().getContainer().setSidecarHost(response.getHeaders().get("X-Sidecar-Host").get(0)); - table.getDatabase().getContainer().setSidecarPort(Integer.parseInt(response.getHeaders().get("X-Sidecar-Port").get(0))); + table.setInternalName(response.getHeaders().get("X-Table").get(0)); log.debug("found privileged database username={}", table.getDatabase().getContainer().getUsername()); return table; } @@ -193,8 +198,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { public PrivilegedViewDto getViewById(Long databaseId, Long id) throws RemoteUnavailableException, ViewNotFoundException, MetadataServiceException { final ResponseEntity<ViewDto> response; + final String url = "/api/database/" + databaseId + "/view/" + id; + log.debug("find privileged view from url: {}", url); try { - response = restTemplate.exchange("/api/database/" + databaseId + "/view/" + id, HttpMethod.GET, HttpEntity.EMPTY, ViewDto.class); + response = restTemplate.exchange(url, HttpMethod.GET, HttpEntity.EMPTY, ViewDto.class); } catch (ResourceAccessException | HttpServerErrorException e) { log.error("Failed to find view with id {}: {}", id, e.getMessage()); throw new RemoteUnavailableException("Failed to find view: " + e.getMessage(), e); @@ -206,7 +213,7 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find view with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find view: service responded unsuccessful: " + response.getStatusCode()); } - final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database"); + final List<String> expectedHeaders = List.of("X-Type", "X-Host", "X-Port", "X-Username", "X-Password", "X-Database", "X-View"); if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { log.error("Failed to find all privileged view headers"); log.debug("expected headers: {}", expectedHeaders); @@ -217,14 +224,15 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find view with id {}: body is empty", id); throw new MetadataServiceException("Failed to find view with id " + id + ": body is empty"); } - final PrivilegedViewDto table = metadataMapper.viewDtoToPrivilegedViewDto(response.getBody()); - table.getDatabase().getContainer().getImage().setJdbcMethod(response.getHeaders().get("X-Type").get(0)); - table.getDatabase().getContainer().setHost(response.getHeaders().get("X-Host").get(0)); - table.getDatabase().getContainer().setPort(Integer.parseInt(response.getHeaders().get("X-Port").get(0))); - table.getDatabase().getContainer().setUsername(response.getHeaders().get("X-Username").get(0)); - table.getDatabase().getContainer().setPassword(response.getHeaders().get("X-Password").get(0)); - table.getDatabase().setInternalName(response.getHeaders().get("X-Database").get(0)); - return table; + final PrivilegedViewDto view = metadataMapper.viewDtoToPrivilegedViewDto(response.getBody()); + view.getDatabase().getContainer().getImage().setJdbcMethod(response.getHeaders().get("X-Type").get(0)); + view.getDatabase().getContainer().setHost(response.getHeaders().get("X-Host").get(0)); + view.getDatabase().getContainer().setPort(Integer.parseInt(response.getHeaders().get("X-Port").get(0))); + view.getDatabase().getContainer().setUsername(response.getHeaders().get("X-Username").get(0)); + view.getDatabase().getContainer().setPassword(response.getHeaders().get("X-Password").get(0)); + view.getDatabase().setInternalName(response.getHeaders().get("X-Database").get(0)); + view.setInternalName(response.getHeaders().get("X-View").get(0)); + return view; } @Override diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java index 62b529976d..ff3ab95a44 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java @@ -1,5 +1,6 @@ package at.tuwien.mapper; +import at.tuwien.ExportResourceDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; @@ -24,23 +25,26 @@ import at.tuwien.api.user.UserDto; import at.tuwien.config.QueryConfig; import at.tuwien.exception.QueryNotFoundException; import at.tuwien.exception.TableNotFoundException; -import com.github.dockerjava.zerodep.shaded.org.apache.commons.codec.binary.Hex; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.*; +import org.apache.hadoop.shaded.com.google.common.hash.Hashing; +import org.apache.hadoop.shaded.org.apache.commons.codec.binary.Hex; +import org.apache.hadoop.shaded.org.apache.commons.io.FileUtils; +import org.apache.spark.Partition; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SaveMode; import org.jetbrains.annotations.NotNull; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; -import org.testcontainers.shaded.com.google.common.hash.Hashing; -import org.testcontainers.shaded.org.apache.commons.io.FileUtils; +import org.springframework.core.io.InputStreamResource; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; +import java.io.*; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.sql.*; diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java index bfca2d923f..8a70a18a77 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java @@ -16,8 +16,10 @@ import org.mapstruct.Named; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.sql.Date; -import java.sql.*; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; import java.text.Normalizer; import java.time.Instant; import java.time.ZoneId; @@ -491,23 +493,14 @@ public interface MariaDbMapper { return "DROP TABLE `" + tableName + "`;"; } - default String tableOrViewToRawExportQuery(String databaseName, String tableOrView, List<ColumnDto> columns, - Instant timestamp, String filePath) { - final StringBuilder statement = new StringBuilder("SELECT "); - int[] idx = new int[]{0}; - columns.forEach(column -> { - statement.append(idx[0] != 0 ? "," : "") - .append("'") - .append(column.getInternalName()) - .append("'"); - idx[0]++; - }); - statement.append(" UNION ALL SELECT "); + default String tableOrViewToRawExportQuery(String databaseName, String tableOrView, List<String> columns, + Instant timestamp) { + final StringBuilder statement = new StringBuilder("(SELECT "); int[] jdx = new int[]{0}; columns.forEach(column -> { statement.append(jdx[0] != 0 ? "," : "") .append("`") - .append(column.getInternalName()) + .append(column) .append("`"); jdx[0]++; }); @@ -522,10 +515,7 @@ public interface MariaDbMapper { .append(mariaDbFormatter.format(timestamp)) .append("'"); } - statement.append(" INTO OUTFILE '") - .append(filePath) - .append("' CHARACTER SET utf8 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';"); - statement.append(";"); + statement.append(") as tbl_alias"); log.debug("mapped table/view export query: {}", statement); return statement.toString(); } @@ -540,50 +530,38 @@ public interface MariaDbMapper { return statement.toString(); } - default String subsetToRawExportQuery(String viewName, Instant timestamp, String filePath) { - final StringBuilder statement = new StringBuilder("SELECT * FROM `") + default String subsetToRawExportQuery(String viewName, Instant timestamp) { + final StringBuilder statement = new StringBuilder("(SELECT * FROM `") .append(viewName) .append("` FOR SYSTEM_TIME AS OF TIMESTAMP'") .append(mariaDbFormatter.format(timestamp)) - .append("'") - .append(" INTO OUTFILE '") - .append(filePath) - .append("' CHARACTER SET utf8 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';"); + .append("') as tbl"); log.debug("mapped export query: {}", statement); return statement.toString(); } - default String datasetToRawInsertQuery(String databaseName, PrivilegedTableDto table, ImportDto data) { - final StringBuilder statement = new StringBuilder("LOAD DATA INFILE '") - .append(data.getLocation()) - .append("' REPLACE INTO TABLE `") - .append(databaseName) + default String temporaryTableToRawMergeQuery(String tmp, String table, List<String> columns) { + final StringBuilder statement = new StringBuilder("INSERT INTO `") + .append(table) + .append("` SELECT * FROM `") + .append(tmp) + .append("` ON DUPLICATE KEY UPDATE "); + final int[] idx = new int[]{0}; + columns.forEach(column -> statement.append(idx[0]++ > 0 ? ", " : "") + .append("`") + .append(table) .append("`.`") - .append(table.getInternalName()) - .append("` CHARACTER SET utf8 FIELDS TERMINATED BY '") - .append(data.getSeparator()) - .append("'"); - if (data.getQuote() != null) { - statement.append(" OPTIONALLY ENCLOSED BY '") - .append(data.getQuote()) - .append("'"); - } - if (data.getLineTermination() != null) { - statement.append(" LINES TERMINATED BY '") - .append(data.getLineTermination()) - .append("'"); - } - if (data.getSkipLines() != null) { - statement.append(" IGNORE ") - .append(data.getSkipLines()) - .append(" LINES"); - } + .append(column) + .append("` = `") + .append(tmp) + .append("`.`") + .append(column) + .append("`")); statement.append(";"); log.trace("mapped insert statement: {}", statement); return statement.toString(); } - default String tupleToRawDeleteQuery(PrivilegedTableDto table, TupleDeleteDto data) throws TableMalformedException { log.trace("table csv to delete query, table.id={}, data.keys={}", table.getId(), data.getKeys()); if (table.getColumns().isEmpty()) { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/StorageService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/StorageService.java index c1f546ce44..b346a187a5 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/StorageService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/StorageService.java @@ -1,10 +1,16 @@ package at.tuwien.service; import at.tuwien.ExportResourceDto; +import at.tuwien.api.database.table.columns.ColumnDto; +import at.tuwien.exception.MalformedException; import at.tuwien.exception.StorageNotFoundException; import at.tuwien.exception.StorageUnavailableException; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import java.io.IOException; import java.io.InputStream; +import java.util.List; public interface StorageService { @@ -59,6 +65,27 @@ public interface StorageService { * @throws StorageUnavailableException The object failed to be loaded from the Storage Service. * @throws StorageNotFoundException The key was not found in the Storage Service. */ - ExportResourceDto getResource(String bucket, String key) throws StorageUnavailableException, StorageNotFoundException; + ExportResourceDto getResource(String bucket, String key) throws StorageUnavailableException, + StorageNotFoundException; + /** + * Transforms the given dataset into a downloadable dataset. + * + * @param data The dataset. + * @throws StorageUnavailableException The object failed to be loaded from the Storage Service. + */ + ExportResourceDto transformDataset(Dataset<Row> data) throws StorageUnavailableException; + + /** + * Loads the dataset from the Storage Service with given key for a list of provided column names. + * + * @param columns The list of column names. + * @param key The key. + * @param withHeader If true, the first line contains the column names, otherwise it contains data only. + * @return The dataset. + * @throws StorageNotFoundException The key was not found in the Storage Service. + * @throws StorageUnavailableException The object failed to be loaded from the Storage Service. + */ + Dataset<Row> loadDataset(List<String> columns, String key, Boolean withHeader) throws StorageNotFoundException, + StorageUnavailableException, MalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java index 56250a2917..938da8820c 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java @@ -7,6 +7,9 @@ import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.exception.*; +import jakarta.validation.constraints.NotNull; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; import java.sql.SQLException; import java.time.Instant; @@ -99,23 +102,21 @@ public interface SubsetService { QueryNotFoundException, RemoteUnavailableException, DatabaseNotFoundException, MetadataServiceException; /** - * Exports a subset by re-executing the query in a given database with given timestamp to a given filename. + * Exports a subset by re-executing the query in a given database with given timestamp to a given s3key. * * @param database The database. * @param query The query. * @param timestamp The timestamp. - * @param filename The filename. * @return The exported subset. * @throws SQLException The connection to the database could not be established. * @throws QueryMalformedException The mapped export query produced a database error. - * @throws SidecarExportException The sidecar of the given database failed to communicate. * @throws StorageNotFoundException The exported subset was not found from the key provided by the sidecar in the Storage Service. * @throws StorageUnavailableException The communication to the Storage Service failed. * @throws RemoteUnavailableException The privileged database information could not be found in the Metadata Service. */ - ExportResourceDto export(PrivilegedDatabaseDto database, QueryDto query, Instant timestamp, String filename) - throws SQLException, QueryMalformedException, SidecarExportException, StorageNotFoundException, - StorageUnavailableException, RemoteUnavailableException; + ExportResourceDto export(PrivilegedDatabaseDto database, QueryDto query, Instant timestamp) throws SQLException, + QueryMalformedException, StorageNotFoundException, StorageUnavailableException, RemoteUnavailableException, + ViewNotFoundException, MalformedException; /** * Executes a subset query without saving it. @@ -180,4 +181,7 @@ public interface SubsetService { * @throws QueryStoreGCException The query store failed to delete stale queries. */ void deleteStaleQueries(PrivilegedDatabaseDto database) throws SQLException, QueryStoreGCException; + + Dataset<Row> getData(@NotNull PrivilegedDatabaseDto database, String viewName, Instant timestamp) throws ViewNotFoundException, + QueryMalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java index c93186f451..c70d1b703f 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java @@ -8,6 +8,9 @@ import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.internal.PrivilegedTableDto; import at.tuwien.api.database.table.internal.TableCreateDto; import at.tuwien.exception.*; +import jakarta.validation.constraints.NotNull; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; import java.sql.SQLException; import java.time.Instant; @@ -17,10 +20,11 @@ public interface TableService { /** * Get table schemas from the information_schema in the data database. + * * @param database The data database privileged object. * @return List of tables, if successful. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. - * @throws TableNotFoundException The table could not be inspected in the data database. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws TableNotFoundException The table could not be inspected in the data database. * @throws DatabaseMalformedException The database inspection was unsuccessful, likely due to a bug in the mapping. */ List<TableDto> getSchemas(PrivilegedDatabaseDto database) throws SQLException, TableNotFoundException, @@ -28,22 +32,24 @@ public interface TableService { /** * Generate table statistic for a given table. Only numerical columns are calculated. + * * @param table The table. * @return The table statistic, if successful. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableMalformedException The table statistic generation was unsuccessful, likely due to a bug in the mapping. - * @throws TableNotFoundException The table could not be inspected in the data database. + * @throws TableNotFoundException The table could not be inspected in the data database. */ TableStatisticDto getStatistics(PrivilegedTableDto table) throws SQLException, TableMalformedException, TableNotFoundException; /** * Finds a table with given data database and table name. - * @param database The data database. + * + * @param database The data database. * @param tableName The table name. * @return The table, if successful. - * @throws TableNotFoundException The table could not be inspected in the data database. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws TableNotFoundException The table could not be inspected in the data database. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The inspection query is malformed. */ TableDto find(PrivilegedDatabaseDto database, String tableName) throws TableNotFoundException, SQLException, @@ -51,12 +57,13 @@ public interface TableService { /** * Creates a table in given data database with table definition. + * * @param database The data database privileged object. - * @param data The table definition. + * @param data The table definition. * @return The created table, if successful. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableNotFoundException The table could not be inspected in the data database. - * @throws TableExistsException The table name already exists in the information_schema. + * @throws TableExistsException The table name already exists in the information_schema. * @throws TableNotFoundException The table could not be inspected in the data database. */ TableDto createTable(PrivilegedDatabaseDto database, TableCreateDto data) throws SQLException, @@ -64,64 +71,71 @@ public interface TableService { /** * Drops a table in given table object. + * * @param table The table object. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The drop table query is malformed. */ void delete(PrivilegedTableDto table) throws SQLException, QueryMalformedException; /** * Obtains data from a table with given table object at timestamp, loaded as page number and length size. - * @param table The table object. + * + * @param table The table object. * @param timestamp The timestamp. - * @param page The page number. - * @param size The page size/length. + * @param page The page number. + * @param size The page size/length. * @return The data. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableMalformedException The table schema is malformed, likely due to a bug in the application. */ - QueryResultDto getData(PrivilegedTableDto table, Instant timestamp, Long page, Long size) throws SQLException, - TableMalformedException; + QueryResultDto getPaginatedData(PrivilegedTableDto table, Instant timestamp, Long page, Long size) + throws SQLException, TableMalformedException; /** * Obtains the table history for a given table object. + * * @param table The table object. - * @param size The maximum size. + * @param size The maximum size. * @return The table history. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableNotFoundException The table could not be found in the data database. */ List<TableHistoryDto> history(PrivilegedTableDto table, Long size) throws SQLException, TableNotFoundException; /** * Obtains the table data tuples count at time. - * @param table The table object. + * + * @param table The table object. * @param timestamp The timestamp. * @return Number of tuples, if successful. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The count query is malformed, likely due to a bug in the application. */ Long getCount(PrivilegedTableDto table, Instant timestamp) throws SQLException, QueryMalformedException; /** - * Imports a dataset by metadata into the sidecar of the target database by given table. + * Imports a dataset into the database by given table. By default, an <code>upsert</code> operation is performed + * that updates duplicate values (identified by their primary key) or inserts values if no duplicate is detected. + * * @param table The table. - * @param data The dataset metadata. - * @throws SidecarImportException The sidecar of the target database failed to import the dataset. - * @throws StorageNotFoundException The storage service was not able to find the dataset for import. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. - * @throws QueryMalformedException The import query is malformed, likely due to a bug in the application. - * @throws RemoteUnavailableException Failed to establish connection to the sidecar. + * @param data The dataset metadata. + * @throws MalformedException The dataset is malformed. + * @throws StorageUnavailableException Failed to establish a connection with the Storage Service. + * @throws StorageNotFoundException The storage service was not able to find the dataset for import. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws QueryMalformedException The import query is malformed, likely due to a bug in the application. */ - void importDataset(PrivilegedTableDto table, ImportDto data) throws SidecarImportException, - StorageNotFoundException, SQLException, QueryMalformedException, RemoteUnavailableException; + void importDataset(PrivilegedTableDto table, ImportDto data) throws MalformedException, StorageNotFoundException, + StorageUnavailableException, SQLException, QueryMalformedException; /** * Imports a dataset by metadata into the sidecar of the target database by given table. + * * @param table The table. - * @param data The dataset metadata. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @param data The dataset metadata. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableMalformedException The tuple is malformed and does not fit the table schema. * @throws QueryMalformedException The delete query is malformed, likely due to a bug in the application. */ @@ -130,41 +144,52 @@ public interface TableService { /** * Creates a tuple in a table. + * * @param table The table. - * @param data The tuple. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. - * @throws QueryMalformedException The create query is malformed, likely due to a bug in the application. - * @throws TableMalformedException The tuple is malformed and does not fit the table schema. + * @param data The tuple. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @throws QueryMalformedException The create query is malformed, likely due to a bug in the application. + * @throws TableMalformedException The tuple is malformed and does not fit the table schema. * @throws StorageUnavailableException Failed to establish a connection with the Storage Service. - * @throws StorageNotFoundException The storage service was not able to find the dataset for import. + * @throws StorageNotFoundException The storage service was not able to find the dataset for import. */ void createTuple(PrivilegedTableDto table, TupleDto data) throws SQLException, QueryMalformedException, TableMalformedException, StorageUnavailableException, StorageNotFoundException; /** * Updates a tuple in a table. + * * @param table The table. - * @param data The tuple. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. + * @param data The tuple. + * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The update query is malformed, likely due to a bug in the application. - * @throws TableMalformedException The tuple is malformed and does not fit the table schema. + * @throws TableMalformedException The tuple is malformed and does not fit the table schema. */ void updateTuple(PrivilegedTableDto table, TupleUpdateDto data) throws SQLException, QueryMalformedException, TableMalformedException; /** * Exports a table at given system-versioning time. - * @param table The table. + * + * @param table The table. * @param timestamp The system-versioning time. * @return The exported resource. - * @throws SQLException Failed to parse SQL query, contains invalid syntax. - * @throws SidecarExportException The sidecar of the target database failed to export the dataset. - * @throws StorageNotFoundException The storage service was not able to find the dataset for export. + * @throws TableNotFoundException The table was not found in the data database. + * @throws QueryMalformedException The export query is malformed, likely due to a bug in the application. * @throws StorageUnavailableException Failed to establish a connection with the Storage Service. + */ + ExportResourceDto exportDataset(PrivilegedTableDto table, Instant timestamp) throws TableNotFoundException, + QueryMalformedException, StorageUnavailableException, MalformedException; + + /** + * Get data from a given table at timestamp. + * + * @param table The table. + * @param timestamp The timestamp. + * @return The data. + * @throws TableNotFoundException The table was not found in the data database. * @throws QueryMalformedException The export query is malformed, likely due to a bug in the application. - * @throws RemoteUnavailableException Failed to establish connection to the sidecar. */ - ExportResourceDto exportDataset(PrivilegedTableDto table, Instant timestamp) - throws SQLException, SidecarExportException, StorageNotFoundException, StorageUnavailableException, - QueryMalformedException, RemoteUnavailableException; + Dataset<Row> getData(@NotNull PrivilegedTableDto table, Instant timestamp) throws TableNotFoundException, + QueryMalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java index 9151f868de..26c04e401b 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java @@ -6,7 +6,11 @@ import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.internal.PrivilegedViewDto; import at.tuwien.api.database.query.QueryResultDto; +import at.tuwien.api.database.table.internal.PrivilegedTableDto; import at.tuwien.exception.*; +import jakarta.validation.constraints.NotNull; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; import java.sql.SQLException; import java.time.Instant; @@ -16,11 +20,12 @@ public interface ViewService { /** * Gets the metadata schema for a given database. + * * @param database The database. * @return The list of view metadata. - * @throws SQLException The connection to the data database was unsuccessful. + * @throws SQLException The connection to the data database was unsuccessful. * @throws DatabaseMalformedException The columns that are referenced in the views are unknown to the Metadata Database. Call {@link TableService#getSchemas(PrivilegedDatabaseDto)} beforehand. - * @throws ViewNotFoundException The view with given name was not found. + * @throws ViewNotFoundException The view with given name was not found. */ List<ViewDto> getSchemas(PrivilegedDatabaseDto database) throws SQLException, DatabaseMalformedException, ViewNotFoundException; @@ -52,33 +57,44 @@ public interface ViewService { /** * Deletes a view. + * * @param view The view. - * @throws SQLException The connection to the data database was unsuccessful. + * @throws SQLException The connection to the data database was unsuccessful. * @throws ViewMalformedException The query is malformed and was rejected by the data database. */ void delete(PrivilegedViewDto view) throws SQLException, ViewMalformedException; /** * Counts tuples in a view at system-versioned timestamp. - * @param view The view. + * + * @param view The view. * @param timestamp The system-versioned timestamp. * @return The number of tuples. - * @throws SQLException The connection to the data database was unsuccessful. + * @throws SQLException The connection to the data database was unsuccessful. * @throws QueryMalformedException The query is malformed and was rejected by the data database. */ Long count(PrivilegedViewDto view, Instant timestamp) throws SQLException, QueryMalformedException; /** * Exports view data into a dataset. + * * @param view The view. * @return The dataset. - * @throws SQLException The connection to the data database was unsuccessful. - * @throws QueryMalformedException The query is malformed and was rejected by the data database. - * @throws SidecarExportException The sidecar of the target database failed to export the dataset. - * @throws RemoteUnavailableException Failed to establish connection to the sidecar. - * @throws StorageNotFoundException The storage service was not able to find the dataset for export. + * @throws QueryMalformedException The query is malformed and was rejected by the data database. * @throws StorageUnavailableException Failed to establish a connection with the Storage Service. + * @throws ViewNotFoundException The view with given name was not found. + */ + ExportResourceDto exportDataset(PrivilegedViewDto view) throws QueryMalformedException, + StorageUnavailableException, ViewNotFoundException, MalformedException; + + /** + * Get data from a given view. + * + * @param view The view. + * @return The data. + * @throws ViewNotFoundException The view with given name was not found. + * @throws QueryMalformedException The query is malformed and was rejected by the data database. */ - ExportResourceDto exportDataset(PrivilegedViewDto view) throws SQLException, QueryMalformedException, - SidecarExportException, RemoteUnavailableException, StorageNotFoundException, StorageUnavailableException; + Dataset<Row> getData(@NotNull PrivilegedViewDto view) throws ViewNotFoundException, + QueryMalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java index 22bb599c60..e2d085ae98 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java @@ -3,15 +3,30 @@ package at.tuwien.service.impl; import at.tuwien.api.container.internal.PrivilegedContainerDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.table.internal.PrivilegedTableDto; +import at.tuwien.config.S3Config; +import at.tuwien.exception.QueryMalformedException; +import at.tuwien.exception.TableNotFoundException; import com.mchange.v2.c3p0.ComboPooledDataSource; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; +import org.apache.spark.SparkConf; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SparkSession; +import org.apache.spark.sql.catalyst.ExtendedAnalysisException; +import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + @Log4j2 @Service public abstract class HibernateConnector { - public static ComboPooledDataSource getPrivilegedDataSource(PrivilegedContainerDto container, String databaseName) { + public ComboPooledDataSource getPrivilegedDataSource(PrivilegedContainerDto container, String databaseName) { final long start = System.currentTimeMillis(); final ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl(url(container, databaseName)); @@ -26,11 +41,35 @@ public abstract class HibernateConnector { return dataSource; } - public static ComboPooledDataSource getPrivilegedDataSource(PrivilegedDatabaseDto database) { + public ComboPooledDataSource getPrivilegedDataSource(PrivilegedDatabaseDto database) { return getPrivilegedDataSource(database.getContainer(), database.getInternalName()); } - private static String url(PrivilegedContainerDto container, String databaseName) { + public Map<String, String> getPrivilegedDatabaseOptions(PrivilegedTableDto table) { + return new HashMap<>() {{ + put("url", url(table.getDatabase().getContainer(), table.getDatabase().getInternalName())); + put("dbtable", table.getInternalName()); + put("user", table.getDatabase().getContainer().getUsername()); + put("password", table.getDatabase().getContainer().getPassword()); + }}; + } + + public String getHibernateUrl(PrivilegedContainerDto container, String databaseName) { + final StringBuilder sb = new StringBuilder(url(container, databaseName)) + .append("?currentSchema=") + .append(databaseName); + log.trace("mapped container to hibernate url: {}", sb.toString()); + return sb.toString(); + } + + public String getSparkUrl(PrivilegedContainerDto container, String databaseName) { + final StringBuilder sb = new StringBuilder(url(container, databaseName)) + .append("?sessionVariables=sql_mode='ANSI_QUOTES'"); + log.trace("mapped container to spark url: {}", sb.toString()); + return sb.toString(); + } + + private String url(PrivilegedContainerDto container, String databaseName) { final StringBuilder stringBuilder = new StringBuilder("jdbc:") .append(container.getImage().getJdbcMethod()) .append("://") @@ -39,8 +78,6 @@ public abstract class HibernateConnector { .append(container.getPort()); if (databaseName != null) { stringBuilder.append("/") - .append(databaseName) - .append("?currentSchema=") .append(databaseName); } return stringBuilder.toString(); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java index 9a748d96dc..a3bcaed578 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java @@ -2,18 +2,29 @@ package at.tuwien.service.impl; import at.tuwien.ExportResourceDto; import at.tuwien.config.S3Config; +import at.tuwien.exception.MalformedException; import at.tuwien.exception.StorageNotFoundException; import at.tuwien.exception.StorageUnavailableException; import at.tuwien.service.StorageService; import lombok.extern.log4j.Log4j2; +import org.apache.spark.sql.*; +import org.apache.spark.sql.types.StructField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.stereotype.Service; import software.amazon.awssdk.services.s3.S3Client; -import software.amazon.awssdk.services.s3.model.*; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.NoSuchKeyException; +import software.amazon.awssdk.services.s3.model.S3Exception; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static scala.collection.JavaConverters.asScalaIteratorConverter; @Log4j2 @Service @@ -21,11 +32,13 @@ public class StorageServiceS3Impl implements StorageService { private final S3Config s3Config; private final S3Client s3Client; + private final SparkSession sparkSession; @Autowired - public StorageServiceS3Impl(S3Config s3Config, S3Client s3Client) { + public StorageServiceS3Impl(S3Config s3Config, S3Client s3Client, SparkSession sparkSession) { this.s3Config = s3Config; this.s3Client = s3Client; + this.sparkSession = sparkSession; } @Override @@ -76,4 +89,87 @@ public class StorageServiceS3Impl implements StorageService { .filename(key) .build(); } + + @Override + public ExportResourceDto transformDataset(Dataset<Row> dataset) throws StorageUnavailableException { + final List<Map<String, String>> inMemory = dataset.collectAsList() + .stream() + .map(row -> { + final Map<String, String> map = new LinkedHashMap<>(); + for (int i = 0; i < dataset.columns().length; i++) { + map.put(dataset.columns()[i], row.get(i) != null ? String.valueOf(row.get(i)) : ""); + } + return map; + }) + .toList(); + log.debug("collected dataset with {} row(s)", inMemory.size()); + try { + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try (Writer w = new OutputStreamWriter(byteArrayOutputStream, Charset.defaultCharset())) { + /* header */ + w.write(String.join(",", Arrays.stream(dataset.schema().fields()).map(StructField::name).toList())); + w.write("\n"); + /* rows */ + for (Map<String, String> map : inMemory) { + w.write(String.join(",", map.values().stream().map(v -> { + if (v.contains(",")) { + v = "\"" + v + "\""; + } + return v; + }) + .toList())); + w.write("\n"); + } + w.flush(); + } + return ExportResourceDto.builder() + .filename("dataset.csv") + .resource(new InputStreamResource(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) + .build(); + } catch (IOException e) { + log.error("Failed to transform in-memory dataset: {}", e.getMessage()); + throw new StorageUnavailableException("Failed to transform in-memory dataset: " + e.getMessage(), e); + } + } + + @Override + public Dataset<Row> loadDataset(List<String> columns, String key, Boolean withHeader) throws StorageNotFoundException, + StorageUnavailableException, MalformedException { + final String path = "s3a://" + s3Config.getS3Bucket() + "/" + key; + log.debug("read dataset from s3 path: {} using header: {}", path, withHeader); + Dataset<Row> dataset; + try { + log.trace("spark session conf: {}", sparkSession.conf().getAllAsJava()); + dataset = sparkSession.read() + .option("header", withHeader) + .csv(path); + } catch (Exception e) { + if (e instanceof AnalysisException) { + final AnalysisException exception = (AnalysisException) e; + if (exception.getSimpleMessage().contains("PATH_NOT_FOUND")) { + log.error("Failed to find dataset {} in storage service: {}", key, e.getMessage()); + throw new StorageNotFoundException("Failed to find dataset in storage service: " + e.getMessage()); + } + } + log.error("Failed to connect to storage service: {}", e.getMessage()); + throw new StorageUnavailableException("Failed to connect to storage service: " + e.getMessage()); + } + if (!withHeader) { + log.debug("no header provided: use table column names: {}", columns); + dataset = dataset.toDF(asScalaIteratorConverter(columns.iterator()) + .asScala() + .toSeq()); + } + /* determine header order in dataset */ + if (dataset.schema().fields().length != columns.size()) { + log.error("Failed to transform dataset: field length {} and header length arrays differ {}", dataset.schema().fields().length, columns.size()); + throw new MalformedException("Failed to transform dataset: field length and order length arrays differ"); + } + /* reorder */ + final List<Column> columnOrder = columns.stream() + .map(Column::new) + .toList(); + log.trace("ordered columns: {}", columnOrder); + return dataset.select(columnOrder.toArray(new Column[0])); + } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java index 8bfdc0089a..55f513f339 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java @@ -3,6 +3,7 @@ package at.tuwien.service.impl; import at.tuwien.ExportResourceDto; import at.tuwien.api.SortTypeDto; import at.tuwien.api.container.internal.PrivilegedContainerDto; +import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryResultDto; @@ -10,29 +11,35 @@ import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.api.identifier.IdentifierDto; import at.tuwien.api.identifier.IdentifierTypeDto; import at.tuwien.api.user.UserDto; -import at.tuwien.config.S3Config; +import at.tuwien.config.SparkConfig; import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.mapper.DataMapper; import at.tuwien.mapper.MariaDbMapper; import at.tuwien.mapper.MetadataMapper; +import at.tuwien.service.SchemaService; import at.tuwien.service.StorageService; import at.tuwien.service.SubsetService; import com.mchange.v2.c3p0.ComboPooledDataSource; import io.micrometer.core.instrument.Counter; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import net.sf.jsqlparser.JSQLParserException; import org.apache.commons.lang3.RandomUtils; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SparkSession; +import org.apache.spark.sql.catalyst.ExtendedAnalysisException; +import org.sparkproject.guava.hash.Hashing; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.testcontainers.shaded.com.google.common.hash.Hashing; import java.nio.charset.Charset; import java.sql.*; import java.time.Instant; import java.util.LinkedList; import java.util.List; +import java.util.Properties; import java.util.UUID; @Log4j2 @@ -40,27 +47,27 @@ import java.util.UUID; public class SubsetServiceMariaDbImpl extends HibernateConnector implements SubsetService { private final Counter httpDataAccessCounter; - private final S3Config s3Config; private final DataMapper dataMapper; + private final SparkSession sparkSession; private final MariaDbMapper mariaDbMapper; + private final SchemaService schemaService; private final MetadataMapper metadataMapper; private final StorageService storageService; private final MetadataServiceGateway metadataServiceGateway; - private final DataDatabaseSidecarGateway dataDatabaseSidecarGateway; @Autowired - public SubsetServiceMariaDbImpl(Counter httpDataAccessCounter, S3Config s3Config, DataMapper dataMapper, - MariaDbMapper mariaDbMapper, MetadataMapper metadataMapper, - StorageService storageService, MetadataServiceGateway metadataServiceGateway, - DataDatabaseSidecarGateway dataDatabaseSidecarGateway) { + public SubsetServiceMariaDbImpl(Counter httpDataAccessCounter, DataMapper dataMapper, SparkSession sparkSession, + MariaDbMapper mariaDbMapper, SchemaService schemaService, + MetadataMapper metadataMapper, StorageService storageService, + MetadataServiceGateway metadataServiceGateway) { this.httpDataAccessCounter = httpDataAccessCounter; - this.s3Config = s3Config; this.dataMapper = dataMapper; + this.sparkSession = sparkSession; this.mariaDbMapper = mariaDbMapper; + this.schemaService = schemaService; this.metadataMapper = metadataMapper; this.storageService = storageService; this.metadataServiceGateway = metadataServiceGateway; - this.dataDatabaseSidecarGateway = dataDatabaseSidecarGateway; } @Override @@ -171,14 +178,14 @@ public class SubsetServiceMariaDbImpl extends HibernateConnector implements Subs } @Override - public ExportResourceDto export(PrivilegedDatabaseDto database, QueryDto query, Instant timestamp, String filename) - throws SQLException, QueryMalformedException, SidecarExportException, StorageNotFoundException, - StorageUnavailableException, RemoteUnavailableException { - final String filePath = s3Config.getS3FilePath() + "/" + filename; + public ExportResourceDto export(PrivilegedDatabaseDto database, QueryDto query, Instant timestamp) + throws SQLException, QueryMalformedException, StorageNotFoundException, StorageUnavailableException, + RemoteUnavailableException, ViewNotFoundException, MalformedException { final String viewName = "ex_" + Hashing.sha512() .hashString(new String(RandomUtils.nextBytes(256), Charset.defaultCharset()), Charset.defaultCharset()) .toString() .substring(0, 60); + final ExportResourceDto export; final ComboPooledDataSource dataSource = getPrivilegedDataSource(database); final Connection connection = dataSource.getConnection(); try { @@ -186,15 +193,23 @@ public class SubsetServiceMariaDbImpl extends HibernateConnector implements Subs long start = System.currentTimeMillis(); connection.prepareStatement(mariaDbMapper.subsetToRawTemporaryViewQuery(viewName, query.getQuery())) .executeUpdate(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); + log.debug("executed create view statement in {} ms", System.currentTimeMillis() - start); start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.subsetToRawExportQuery(viewName, timestamp, filePath)) - .executeUpdate(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); + final List<String> columns = schemaService.inspectView(database, viewName) + .getColumns() + .stream() + .map(ViewColumnDto::getInternalName) + .toList(); + log.debug("executed inspect view columns statement in {} ms", System.currentTimeMillis() - start); + start = System.currentTimeMillis(); + final Dataset<Row> dataset = getData(database, viewName, timestamp) + .selectExpr(columns.toArray(new String[0])); + export = storageService.transformDataset(dataset); + log.debug("executed extract statement in {} ms", System.currentTimeMillis() - start); start = System.currentTimeMillis(); connection.prepareStatement(mariaDbMapper.dropViewRawQuery(viewName)) .executeUpdate(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); + log.debug("executed drop view statement in {} ms", System.currentTimeMillis() - start); connection.commit(); } catch (SQLException e) { connection.rollback(); @@ -203,9 +218,8 @@ public class SubsetServiceMariaDbImpl extends HibernateConnector implements Subs } finally { dataSource.close(); } - dataDatabaseSidecarGateway.exportFile(database.getContainer().getSidecarHost(), database.getContainer().getSidecarPort(), filename); httpDataAccessCounter.increment(); - return storageService.getResource(filename); + return export; } public QueryResultDto executeNonPersistent(PrivilegedDatabaseDto database, String statement, @@ -350,4 +364,27 @@ public class SubsetServiceMariaDbImpl extends HibernateConnector implements Subs } } + @Override + public Dataset<Row> getData(@NotNull PrivilegedDatabaseDto database, String viewName, Instant timestamp) + throws ViewNotFoundException, QueryMalformedException { + log.debug("get data from view: {}", viewName); + try { + final Properties properties = new Properties(); + properties.setProperty("user", database.getContainer().getUsername()); + properties.setProperty("password", database.getContainer().getPassword()); + return sparkSession.read() + .jdbc(getSparkUrl(database.getContainer(), database.getInternalName()), + mariaDbMapper.subsetToRawExportQuery(viewName, timestamp), properties); + } catch (Exception e) { + if (e instanceof ExtendedAnalysisException exception) { + if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) { + log.error("Failed to find temporary view {}: {}", viewName, exception.getSimpleMessage()); + throw new ViewNotFoundException("Failed to find temporary view " + viewName + ": " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */; + } + } + log.error("Failed to find get data from view: {}", e.getMessage()); + throw new QueryMalformedException("Failed to find get data from view: " + e.getMessage(), e); + } + } + } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java index 3ab02bbb01..531897706b 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java @@ -11,8 +11,8 @@ import at.tuwien.api.database.table.columns.ColumnTypeDto; import at.tuwien.api.database.table.internal.PrivilegedTableDto; import at.tuwien.api.database.table.internal.TableCreateDto; import at.tuwien.config.S3Config; +import at.tuwien.config.SparkConfig; import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; import at.tuwien.mapper.DataMapper; import at.tuwien.mapper.MariaDbMapper; import at.tuwien.service.SchemaService; @@ -21,12 +21,16 @@ import at.tuwien.service.TableService; import at.tuwien.utils.MariaDbUtil; import com.mchange.v2.c3p0.ComboPooledDataSource; import io.micrometer.core.instrument.Counter; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.spark.sql.*; +import org.apache.spark.sql.catalyst.ExtendedAnalysisException; +import org.apache.spark.sql.types.StructField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.io.File; +import java.io.ByteArrayInputStream; import java.sql.*; import java.time.Instant; import java.util.*; @@ -36,25 +40,22 @@ import java.util.*; public class TableServiceMariaDbImpl extends HibernateConnector implements TableService { private final Counter httpDataAccessCounter; - private final S3Config s3Config; private final DataMapper dataMapper; + private final SparkSession sparkSession; private final MariaDbMapper mariaDbMapper; private final SchemaService schemaService; private final StorageService storageService; - private final DataDatabaseSidecarGateway dataDatabaseSidecarGateway; @Autowired - public TableServiceMariaDbImpl(Counter httpDataAccessCounter, S3Config s3Config, DataMapper dataMapper, + public TableServiceMariaDbImpl(Counter httpDataAccessCounter, DataMapper dataMapper, SparkSession sparkSession, MariaDbMapper mariaDbMapper, SchemaService schemaService, - StorageService storageService, - DataDatabaseSidecarGateway dataDatabaseSidecarGateway) { + StorageService storageService) { this.httpDataAccessCounter = httpDataAccessCounter; - this.s3Config = s3Config; this.dataMapper = dataMapper; + this.sparkSession = sparkSession; this.mariaDbMapper = mariaDbMapper; this.schemaService = schemaService; this.storageService = storageService; - this.dataDatabaseSidecarGateway = dataDatabaseSidecarGateway; } @Override @@ -190,7 +191,7 @@ public class TableServiceMariaDbImpl extends HibernateConnector implements Table } @Override - public QueryResultDto getData(PrivilegedTableDto table, Instant timestamp, Long page, Long size) throws SQLException, + public QueryResultDto getPaginatedData(PrivilegedTableDto table, Instant timestamp, Long page, Long size) throws SQLException, TableMalformedException { final ComboPooledDataSource dataSource = getPrivilegedDataSource(table.getDatabase()); final Connection connection = dataSource.getConnection(); @@ -273,20 +274,43 @@ public class TableServiceMariaDbImpl extends HibernateConnector implements Table } @Override - public void importDataset(PrivilegedTableDto table, ImportDto data) throws StorageNotFoundException, - SQLException, QueryMalformedException, RemoteUnavailableException, SidecarImportException { - /* import .csv from blob storage to sidecar */ - dataDatabaseSidecarGateway.importFile(table.getDatabase().getContainer().getSidecarHost(), table.getDatabase().getContainer().getSidecarPort(), data.getLocation()); + public void importDataset(PrivilegedTableDto table, ImportDto data) throws MalformedException, + StorageNotFoundException, StorageUnavailableException, SQLException, QueryMalformedException { + final List<String> columns = table.getColumns() + .stream() + .map(ColumnDto::getInternalName) + .toList(); + final Dataset<Row> dataset = storageService.loadDataset(columns, data.getLocation(), data.getHeader()); + final Properties properties = new Properties(); + properties.setProperty("user", table.getDatabase().getContainer().getUsername()); + properties.setProperty("password", table.getDatabase().getContainer().getPassword()); + final String temporaryTable = table.getInternalName() + "_tmp"; + try { + log.trace("import dataset to temporary table: {}", temporaryTable); + dataset.write() + .mode(SaveMode.Overwrite) + .option("header", data.getHeader()) + .option("inferSchema", "true") + .jdbc(getSparkUrl(table.getDatabase().getContainer(), table.getDatabase().getInternalName()), + temporaryTable, properties); + } catch (Exception e) { + if (e instanceof AnalysisException exception) { + final String message = exception.getSimpleMessage() + .replaceAll(" Some\\(.*", ""); + log.error("Failed to write dataset: schema malformed: {}", message); + throw new MalformedException("Failed to write dataset: schema malformed: " + message) /* remove throwable on purpose, clutters the output */; + } + log.error("Failed to write dataset: {}", e.getMessage()); + throw new MalformedException("Failed to write dataset: " + e.getMessage()) /* remove throwable on purpose, clutters the output */; + } /* import .csv from sidecar to database */ final ComboPooledDataSource dataSource = getPrivilegedDataSource(table.getDatabase()); final Connection connection = dataSource.getConnection(); try { /* import tuple */ - data.setLocation(s3Config.getS3FilePath() + File.separator + data.getLocation()); - final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.datasetToRawInsertQuery(table.getDatabase().getInternalName(), table, data)) + connection.prepareStatement(mariaDbMapper.temporaryTableToRawMergeQuery(temporaryTable, + table.getInternalName(), table.getColumns().stream().map(c -> c.getInternalName()).toList())) .execute(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); connection.commit(); } catch (SQLException e) { connection.rollback(); @@ -420,31 +444,35 @@ public class TableServiceMariaDbImpl extends HibernateConnector implements Table } @Override - public ExportResourceDto exportDataset(PrivilegedTableDto table, Instant timestamp) throws SQLException, - StorageNotFoundException, StorageUnavailableException, QueryMalformedException, RemoteUnavailableException, - SidecarExportException { - final String fileName = RandomStringUtils.randomAlphabetic(40) + ".csv"; - final String filePath = s3Config.getS3FilePath() + "/" + fileName; - final ComboPooledDataSource dataSource = getPrivilegedDataSource(table.getDatabase()); - final Connection connection = dataSource.getConnection(); + public ExportResourceDto exportDataset(PrivilegedTableDto table, Instant timestamp) throws TableNotFoundException, + QueryMalformedException, StorageUnavailableException, MalformedException { + final Dataset<Row> dataset = getData(table, timestamp); + httpDataAccessCounter.increment(); + return storageService.transformDataset(dataset); + } + + @Override + public Dataset<Row> getData(@NotNull PrivilegedTableDto table, Instant timestamp) throws TableNotFoundException, + QueryMalformedException { try { - /* export to data database sidecar */ - final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.tableOrViewToRawExportQuery(table.getDatabase().getInternalName(), - table.getInternalName(), table.getColumns(), timestamp, filePath)) - .executeUpdate(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); - connection.commit(); - } catch (SQLException e) { - connection.rollback(); - log.error("Failed to execute query: {}", e.getMessage()); - throw new QueryMalformedException("Failed to execute query: " + e.getMessage(), e); - } finally { - dataSource.close(); + final Properties properties = new Properties(); + properties.setProperty("user", table.getDatabase().getContainer().getUsername()); + properties.setProperty("password", table.getDatabase().getContainer().getPassword()); + return sparkSession.read() + .jdbc(getSparkUrl(table.getDatabase().getContainer(), table.getDatabase().getInternalName()), + mariaDbMapper.tableOrViewToRawExportQuery(table.getDatabase().getInternalName(), + table.getInternalName(), table.getColumns().stream() + .map(ColumnDto::getInternalName).toList(), timestamp), properties); + } catch (Exception e) { + if (e instanceof ExtendedAnalysisException exception) { + if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) { + log.error("Failed to find table {}: {}", table.getInternalName(), exception.getSimpleMessage()); + throw new TableNotFoundException("Failed to find table " + table.getInternalName() + ": " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */; + } + } + log.error("Failed to export dataset: {}", e.getMessage()); + throw new QueryMalformedException("Failed to export dataset: " + e.getMessage(), e); } - dataDatabaseSidecarGateway.exportFile(table.getDatabase().getContainer().getSidecarHost(), table.getDatabase().getContainer().getSidecarPort(), fileName); - httpDataAccessCounter.increment(); - return storageService.getResource(fileName); } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java index 366cfa5faf..77e065bc93 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java @@ -1,16 +1,18 @@ package at.tuwien.service.impl; import at.tuwien.ExportResourceDto; +import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewCreateDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.internal.PrivilegedDatabaseDto; import at.tuwien.api.database.internal.PrivilegedViewDto; import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.columns.ColumnDto; +import at.tuwien.api.database.table.internal.PrivilegedTableDto; import at.tuwien.config.QueryConfig; import at.tuwien.config.S3Config; +import at.tuwien.config.SparkConfig; import at.tuwien.exception.*; -import at.tuwien.gateway.DataDatabaseSidecarGateway; import at.tuwien.mapper.DataMapper; import at.tuwien.mapper.MariaDbMapper; import at.tuwien.mapper.MetadataMapper; @@ -20,8 +22,13 @@ import at.tuwien.service.ViewService; import com.google.common.hash.Hashing; import com.mchange.v2.c3p0.ComboPooledDataSource; import io.micrometer.core.instrument.Counter; +import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SparkSession; +import org.apache.spark.sql.catalyst.ExtendedAnalysisException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -34,35 +41,34 @@ import java.sql.SQLException; import java.time.Instant; import java.util.LinkedList; import java.util.List; +import java.util.Properties; @Log4j2 @Service public class ViewServiceMariaDbImpl extends HibernateConnector implements ViewService { private final Counter httpDataAccessCounter; - private final S3Config s3Config; private final DataMapper dataMapper; private final QueryConfig queryConfig; + private final SparkSession sparkSession; private final MariaDbMapper mariaDbMapper; private final SchemaService schemaService; private final StorageService storageService; private final MetadataMapper metadataMapper; - private final DataDatabaseSidecarGateway dataDatabaseSidecarGateway; @Autowired - public ViewServiceMariaDbImpl(Counter httpDataAccessCounter, S3Config s3Config, DataMapper dataMapper, - QueryConfig queryConfig, MariaDbMapper mariaDbMapper, SchemaService schemaService, - StorageService storageService, MetadataMapper metadataMapper, - DataDatabaseSidecarGateway dataDatabaseSidecarGateway) { + public ViewServiceMariaDbImpl(Counter httpDataAccessCounter, DataMapper dataMapper, + QueryConfig queryConfig, SparkSession sparkSession, MariaDbMapper mariaDbMapper, + SchemaService schemaService, StorageService storageService, + MetadataMapper metadataMapper) { this.httpDataAccessCounter = httpDataAccessCounter; - this.s3Config = s3Config; this.dataMapper = dataMapper; this.queryConfig = queryConfig; + this.sparkSession = sparkSession; this.mariaDbMapper = mariaDbMapper; this.schemaService = schemaService; this.storageService = storageService; this.metadataMapper = metadataMapper; - this.dataDatabaseSidecarGateway = dataDatabaseSidecarGateway; } @Override @@ -228,35 +234,35 @@ public class ViewServiceMariaDbImpl extends HibernateConnector implements ViewSe } @Override - public ExportResourceDto exportDataset(PrivilegedViewDto view) throws SQLException, QueryMalformedException, - SidecarExportException, RemoteUnavailableException, StorageNotFoundException, StorageUnavailableException { - final String fileName = RandomStringUtils.randomAlphabetic(40) + ".csv"; - final String filePath = s3Config.getS3FilePath() + File.separator + fileName; - final ComboPooledDataSource dataSource = getPrivilegedDataSource(view.getDatabase()); - final Connection connection = dataSource.getConnection(); + public ExportResourceDto exportDataset(PrivilegedViewDto view) throws QueryMalformedException, + StorageUnavailableException, ViewNotFoundException, MalformedException { + final Dataset<Row> dataset = getData(view); + httpDataAccessCounter.increment(); + return storageService.transformDataset(dataset); + } + + @Override + public Dataset<Row> getData(@NotNull PrivilegedViewDto view) throws ViewNotFoundException, + QueryMalformedException { try { - /* export to data database sidecar */ - final List<ColumnDto> columns = view.getColumns() - .stream() - .map(metadataMapper::viewColumnDtoToColumnDto) - .toList(); - final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.tableOrViewToRawExportQuery(view.getDatabase().getInternalName(), - view.getInternalName(), columns, null, filePath)) - .executeUpdate(); - log.debug("executed statement in {} ms", System.currentTimeMillis() - start); - connection.commit(); - } catch (SQLException e) { - connection.rollback(); - log.error("Failed to execute query: {}", e.getMessage()); - throw new QueryMalformedException("Failed to execute query: " + e.getMessage(), e); - } finally { - dataSource.close(); + final Properties properties = new Properties(); + properties.setProperty("user", view.getDatabase().getContainer().getUsername()); + properties.setProperty("password", view.getDatabase().getContainer().getPassword()); + return sparkSession.read() + .jdbc(getSparkUrl(view.getDatabase().getContainer(), view.getDatabase().getInternalName()), + mariaDbMapper.tableOrViewToRawExportQuery(view.getDatabase().getInternalName(), + view.getInternalName(), view.getColumns().stream() + .map(ViewColumnDto::getInternalName).toList(), Instant.now()), properties); + } catch (Exception e) { + if (e instanceof ExtendedAnalysisException exception) { + if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) { + log.error("Failed to find view {}: {}", view.getInternalName(), exception.getSimpleMessage()); + throw new ViewNotFoundException("Failed to find view " + view.getInternalName() + ": " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */; + } + } + log.error("Failed to export dataset: {}", e.getMessage()); + throw new QueryMalformedException("Failed to export dataset: " + e.getMessage(), e); } - dataDatabaseSidecarGateway.exportFile(view.getDatabase().getContainer().getSidecarHost(), - view.getDatabase().getContainer().getSidecarPort(), fileName); - httpDataAccessCounter.increment(); - return storageService.getResource(fileName); } } diff --git a/dbrepo-metadata-db/1_setup-schema.sql b/dbrepo-metadata-db/1_setup-schema.sql index ad240f6c9b..58a4c6ff39 100644 --- a/dbrepo-metadata-db/1_setup-schema.sql +++ b/dbrepo-metadata-db/1_setup-schema.sql @@ -453,8 +453,8 @@ CREATE TABLE IF NOT EXISTS `mdb_related_identifiers` id SERIAL, pid BIGINT UNSIGNED NOT NULL, value varchar(255) NOT NULL, - type varchar(255) NOT NULL, - relation varchar(255) NOT NULL, + type ENUM ('DOI','URL','URN','ARK','ARXIV','BIBCODE','EAN13','EISSN','HANDLE','IGSN','ISBN','ISTC','LISSN','LSID','PMID','PURL','UPC','W3ID') NOT NULL, + relation ENUM ('IS_CITED_BY','CITES','IS_SUPPLEMENT_TO','IS_SUPPLEMENTED_BY','IS_CONTINUED_BY','CONTINUES','IS_DESCRIBED_BY','DESCRIBES','HAS_METADATA','IS_METADATA_FOR','HAS_VERSION','IS_VERSION_OF','IS_NEW_VERSION_OF','IS_PREVIOUS_VERSION_OF','IS_PART_OF','HAS_PART','IS_PUBLISHED_IN','IS_REFERENCED_BY','REFERENCES','IS_DOCUMENTED_BY','DOCUMENTS','IS_COMPILED_BY','COMPILES','IS_VARIANT_FORM_OF','IS_ORIGINAL_FORM_OF','IS_IDENTICAL_TO','IS_REVIEWED_BY','REVIEWS','IS_DERIVED_FROM','IS_SOURCE_OF','IS_REQUIRED_BY','REQUIRES','IS_OBSOLETED_BY','OBSOLETES') NOT NULL, PRIMARY KEY (id), /* must be a single id from persistent identifier concept */ FOREIGN KEY (pid) REFERENCES mdb_identifiers (id), UNIQUE (pid, value) @@ -545,7 +545,7 @@ CREATE TABLE IF NOT EXISTS `mdb_image_operators` PRIMARY KEY (id), FOREIGN KEY (image_id) REFERENCES `mdb_images` (`id`), UNIQUE (value) -) WITH SYSTEM VERSIONING; + ) WITH SYSTEM VERSIONING; COMMIT; diff --git a/dbrepo-metadata-service/Dockerfile b/dbrepo-metadata-service/Dockerfile index 74e8204373..843c334a9a 100644 --- a/dbrepo-metadata-service/Dockerfile +++ b/dbrepo-metadata-service/Dockerfile @@ -1,5 +1,5 @@ ###### FIRST STAGE ###### -FROM maven:3-openjdk-17 AS build +FROM maven:3-amazoncorretto-17 AS build LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" COPY ./pom.xml ./ diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerCreateDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerCreateDto.java index 7080d2b5d9..86b50bea70 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerCreateDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerCreateDto.java @@ -20,7 +20,7 @@ public class ContainerCreateDto { @Schema(example = "Air Quality") private String name; - @NotBlank + @NotNull @JsonProperty("image_id") @Schema(description = "Image ID") private Long imageId; @@ -32,14 +32,6 @@ public class ContainerCreateDto { @Schema(description = "Port of container") private Integer port; - @NotBlank - @JsonProperty("sidecar_host") - private String sidecarHost; - - @NotNull - @JsonProperty("sidecar_port") - private Integer sidecarPort; - @JsonProperty("ui_host") private String uiHost; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java index 7e46b80c1c..8f745f9ee9 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java @@ -37,14 +37,6 @@ public class ContainerDto { private Integer port; - @NotBlank - @JsonProperty("sidecar_host") - private String sidecarHost; - - @NotNull - @JsonProperty("sidecar_port") - private Integer sidecarPort; - @JsonProperty("ui_host") private String uiHost; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java index 8bda16bf41..3a7a375618 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/internal/PrivilegedContainerDto.java @@ -37,14 +37,6 @@ public class PrivilegedContainerDto { private Integer port; - @NotBlank - @JsonProperty("sidecar_host") - private String sidecarHost; - - @NotNull - @JsonProperty("sidecar_port") - private Integer sidecarPort; - @JsonProperty("ui_host") private String uiHost; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java index 043e3bc3ee..1b31d9d619 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/ImportDto.java @@ -1,11 +1,9 @@ package at.tuwien.api.database.query; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.extern.jackson.Jacksonized; @@ -23,9 +21,9 @@ public class ImportDto { @Schema(example = "file.csv") private String location; - @Min(value = 0L) - @JsonProperty("skip_lines") - private Long skipLines; + @NotNull + @Schema(description = "If true, the first line contains the column names, otherwise it contains only data") + private Boolean header; @NotNull @Schema(example = ",") diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/container/Container.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/container/Container.java index 7545260ce1..168c0cc752 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/container/Container.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/container/Container.java @@ -43,12 +43,6 @@ public class Container { @Column private Integer port; - @Column - private String sidecarHost; - - @Column - private Integer sidecarPort; - @Column private String uiHost; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/ViewColumn.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/ViewColumn.java index 10ac29d8e6..201d7075e5 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/ViewColumn.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/ViewColumn.java @@ -39,7 +39,7 @@ public class ViewColumn implements Comparable<ViewColumn> { @Column(name = "internal_name", nullable = false, columnDefinition = "VARCHAR(64)") private String internalName; - @Column(nullable = false, columnDefinition = "ENUM('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR')") + @Column(nullable = false, columnDefinition = "ENUM('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','SERIAL','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR')") @Enumerated(EnumType.STRING) private TableColumnType columnType; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Creator.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Creator.java index f2452ac559..f69f3c6d71 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Creator.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Creator.java @@ -33,14 +33,14 @@ public class Creator { @Column(name = "creator_name", nullable = false) private String creatorName; - @Column(columnDefinition = "enum('PERSONAL', 'ORGANIZATIONAL')") + @Column(columnDefinition = "ENUM('PERSONAL', 'ORGANIZATIONAL')") @Enumerated(EnumType.STRING) private NameType nameType; @Column private String nameIdentifier; - @Column(columnDefinition = "enum('ROR', 'GRID', 'ISNI', 'ORCID')") + @Column(columnDefinition = "ENUM('ROR', 'GRID', 'ISNI', 'ORCID')") @Enumerated(EnumType.STRING) private NameIdentifierSchemeType nameIdentifierScheme; @@ -53,7 +53,7 @@ public class Creator { @Column private String affiliationIdentifier; - @Column(columnDefinition = "enum('ROR', 'GRID', 'ISNI')") + @Column(columnDefinition = "ENUM('ROR', 'GRID', 'ISNI')") @Enumerated(EnumType.STRING) private AffiliationIdentifierSchemeType affiliationIdentifierScheme; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java index 6c8615f0d9..abf76758cc 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java @@ -66,7 +66,7 @@ public class Identifier implements Serializable { @Column(nullable = false) private String publisher; - @Column(nullable = false, columnDefinition = "enum('DRAFT', 'PUBLISHED')") + @Column(nullable = false, columnDefinition = "ENUM('DRAFT', 'PUBLISHED')") @Enumerated(EnumType.STRING) private IdentifierStatusType status; @@ -106,7 +106,7 @@ public class Identifier implements Serializable { ) private List<License> licenses; - @Column(name = "identifier_type", nullable = false, columnDefinition = "enum('SUBSET', 'DATABASE', 'VIEW', 'TABLE')") + @Column(name = "identifier_type", nullable = false, columnDefinition = "ENUM('SUBSET', 'DATABASE', 'VIEW', 'TABLE')") @Enumerated(EnumType.STRING) private IdentifierType type; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierDescription.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierDescription.java index 17376c1cb6..8544650a6c 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierDescription.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierDescription.java @@ -29,11 +29,11 @@ public class IdentifierDescription implements Serializable { @Column(nullable = false, columnDefinition = "TEXT") private String description; - @Column(columnDefinition = "enum('ABSTRACT', 'METHODS', 'SERIES_INFORMATION', 'TABLE_OF_CONTENTS', 'TECHNICAL_INFO', 'OTHER')") + @Column(columnDefinition = "ENUM('ABSTRACT', 'METHODS', 'SERIES_INFORMATION', 'TABLE_OF_CONTENTS', 'TECHNICAL_INFO', 'OTHER')") @Enumerated(EnumType.STRING) private DescriptionType descriptionType; - @Column(columnDefinition = "enum('AB','AA','AF','AK','SQ','AM','AR','AN','HY','AS','AV','AE','AY','AZ','BM','BA','EU','BE','BN','BH','BI','BS','BR','BG','MY','CA','KM','CH','CE','NY','ZH','CU','CV','KW','CO','CR','HR','CS','DA','DV','NL','DZ','EN','EO','ET','EE','FO','FJ','FI','FR','FF','GD','GL','LG','KA','DE','KI','EL','KL','GN','GU','HT','HA','HE','HZ','HI','HO','HU','IS','IO','IG','ID','IA','IE','IU','IK','GA','IT','JA','JV','KN','KR','KS','KK','RW','KV','KG','KO','KJ','KU','KY','LO','LA','LV','LB','LI','LN','LT','LU','MK','MG','MS','ML','MT','GV','MI','MR','MH','RO','MN','NA','NV','ND','NG','NE','SE','NO','NB','NN','II','OC','OJ','OR','OM','OS','PI','PA','PS','FA','PL','PT','QU','RM','RN','RU','SM','SG','SA','SC','SR','SN','SD','SI','SK','SL','SO','ST','NR','ES','SU','SW','SS','SV','TL','TY','TG','TA','TT','TE','TH','BO','TI','TO','TS','TN','TR','TK','TW','UG','UK','UR','UZ','VE','VI','VO','WA','CY','FY','WO','XH','YI','YO','ZA','ZU')") + @Column(columnDefinition = "ENUM('AB','AA','AF','AK','SQ','AM','AR','AN','HY','AS','AV','AE','AY','AZ','BM','BA','EU','BE','BN','BH','BI','BS','BR','BG','MY','CA','KM','CH','CE','NY','ZH','CU','CV','KW','CO','CR','HR','CS','DA','DV','NL','DZ','EN','EO','ET','EE','FO','FJ','FI','FR','FF','GD','GL','LG','KA','DE','KI','EL','KL','GN','GU','HT','HA','HE','HZ','HI','HO','HU','IS','IO','IG','ID','IA','IE','IU','IK','GA','IT','JA','JV','KN','KR','KS','KK','RW','KV','KG','KO','KJ','KU','KY','LO','LA','LV','LB','LI','LN','LT','LU','MK','MG','MS','ML','MT','GV','MI','MR','MH','RO','MN','NA','NV','ND','NG','NE','SE','NO','NB','NN','II','OC','OJ','OR','OM','OS','PI','PA','PS','FA','PL','PT','QU','RM','RN','RU','SM','SG','SA','SC','SR','SN','SD','SI','SK','SL','SO','ST','NR','ES','SU','SW','SS','SV','TL','TY','TG','TA','TT','TE','TH','BO','TI','TO','TS','TN','TR','TK','TW','UG','UK','UR','UZ','VE','VI','VO','WA','CY','FY','WO','XH','YI','YO','ZA','ZU')") @Enumerated(EnumType.STRING) private LanguageType language; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierFunder.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierFunder.java index 21977c19a9..cd08b9ccbe 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierFunder.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierFunder.java @@ -30,7 +30,7 @@ public class IdentifierFunder implements Serializable { @Column(columnDefinition = "TEXT") private String funderIdentifier; - @Column(name="funder_identifier_type", columnDefinition = "enum('CROSSREF_FUNDER_ID', 'ROR', 'GND', 'ISNI', 'OTHER')") + @Column(name="funder_identifier_type", columnDefinition = "ENUM('CROSSREF_FUNDER_ID', 'ROR', 'GND', 'ISNI', 'OTHER')") @Enumerated(EnumType.STRING) private IdentifierFunderType funderIdentifierType; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierTitle.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierTitle.java index c5a62974b0..72cc7c95ca 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierTitle.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/IdentifierTitle.java @@ -28,11 +28,11 @@ public class IdentifierTitle implements Serializable { @Column(nullable = false, columnDefinition = "TEXT") private String title; - @Column(columnDefinition = "enum('ALTERNATIVE_TITLE', 'SUBTITLE', 'TRANSLATED_TITLE', 'OTHER')") + @Column(columnDefinition = "ENUM('ALTERNATIVE_TITLE', 'SUBTITLE', 'TRANSLATED_TITLE', 'OTHER')") @Enumerated(EnumType.STRING) private TitleType titleType; - @Column(columnDefinition = "enum('AB','AA','AF','AK','SQ','AM','AR','AN','HY','AS','AV','AE','AY','AZ','BM','BA','EU','BE','BN','BH','BI','BS','BR','BG','MY','CA','KM','CH','CE','NY','ZH','CU','CV','KW','CO','CR','HR','CS','DA','DV','NL','DZ','EN','EO','ET','EE','FO','FJ','FI','FR','FF','GD','GL','LG','KA','DE','KI','EL','KL','GN','GU','HT','HA','HE','HZ','HI','HO','HU','IS','IO','IG','ID','IA','IE','IU','IK','GA','IT','JA','JV','KN','KR','KS','KK','RW','KV','KG','KO','KJ','KU','KY','LO','LA','LV','LB','LI','LN','LT','LU','MK','MG','MS','ML','MT','GV','MI','MR','MH','RO','MN','NA','NV','ND','NG','NE','SE','NO','NB','NN','II','OC','OJ','OR','OM','OS','PI','PA','PS','FA','PL','PT','QU','RM','RN','RU','SM','SG','SA','SC','SR','SN','SD','SI','SK','SL','SO','ST','NR','ES','SU','SW','SS','SV','TL','TY','TG','TA','TT','TE','TH','BO','TI','TO','TS','TN','TR','TK','TW','UG','UK','UR','UZ','VE','VI','VO','WA','CY','FY','WO','XH','YI','YO','ZA','ZU')") + @Column(columnDefinition = "ENUM('AB','AA','AF','AK','SQ','AM','AR','AN','HY','AS','AV','AE','AY','AZ','BM','BA','EU','BE','BN','BH','BI','BS','BR','BG','MY','CA','KM','CH','CE','NY','ZH','CU','CV','KW','CO','CR','HR','CS','DA','DV','NL','DZ','EN','EO','ET','EE','FO','FJ','FI','FR','FF','GD','GL','LG','KA','DE','KI','EL','KL','GN','GU','HT','HA','HE','HZ','HI','HO','HU','IS','IO','IG','ID','IA','IE','IU','IK','GA','IT','JA','JV','KN','KR','KS','KK','RW','KV','KG','KO','KJ','KU','KY','LO','LA','LV','LB','LI','LN','LT','LU','MK','MG','MS','ML','MT','GV','MI','MR','MH','RO','MN','NA','NV','ND','NG','NE','SE','NO','NB','NN','II','OC','OJ','OR','OM','OS','PI','PA','PS','FA','PL','PT','QU','RM','RN','RU','SM','SG','SA','SC','SR','SN','SD','SI','SK','SL','SO','ST','NR','ES','SU','SW','SS','SV','TL','TY','TG','TA','TT','TE','TH','BO','TI','TO','TS','TN','TR','TK','TW','UG','UK','UR','UZ','VE','VI','VO','WA','CY','FY','WO','XH','YI','YO','ZA','ZU')") @Enumerated(EnumType.STRING) private LanguageType language; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java index a8006e626d..1bc3d269fa 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java @@ -29,11 +29,11 @@ public class RelatedIdentifier { @Column(nullable = false) private String value; - @Column(columnDefinition = "enum('DOI','URL','URN','ARK','arXiv','bibcode','EAN13','EISSN','Handle','IGSN','ISBN','ISTC','LISSN','LSID','PMID','PURL','UPC','w3id')") + @Column(columnDefinition = "ENUM('DOI','URL','URN','ARK','ARXIV','BIBCODE','EAN13','EISSN','HANDLE','IGSN','ISBN','ISTC','LISSN','LSID','PMID','PURL','UPC','W3ID')") @Enumerated(EnumType.STRING) private RelatedType type; - @Column(columnDefinition = "enum('IsCitedBy','Cites','IsSupplementTo','IsSupplementedBy','IsContinuedBy','Continues','IsDescribedBy','Describes','HasMetadata','IsMetadataFor','HasVersion','IsVersionOf','IsNewVersionOf','IsPreviousVersionOf','IsPartOf','HasPart','IsPublishedIn','IsReferencedBy','References','IsDocumentedBy','Documents','IsCompiledBy','Compiles','IsVariantFormOf','IsOriginalFormOf','IsIdenticalTo','IsReviewedBy','Reviews','IsDerivedFrom','IsSourceOf','IsRequiredBy','Requires','IsObsoletedBy','Obsoletes')") + @Column(columnDefinition = "ENUM('IS_CITED_BY','CITES','IS_SUPPLEMENT_TO','IS_SUPPLEMENTED_BY','IS_CONTINUED_BY','CONTINUES','IS_DESCRIBED_BY','DESCRIBES','HAS_METADATA','IS_METADATA_FOR','HAS_VERSION','IS_VERSION_OF','IS_NEW_VERSION_OF','IS_PREVIOUS_VERSION_OF','IS_PART_OF','HAS_PART','IS_PUBLISHED_IN','IS_REFERENCED_BY','REFERENCES','IS_DOCUMENTED_BY','DOCUMENTS','IS_COMPILED_BY','COMPILES','IS_VARIANT_FORM_OF','IS_ORIGINAL_FORM_OF','IS_IDENTICAL_TO','IS_REVIEWED_BY','REVIEWS','IS_DERIVED_FROM','IS_SOURCE_OF','IS_REQUIRED_BY','REQUIRES','IS_OBSOLETED_BY','OBSOLETES')") @Enumerated(EnumType.STRING) private RelationType relation; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/maintenance/BannerMessage.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/maintenance/BannerMessage.java index f7d2abaafc..de0d917b43 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/maintenance/BannerMessage.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/maintenance/BannerMessage.java @@ -27,7 +27,7 @@ public class BannerMessage { @Column(updatable = false, nullable = false) private Long id; - @Column(nullable = false, columnDefinition = "enum('ERROR','WARNING','INFO')") + @Column(nullable = false, columnDefinition = "ENUM('ERROR','WARNING','INFO')") @Enumerated(EnumType.STRING) private BannerMessageType type; diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml index a2de622dca..5ac480bce0 100644 --- a/dbrepo-metadata-service/pom.xml +++ b/dbrepo-metadata-service/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>3.0.13</version> + <version>3.1.12</version> </parent> <groupId>at.tuwien</groupId> diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarExportException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/AnalyseServiceException.java similarity index 53% rename from dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarExportException.java rename to dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/AnalyseServiceException.java index 6000222a67..44cd0d3dc8 100644 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarExportException.java +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/AnalyseServiceException.java @@ -3,18 +3,18 @@ package at.tuwien.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -@ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE, reason = "error.sidecar.export") -public class SidecarExportException extends Exception { +@ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE, reason = "error.analyse.invalid") +public class AnalyseServiceException extends Exception { - public SidecarExportException(String message) { + public AnalyseServiceException(String message) { super(message); } - public SidecarExportException(String message, Throwable thr) { + public AnalyseServiceException(String message, Throwable thr) { super(message, thr); } - public SidecarExportException(Throwable thr) { + public AnalyseServiceException(Throwable thr) { super(thr); } diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarImportException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarImportException.java deleted file mode 100644 index 4f44226c73..0000000000 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/SidecarImportException.java +++ /dev/null @@ -1,21 +0,0 @@ -package at.tuwien.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE, reason = "error.sidecar.import") -public class SidecarImportException extends Exception { - - public SidecarImportException(String message) { - super(message); - } - - public SidecarImportException(String message, Throwable thr) { - super(message, thr); - } - - public SidecarImportException(Throwable thr) { - super(thr); - } - -} diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index f50f916ac4..3b39857ee6 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -91,8 +91,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseAccessDto> create(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<DatabaseAccessDto> create(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @Valid @RequestBody UpdateDatabaseAccessDto data, @NotNull Principal principal) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, UserNotFoundException, AccessNotFoundException, @@ -154,8 +154,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> update(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<Void> update(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @Valid @RequestBody UpdateDatabaseAccessDto data, @NotNull Principal principal) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, UserNotFoundException, @@ -199,8 +199,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<DatabaseAccessDto> find(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<DatabaseAccessDto> find(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @NotNull Principal principal) throws DatabaseNotFoundException, UserNotFoundException, AccessNotFoundException, NotAllowedException { log.debug("endpoint get database access, databaseId={}, userId={}, principal.name={}", databaseId, userId, @@ -256,8 +256,8 @@ public class AccessEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), }) - public ResponseEntity<Void> revoke(@NotBlank @PathVariable("databaseId") Long databaseId, - @NotBlank @PathVariable("userId") UUID userId, + public ResponseEntity<Void> revoke(@NotNull @PathVariable("databaseId") Long databaseId, + @org.hibernate.validator.constraints.UUID @PathVariable("userId") UUID userId, @NotNull Principal principal) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, UserNotFoundException, AccessNotFoundException, SearchServiceException, SearchServiceConnectionException { diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index d5c316fed9..b270bdb206 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -448,6 +448,9 @@ public class DatabaseEndpoint { @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Database found successfully", + headers = {@Header(name = "X-Username", description = "The authentication username", schema = @Schema(implementation = String.class)), + @Header(name = "X-Password", description = "The authentication password", schema = @Schema(implementation = String.class)), + @Header(name = "Access-Control-Expose-Headers", description = "Expose custom headers", schema = @Schema(implementation = String.class))}, content = {@Content( mediaType = "application/json", schema = @Schema(implementation = DatabaseDto.class))}), diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java index 831e9cd28d..7f2e0ee93d 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java @@ -187,11 +187,6 @@ public class IdentifierEndpoint { content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), - @ApiResponse(responseCode = "422", - description = "Failed to retrieve from database sidecar", - content = {@Content( - mediaType = "application/json", - schema = @Schema(implementation = ApiErrorDto.class))}), @ApiResponse(responseCode = "502", description = "Connection to data service failed", content = {@Content( diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 738e30d4e4..ef897d06ee 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -22,6 +22,7 @@ import at.tuwien.utils.UserUtil; import at.tuwien.validation.EndpointValidator; import io.micrometer.observation.annotation.Observed; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -361,11 +362,19 @@ public class TableEndpoint { @Transactional(readOnly = true) @Observed(name = "dbrepo_tables_find") @Operation(summary = "Find table", - description = "Finds a table with id.", + description = "Finds a table with id. When the `system` role is present, the endpoint responds with additional connection metadata in the header.", security = {@SecurityRequirement(name = "bearerAuth"), @SecurityRequirement(name = "basicAuth")}) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Find table successfully", + headers = {@Header(name = "X-Username", description = "The authentication username", schema = @Schema(implementation = String.class)), + @Header(name = "X-Password", description = "The authentication password", schema = @Schema(implementation = String.class)), + @Header(name = "X-Host", description = "The database hostname", schema = @Schema(implementation = String.class)), + @Header(name = "X-Port", description = "The database port number", schema = @Schema(implementation = Integer.class)), + @Header(name = "X-Type", description = "The JDBC connection type", schema = @Schema(implementation = String.class)), + @Header(name = "X-Database", description = "The database internal name", schema = @Schema(implementation = String.class)), + @Header(name = "X-Table", description = "The table internal name", schema = @Schema(implementation = String.class)), + @Header(name = "Access-Control-Expose-Headers", description = "Expose custom headers", schema = @Schema(implementation = String.class))}, content = {@Content( mediaType = "application/json", schema = @Schema(implementation = TableDto.class))}), @@ -405,9 +414,8 @@ public class TableEndpoint { headers.set("X-Port", "" + table.getDatabase().getContainer().getPort()); headers.set("X-Type", table.getDatabase().getContainer().getImage().getJdbcMethod()); headers.set("X-Database", table.getDatabase().getInternalName()); - headers.set("X-Sidecar-Host", table.getDatabase().getContainer().getSidecarHost()); - headers.set("X-Sidecar-Port", "" + table.getDatabase().getContainer().getSidecarPort()); - headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Sidecar-Host X-Sidecar-Port"); + headers.set("X-Table", table.getInternalName()); + headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Table"); } return ResponseEntity.status(HttpStatus.OK) .headers(headers) diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 79981ee6d1..cfcc554885 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -15,6 +15,7 @@ import at.tuwien.service.ViewService; import at.tuwien.utils.UserUtil; import io.micrometer.observation.annotation.Observed; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -161,6 +162,14 @@ public class ViewEndpoint { @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Find view successfully", + headers = {@Header(name = "X-Username", description = "The authentication username", schema = @Schema(implementation = String.class)), + @Header(name = "X-Password", description = "The authentication password", schema = @Schema(implementation = String.class)), + @Header(name = "X-Host", description = "The database hostname", schema = @Schema(implementation = String.class)), + @Header(name = "X-Port", description = "The database port number", schema = @Schema(implementation = Integer.class)), + @Header(name = "X-Type", description = "The JDBC connection type", schema = @Schema(implementation = String.class)), + @Header(name = "X-Database", description = "The database internal name", schema = @Schema(implementation = String.class)), + @Header(name = "X-View", description = "The view internal name", schema = @Schema(implementation = String.class)), + @Header(name = "Access-Control-Expose-Headers", description = "Expose custom headers", schema = @Schema(implementation = String.class))}, content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ViewDto.class))}), @@ -190,7 +199,8 @@ public class ViewEndpoint { headers.set("X-Port", "" + view.getDatabase().getContainer().getPort()); headers.set("X-Type", view.getDatabase().getContainer().getImage().getJdbcMethod()); headers.set("X-Database", view.getDatabase().getInternalName()); - headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database"); + headers.set("X-View", view.getInternalName()); + headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View"); } return ResponseEntity.status(HttpStatus.OK) .headers(headers) diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java index bf655f071a..5b5769583a 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java @@ -30,6 +30,13 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } + @Hidden + @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) + @ExceptionHandler(AnalyseServiceException.class) + public ResponseEntity<ApiErrorDto> handle(AnalyseServiceException e) { + return generic_handle(e.getClass(), e.getLocalizedMessage()); + } + @Hidden @ResponseStatus(code = HttpStatus.BAD_GATEWAY) @ExceptionHandler(AuthServiceConnectionException.class) @@ -359,20 +366,6 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } - @Hidden - @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) - @ExceptionHandler(SidecarExportException.class) - public ResponseEntity<ApiErrorDto> handle(SidecarExportException e) { - return generic_handle(e.getClass(), e.getLocalizedMessage()); - } - - @Hidden - @ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE) - @ExceptionHandler(SidecarImportException.class) - public ResponseEntity<ApiErrorDto> handle(SidecarImportException e) { - return generic_handle(e.getClass(), e.getLocalizedMessage()); - } - @Hidden @ResponseStatus(code = HttpStatus.BAD_REQUEST) @ExceptionHandler(SortException.class) diff --git a/dbrepo-metadata-service/rest-service/src/main/resources/application-local.yml b/dbrepo-metadata-service/rest-service/src/main/resources/application-local.yml index 793a2b6021..00aad25934 100644 --- a/dbrepo-metadata-service/rest-service/src/main/resources/application-local.yml +++ b/dbrepo-metadata-service/rest-service/src/main/resources/application-local.yml @@ -6,7 +6,6 @@ spring: password: dbrepo jpa: show-sql: false - database-platform: org.hibernate.dialect.MariaDBDialect open-in-view: false properties: hibernate: diff --git a/dbrepo-metadata-service/rest-service/src/main/resources/application.yml b/dbrepo-metadata-service/rest-service/src/main/resources/application.yml index 13e207a8bd..2d79e7cfae 100644 --- a/dbrepo-metadata-service/rest-service/src/main/resources/application.yml +++ b/dbrepo-metadata-service/rest-service/src/main/resources/application.yml @@ -9,7 +9,6 @@ spring: password: "${METADATA_DB_PASSWORD:dbrepo}" jpa: show-sql: false - database-platform: org.hibernate.dialect.MariaDBDialect open-in-view: false properties: hibernate: diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java index b4291ce902..5451efdd75 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java @@ -60,8 +60,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findAll_publicAnonymous_succeeds() throws ViewNotFoundException, UserNotFoundException, - AccessNotFoundException, DatabaseNotFoundException { + public void findAll_publicAnonymous_succeeds() throws UserNotFoundException, AccessNotFoundException, + DatabaseNotFoundException { /* test */ findAll_generic(DATABASE_3_ID, DATABASE_3, null, null, null, null); @@ -69,8 +69,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"list-views"}) - public void findAll_publicHasRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - AccessNotFoundException, DatabaseNotFoundException { + public void findAll_publicHasRole_succeeds() throws UserNotFoundException, AccessNotFoundException, + DatabaseNotFoundException { /* test */ findAll_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); @@ -78,8 +78,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"list-views"}) - public void findAll_publicHasRoleHasAccess_succeeds() throws ViewNotFoundException, UserNotFoundException, - AccessNotFoundException, DatabaseNotFoundException { + public void findAll_publicHasRoleHasAccess_succeeds() throws UserNotFoundException, AccessNotFoundException, + DatabaseNotFoundException { /* test */ findAll_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_3_USER_2_READ_ACCESS); @@ -87,8 +87,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void findAll_publicNoRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - AccessNotFoundException, DatabaseNotFoundException { + public void findAll_publicNoRole_succeeds() throws UserNotFoundException, AccessNotFoundException, + DatabaseNotFoundException { /* test */ findAll_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); @@ -136,8 +136,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void find_publicAnonymous_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_publicAnonymous_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_3_ID, DATABASE_3, null, null, null, null); @@ -145,8 +145,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"find-database-view"}) - public void find_publicHasRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_publicHasRole_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -154,8 +154,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void find_publicNoRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_publicNoRole_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -163,8 +163,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void find_publicHasRoleHasAccess_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_publicHasRoleHasAccess_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -203,8 +203,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"delete-database-view"}) public void delete_publicOwner_succeeds() throws NotAllowedException, DataServiceException, - DataServiceConnectionException, ViewNotFoundException, DatabaseNotFoundException, AccessNotFoundException, - SearchServiceException, SearchServiceConnectionException { + DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, + SearchServiceException, SearchServiceConnectionException, ViewNotFoundException { /* test */ delete_generic(DATABASE_3_ID, DATABASE_3, VIEW_5_ID, VIEW_5, USER_3_PRINCIPAL, USER_3_ID, USER_3, DATABASE_3_USER_1_WRITE_ALL_ACCESS); @@ -216,7 +216,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findAll_privateAnonymous_succeeds() throws ViewNotFoundException, UserNotFoundException, + public void findAll_privateAnonymous_succeeds() throws UserNotFoundException, AccessNotFoundException, DatabaseNotFoundException { /* test */ @@ -225,7 +225,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"list-views"}) - public void findAll_privateHasRole_succeeds() throws ViewNotFoundException, UserNotFoundException, + public void findAll_privateHasRole_succeeds() throws UserNotFoundException, AccessNotFoundException, DatabaseNotFoundException { /* test */ @@ -234,7 +234,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"list-views"}) - public void findAll_privateHasRoleHasAccess_succeeds() throws ViewNotFoundException, UserNotFoundException, + public void findAll_privateHasRoleHasAccess_succeeds() throws UserNotFoundException, AccessNotFoundException, DatabaseNotFoundException { /* test */ @@ -243,7 +243,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void findAll_privateNoRole_succeeds() throws ViewNotFoundException, UserNotFoundException, + public void findAll_privateNoRole_succeeds() throws UserNotFoundException, AccessNotFoundException, DatabaseNotFoundException { /* test */ @@ -292,8 +292,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void find_privateAnonymous_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_privateAnonymous_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_1_ID, DATABASE_1, null, null, null, null); @@ -301,8 +301,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"find-database-view"}) - public void find_privateHasRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_privateHasRole_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -310,8 +310,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void find_privateNoRole_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_privateNoRole_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -319,8 +319,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void find_privateHasRoleHasAccess_succeeds() throws ViewNotFoundException, UserNotFoundException, - DatabaseNotFoundException, AccessNotFoundException { + public void find_privateHasRoleHasAccess_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { /* test */ find_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); @@ -358,9 +358,9 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-view"}) - public void delete_privateOwner_succeeds() throws NotAllowedException, DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, AccessNotFoundException, ViewNotFoundException, SearchServiceException, - SearchServiceConnectionException { + public void delete_privateOwner_succeeds() throws NotAllowedException, DataServiceException, + DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, SearchServiceException, + SearchServiceConnectionException, ViewNotFoundException { /* test */ delete_generic(DATABASE_1_ID, DATABASE_1, VIEW_1_ID, VIEW_1, USER_1_PRINCIPAL, USER_1_ID, USER_1, DATABASE_1_USER_1_WRITE_ALL_ACCESS); @@ -476,7 +476,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { protected void delete_generic(Long databaseId, Database database, Long viewId, View view, Principal principal, UUID userId, User user, DatabaseAccess access) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, - ViewNotFoundException, SearchServiceException, SearchServiceConnectionException { + SearchServiceException, SearchServiceConnectionException, ViewNotFoundException { /* mock */ when(databaseService.findById(databaseId)) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java index 474db3910b..6a01ae6fec 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java @@ -146,8 +146,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().doesNotExist("X-Port")) .andExpect(header().doesNotExist("X-Type")) .andExpect(header().doesNotExist("X-Database")) - .andExpect(header().doesNotExist("X-Sidecar-Host")) - .andExpect(header().doesNotExist("X-Sidecar-Port")) + .andExpect(header().doesNotExist("X-Table")) .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @@ -167,9 +166,8 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) .andExpect(header().string("X-Type", IMAGE_1_JDBC)) .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("X-Sidecar-Host", CONTAINER_1_SIDECAR_HOST)) - .andExpect(header().string("X-Sidecar-Port", "" + CONTAINER_1_SIDECAR_PORT)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Sidecar-Host X-Sidecar-Port")) + .andExpect(header().string("X-Table", TABLE_1_INTERNALNAME)) + .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Table")) .andExpect(status().isOk()); } @@ -186,9 +184,8 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) .andExpect(header().string("X-Type", IMAGE_1_JDBC)) .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("X-Sidecar-Host", CONTAINER_1_SIDECAR_HOST)) - .andExpect(header().string("X-Sidecar-Port", "" + CONTAINER_1_SIDECAR_PORT)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Sidecar-Host X-Sidecar-Port")) + .andExpect(header().string("X-Table", TABLE_1_INTERNALNAME)) + .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Table")) .andExpect(status().isOk()); } @@ -207,6 +204,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().doesNotExist("X-Port")) .andExpect(header().doesNotExist("X-Type")) .andExpect(header().doesNotExist("X-Database")) + .andExpect(header().doesNotExist("X-View")) .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @@ -226,7 +224,8 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) .andExpect(header().string("X-Type", IMAGE_1_JDBC)) .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database")) + .andExpect(header().string("X-View", VIEW_1_INTERNAL_NAME)) + .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View")) .andExpect(status().isOk()); } @@ -243,7 +242,8 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) .andExpect(header().string("X-Type", IMAGE_1_JDBC)) .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database")) + .andExpect(header().string("X-View", VIEW_1_INTERNAL_NAME)) + .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View")) .andExpect(status().isOk()); } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java index 51b6df4d27..436ccd1879 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java @@ -70,8 +70,6 @@ public class DatabaseServicePersistenceTest extends AbstractUnitTest { assertEquals(CONTAINER_1_UI_HOST, response.getContainer().getUiHost()); assertEquals(CONTAINER_1_UI_PORT, response.getContainer().getUiPort()); assertEquals(CONTAINER_1_UI_ADDITIONAL_FLAGS, response.getContainer().getUiAdditionalFlags()); - assertEquals(CONTAINER_1_SIDECAR_HOST, response.getContainer().getSidecarHost()); - assertEquals(CONTAINER_1_SIDECAR_PORT, response.getContainer().getSidecarPort()); assertEquals(CONTAINER_1_PRIVILEGED_USERNAME, response.getContainer().getPrivilegedUsername()); assertEquals(CONTAINER_1_PRIVILEGED_PASSWORD, response.getContainer().getPrivilegedPassword()); assertNotNull(response.getContainer().getImage()); @@ -110,8 +108,6 @@ public class DatabaseServicePersistenceTest extends AbstractUnitTest { assertEquals(CONTAINER_1_UI_HOST, response.getContainer().getUiHost()); assertEquals(CONTAINER_1_UI_PORT, response.getContainer().getUiPort()); assertEquals(CONTAINER_1_UI_ADDITIONAL_FLAGS, response.getContainer().getUiAdditionalFlags()); - assertEquals(CONTAINER_1_SIDECAR_HOST, response.getContainer().getSidecarHost()); - assertEquals(CONTAINER_1_SIDECAR_PORT, response.getContainer().getSidecarPort()); assertEquals(CONTAINER_1_PRIVILEGED_USERNAME, response.getContainer().getPrivilegedUsername()); assertEquals(CONTAINER_1_PRIVILEGED_PASSWORD, response.getContainer().getPrivilegedPassword()); assertNotNull(response.getContainer().getImage()); diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index 767697c1e2..7e6154be62 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -976,8 +976,6 @@ public abstract class BaseTest { public final static Integer CONTAINER_1_COUNT = 3; public final static String CONTAINER_1_HOST = "localhost"; public final static Integer CONTAINER_1_PORT = 3308; - public final static String CONTAINER_1_SIDECAR_HOST = "localhost"; - public final static Integer CONTAINER_1_SIDECAR_PORT = 33081; public final static String CONTAINER_1_PRIVILEGED_USERNAME = "root"; public final static String CONTAINER_1_PRIVILEGED_PASSWORD = "dbrepo"; public final static Instant CONTAINER_1_CREATED = Instant.ofEpochSecond(1677399629L) /* 2023-02-26 08:20:29 (UTC) */; @@ -996,8 +994,6 @@ public abstract class BaseTest { .uiAdditionalFlags(CONTAINER_1_UI_ADDITIONAL_FLAGS) .privilegedUsername(CONTAINER_1_PRIVILEGED_USERNAME) .privilegedPassword(CONTAINER_1_PRIVILEGED_PASSWORD) - .sidecarHost(CONTAINER_1_SIDECAR_HOST) - .sidecarPort(CONTAINER_1_SIDECAR_PORT) .build(); public final static ContainerDto CONTAINER_1_DTO = ContainerDto.builder() @@ -1027,8 +1023,6 @@ public abstract class BaseTest { .created(CONTAINER_1_CREATED) .host(CONTAINER_1_HOST) .port(CONTAINER_1_PORT) - .sidecarHost(CONTAINER_1_SIDECAR_HOST) - .sidecarPort(CONTAINER_1_SIDECAR_PORT) .username(CONTAINER_1_PRIVILEGED_USERNAME) .password(CONTAINER_1_PRIVILEGED_PASSWORD) .build(); @@ -1041,8 +1035,6 @@ public abstract class BaseTest { public final static String CONTAINER_2_IP = "172.30.0.6"; public final static String CONTAINER_2_HOST = "localhost"; public final static Integer CONTAINER_2_PORT = 3309; - public final static String CONTAINER_2_SIDECAR_HOST = "localhost"; - public final static Integer CONTAINER_2_SIDECAR_PORT = 33091; public final static Integer CONTAINER_2_QUOTA = 3; public final static Integer CONTAINER_2_COUNT = 3; public final static String CONTAINER_2_PRIVILEGED_USERNAME = "root"; @@ -1089,8 +1081,6 @@ public abstract class BaseTest { public final static String CONTAINER_3_HOST = "localhost"; public final static Integer CONTAINER_3_PORT = 3310; public final static Integer CONTAINER_3_QUOTA = 20; - public final static String CONTAINER_3_SIDECAR_HOST = "localhost"; - public final static Integer CONTAINER_3_SIDECAR_PORT = 33101; public final static String CONTAINER_3_PRIVILEGED_USERNAME = "root"; public final static String CONTAINER_3_PRIVILEGED_PASSWORD = "dbrepo"; public final static Instant CONTAINER_3_CREATED = Instant.ofEpochSecond(1677399672L) /* 2023-02-26 08:21:12 (UTC) */; @@ -1117,8 +1107,6 @@ public abstract class BaseTest { public final static String CONTAINER_4_HOST = "localhost"; public final static Integer CONTAINER_4_PORT = 3311; public final static Integer CONTAINER_4_QUOTA = 0; - public final static String CONTAINER_4_SIDECAR_HOST = "localhost"; - public final static Integer CONTAINER_4_SIDECAR_PORT = 33111; public final static String CONTAINER_4_PRIVILEGED_USERNAME = "root"; public final static String CONTAINER_4_PRIVILEGED_PASSWORD = "dbrepo"; public final static Instant CONTAINER_4_CREATED = Instant.ofEpochSecond(1677399688L) /* 2023-02-26 08:21:28 (UTC) */; diff --git a/dbrepo-metric-db/prometheus.yml b/dbrepo-metric-db/prometheus.yml index 10df4f1895..92ecf83adc 100644 --- a/dbrepo-metric-db/prometheus.yml +++ b/dbrepo-metric-db/prometheus.yml @@ -16,7 +16,7 @@ scrape_configs: - job_name: 'metrics scrape' metrics_path: '/metrics' static_configs: - - targets: ['ui:3000', 'auth-service:9000', 'analyse-service:8080', 'search-service:8080', 'data-db-sidecar:8080', 'broker-service:15692', 'storage-service:9090', 'upload-service:8080', 'dashboard-service:3000'] + - targets: ['ui:3000', 'compute-service:8080', 'auth-service:9000', 'analyse-service:8080', 'search-service:8080', 'data-db-sidecar:8080', 'broker-service:15692', 'storage-service:9090', 'upload-service:8080', 'dashboard-service:3000'] # - job_name: 'gateway scrape' # metrics_path: '/metrics' # static_configs: diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock index 123e864f6d..fc5839fcdb 100644 --- a/dbrepo-search-service/Pipfile.lock +++ b/dbrepo-search-service/Pipfile.lock @@ -355,40 +355,40 @@ }, "cryptography": { "hashes": [ - "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", - "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", - "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", - "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", - "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2", - "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", - "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", - "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", - "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", - "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", - "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d", - "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", - "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2", - "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", - "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", - "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", - "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", - "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", - "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", - "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", - "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", - "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", - "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", - "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", - "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", - "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", - "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289" + "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", + "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa", + "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83", + "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff", + "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", + "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664", + "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08", + "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", + "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", + "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", + "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", + "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", + "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", + "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3", + "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", + "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", + "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c", + "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", + "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7", + "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", + "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7" ], "markers": "python_version >= '3.7'", - "version": "==43.0.1" + "version": "==43.0.3" }, "dbrepo": { "hashes": [ - "sha256:84607677b0826bb9b2fa120aacdf56d16c8d9ae423f435b2bd2c22b1c965a33c" + "sha256:36316d520c23dcbd249b779ad596a979fe574321882a7d4b6c6934c62a5de57b" ], "path": "./lib/dbrepo-1.4.7.tar.gz" }, @@ -458,86 +458,101 @@ }, "frozenlist": { "hashes": [ - "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", - "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", - "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", - "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", - "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", - "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", - "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", - "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", - "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", - "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", - "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", - "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", - "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", - "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", - "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", - "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", - "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", - "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", - "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", - "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", - "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", - "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", - "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", - "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", - "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", - "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", - "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", - "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", - "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", - "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", - "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", - "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", - "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", - "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", - "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", - "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", - "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", - "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", - "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", - "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", - "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", - "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", - "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", - "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", - "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", - "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", - "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", - "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", - "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", - "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", - "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", - "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", - "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", - "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", - "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", - "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", - "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", - "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", - "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", - "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", - "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", - "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", - "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", - "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", - "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", - "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", - "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", - "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", - "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", - "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", - "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", - "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", - "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", - "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", - "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", - "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", - "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" + "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", + "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", + "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6", + "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", + "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", + "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f", + "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", + "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", + "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", + "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", + "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", + "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2", + "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c", + "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336", + "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", + "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", + "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b", + "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c", + "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10", + "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08", + "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", + "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", + "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f", + "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10", + "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", + "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", + "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", + "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", + "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d", + "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923", + "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", + "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", + "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", + "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0", + "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", + "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", + "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", + "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", + "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0", + "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", + "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", + "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", + "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3", + "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", + "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", + "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604", + "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", + "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", + "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", + "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", + "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", + "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", + "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", + "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", + "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3", + "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", + "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", + "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", + "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf", + "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", + "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", + "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171", + "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", + "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", + "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", + "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972", + "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", + "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", + "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9", + "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411", + "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723", + "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", + "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b", + "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99", + "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e", + "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", + "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", + "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", + "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", + "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", + "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca", + "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", + "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", + "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", + "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", + "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307", + "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e", + "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", + "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", + "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", + "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", + "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a" ], "markers": "python_version >= '3.8'", - "version": "==1.4.1" + "version": "==1.5.0" }, "greenlet": { "hashes": [ @@ -643,13 +658,6 @@ "markers": "python_version >= '3.7'", "version": "==2.0.0" }, - "isodate": { - "hashes": [ - "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", - "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" - ], - "version": "==0.6.1" - }, "itsdangerous": { "hashes": [ "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", @@ -692,70 +700,70 @@ }, "markupsafe": { "hashes": [ - "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", - "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", - "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", - "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", - "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", - "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", - "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", - "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", - "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", - "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", - "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", - "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", - "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", - "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", - "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", - "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", - "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", - "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", - "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", - "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", - "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", - "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", - "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", - "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", - "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", - "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", - "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", - "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", - "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", - "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", - "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", - "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", - "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", - "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", - "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", - "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", - "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", - "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", - "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", - "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", - "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", - "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", - "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", - "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", - "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", - "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", - "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", - "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", - "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", - "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", - "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", - "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", - "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", - "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", - "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", - "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", - "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", - "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", - "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", - "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", - "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" ], "markers": "python_version >= '3.9'", - "version": "==3.0.1" + "version": "==3.0.2" }, "mistune": { "hashes": [ @@ -865,62 +873,64 @@ }, "numpy": { "hashes": [ - "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", - "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", - "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", - "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", - "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", - "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", - "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", - "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", - "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", - "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", - "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", - "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", - "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", - "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", - "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", - "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", - "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", - "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", - "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", - "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", - "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", - "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", - "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", - "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", - "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", - "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", - "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", - "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", - "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", - "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", - "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", - "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", - "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", - "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", - "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", - "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", - "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", - "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", - "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", - "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", - "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", - "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", - "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", - "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", - "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", - "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", - "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", - "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", - "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", - "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", - "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", - "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", - "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe", + "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", + "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48", + "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", + "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", + "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", + "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17", + "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", + "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", + "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", + "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4", + "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", + "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6", + "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4", + "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", + "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", + "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f", + "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f", + "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56", + "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", + "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", + "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", + "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed", + "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", + "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", + "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", + "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", + "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f", + "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", + "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f", + "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", + "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", + "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0", + "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", + "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef", + "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", + "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e", + "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", + "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", + "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43", + "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", + "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", + "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", + "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408", + "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", + "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", + "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57", + "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", + "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", + "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", + "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a", + "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", + "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", + "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598", + "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4" ], "markers": "python_version == '3.11'", - "version": "==2.1.2" + "version": "==2.1.3" }, "opensearch-py": { "hashes": [ @@ -1344,12 +1354,12 @@ }, "rdflib": { "hashes": [ - "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd", - "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae" + "sha256:164de86bd3564558802ca983d84f6616a4a1a420c7a17a8152f5016076b2913e", + "sha256:e590fa9a2c34ba33a667818b5a84be3fb8a4d85868f8038f17912ec84f912a25" ], "index": "pypi", "markers": "python_full_version >= '3.8.1' and python_full_version < '4.0.0'", - "version": "==7.0.0" + "version": "==7.1.1" }, "referencing": { "hashes": [ @@ -1369,112 +1379,112 @@ }, "rpds-py": { "hashes": [ - "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", - "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", - "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", - "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", - "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", - "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", - "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", - "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", - "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", - "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", - "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", - "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", - "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", - "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", - "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", - "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", - "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", - "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", - "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", - "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", - "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", - "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", - "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", - "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", - "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", - "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", - "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", - "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", - "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", - "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", - "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", - "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", - "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", - "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", - "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", - "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", - "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", - "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", - "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", - "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", - "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", - "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", - "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", - "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", - "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", - "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", - "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", - "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", - "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", - "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", - "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", - "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", - "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", - "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", - "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", - "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", - "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", - "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", - "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", - "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", - "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", - "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", - "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", - "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", - "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", - "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", - "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", - "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", - "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", - "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", - "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", - "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", - "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", - "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", - "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", - "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", - "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", - "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", - "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", - "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", - "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", - "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", - "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", - "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", - "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", - "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", - "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", - "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", - "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", - "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", - "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", - "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", - "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", - "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", - "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", - "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", - "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", - "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", - "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", - "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", - "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", - "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", - "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + "sha256:02a0629ec053fc013808a85178524e3cb63a61dbc35b22499870194a63578fb9", + "sha256:07924c1b938798797d60c6308fa8ad3b3f0201802f82e4a2c41bb3fafb44cc28", + "sha256:07f59760ef99f31422c49038964b31c4dfcfeb5d2384ebfc71058a7c9adae2d2", + "sha256:0a3a1e9ee9728b2c1734f65d6a1d376c6f2f6fdcc13bb007a08cc4b1ff576dc5", + "sha256:0a90c373ea2975519b58dece25853dbcb9779b05cc46b4819cb1917e3b3215b6", + "sha256:0ad56edabcdb428c2e33bbf24f255fe2b43253b7d13a2cdbf05de955217313e6", + "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712", + "sha256:0f8f741b6292c86059ed175d80eefa80997125b7c478fb8769fd9ac8943a16c0", + "sha256:0fc212779bf8411667234b3cdd34d53de6c2b8b8b958e1e12cb473a5f367c338", + "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86", + "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c", + "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c", + "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f", + "sha256:16d4477bcb9fbbd7b5b0e4a5d9b493e42026c0bf1f06f723a9353f5153e75d30", + "sha256:1791ff70bc975b098fe6ecf04356a10e9e2bd7dc21fa7351c1742fdeb9b4966f", + "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd", + "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e", + "sha256:2249280b870e6a42c0d972339e9cc22ee98730a99cd7f2f727549af80dd5a963", + "sha256:2b431c777c9653e569986ecf69ff4a5dba281cded16043d348bf9ba505486f36", + "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2", + "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e", + "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d", + "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17", + "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb", + "sha256:3aea7eed3e55119635a74bbeb80b35e776bafccb70d97e8ff838816c124539f1", + "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5", + "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163", + "sha256:3d089d0b88996df627693639d123c8158cff41c0651f646cd8fd292c7da90eaf", + "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356", + "sha256:3e310838a5801795207c66c73ea903deda321e6146d6f282e85fa7e3e4854804", + "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93", + "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a", + "sha256:4888e117dd41b9d34194d9e31631af70d3d526efc363085e3089ab1a62c32ed1", + "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496", + "sha256:4a5a844f68776a7715ecb30843b453f07ac89bad393431efbf7accca3ef599c1", + "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0", + "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899", + "sha256:518d2ca43c358929bf08f9079b617f1c2ca6e8848f83c1225c88caeac46e6cbc", + "sha256:5265505b3d61a0f56618c9b941dc54dc334dc6e660f1592d112cd103d914a6db", + "sha256:55cd1fa4ecfa6d9f14fbd97ac24803e6f73e897c738f771a9fe038f2f11ff07c", + "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8", + "sha256:59240685e7da61fb78f65a9f07f8108e36a83317c53f7b276b4175dc44151684", + "sha256:5b48e790e0355865197ad0aca8cde3d8ede347831e1959e158369eb3493d2191", + "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06", + "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff", + "sha256:653647b8838cf83b2e7e6a0364f49af96deec64d2a6578324db58380cff82aca", + "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8", + "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc", + "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a", + "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7", + "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4", + "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751", + "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e", + "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b", + "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75", + "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e", + "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74", + "sha256:7dca7081e9a0c3b6490a145593f6fe3173a94197f2cb9891183ef75e9d64c425", + "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84", + "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d", + "sha256:83cba698cfb3c2c5a7c3c6bac12fe6c6a51aae69513726be6411076185a8b24a", + "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a", + "sha256:84b8382a90539910b53a6307f7c35697bc7e6ffb25d9c1d4e998a13e842a5e83", + "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535", + "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb", + "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd", + "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979", + "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d", + "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d", + "sha256:9c4cb04a16b0f199a8c9bf807269b2f63b7b5b11425e4a6bd44bd6961d28282c", + "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782", + "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad", + "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75", + "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4", + "sha256:b41b6321805c472f66990c2849e152aff7bc359eb92f781e3f606609eac877ad", + "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e", + "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c", + "sha256:bb63804105143c7e24cee7db89e37cb3f3941f8e80c4379a0b355c52a52b6780", + "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01", + "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf", + "sha256:c14937af98c4cc362a1d4374806204dd51b1e12dded1ae30645c298e5a5c4cb1", + "sha256:ca449520e7484534a2a44faf629362cae62b660601432d04c482283c47eaebab", + "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732", + "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa", + "sha256:d126b52e4a473d40232ec2052a8b232270ed1f8c9571aaf33f73a14cc298c24f", + "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3", + "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711", + "sha256:da584ff96ec95e97925174eb8237e32f626e7a1a97888cdd27ee2f1f24dd0ad8", + "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a", + "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d", + "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c", + "sha256:e13de156137b7095442b288e72f33503a469aa1980ed856b43c353ac86390519", + "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350", + "sha256:e75ba609dba23f2c95b776efb9dd3f0b78a76a151e96f96cc5b6b1b0004de66f", + "sha256:e79059d67bea28b53d255c1437b25391653263f0e69cd7dec170d778fdbca95e", + "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb", + "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc", + "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f", + "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977", + "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311", + "sha256:fa41a64ac5b08b292906e248549ab48b69c5428f3987b09689ab2441f267d04d", + "sha256:fbf15aff64a163db29a91ed0868af181d6f68ec1a3a7d5afcfe4501252840bad", + "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982" ], "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "version": "==0.20.1" }, "six": { "hashes": [ @@ -1486,58 +1496,66 @@ }, "sqlalchemy": { "hashes": [ - "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9", - "sha256:032d979ce77a6c2432653322ba4cbeabf5a6837f704d16fa38b5a05d8e21fa00", - "sha256:0375a141e1c0878103eb3d719eb6d5aa444b490c96f3fedab8471c7f6ffe70ee", - "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6", - "sha256:05c3f58cf91683102f2f0265c0db3bd3892e9eedabe059720492dbaa4f922da1", - "sha256:0630774b0977804fba4b6bbea6852ab56c14965a2b0c7fc7282c5f7d90a1ae72", - "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf", - "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8", - "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b", - "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc", - "sha256:2a275a806f73e849e1c309ac11108ea1a14cd7058577aba962cd7190e27c9e3c", - "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1", - "sha256:2e795c2f7d7249b75bb5f479b432a51b59041580d20599d4e112b5f2046437a3", - "sha256:3655af10ebcc0f1e4e06c5900bb33e080d6a1fa4228f502121f28a3b1753cde5", - "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90", - "sha256:4c31943b61ed8fdd63dfd12ccc919f2bf95eefca133767db6fbbd15da62078ec", - "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71", - "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7", - "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b", - "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468", - "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3", - "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e", - "sha256:732e026240cdd1c1b2e3ac515c7a23820430ed94292ce33806a95869c46bd139", - "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff", - "sha256:890da8cd1941fa3dab28c5bac3b9da8502e7e366f895b3b8e500896f12f94d11", - "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01", - "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62", - "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d", - "sha256:8d625eddf7efeba2abfd9c014a22c0f6b3796e0ffb48f5d5ab106568ef01ff5a", - "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db", - "sha256:9509c4123491d0e63fb5e16199e09f8e262066e58903e84615c301dde8fa2e87", - "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e", - "sha256:a62dd5d7cc8626a3634208df458c5fe4f21200d96a74d122c83bc2015b333bc1", - "sha256:ada603db10bb865bbe591939de854faf2c60f43c9b763e90f653224138f910d9", - "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f", - "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0", - "sha256:c0d8326269dbf944b9201911b0d9f3dc524d64779a07518199a58384c3d37a44", - "sha256:c41411e192f8d3ea39ea70e0fae48762cd11a2244e03751a98bd3c0ca9a4e936", - "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8", - "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea", - "sha256:cc32b2990fc34380ec2f6195f33a76b6cdaa9eecf09f0c9404b74fc120aef36f", - "sha256:ccae5de2a0140d8be6838c331604f91d6fafd0735dbdcee1ac78fc8fbaba76b4", - "sha256:d299797d75cd747e7797b1b41817111406b8b10a4f88b6e8fe5b5e59598b43b0", - "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c", - "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f", - "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60", - "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2", - "sha256:f021d334f2ca692523aaf7bbf7592ceff70c8594fad853416a81d66b35e3abf9", - "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33" + "sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763", + "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", + "sha256:07b441f7d03b9a66299ce7ccf3ef2900abc81c0db434f42a5694a37bd73870f2", + "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", + "sha256:1e0d612a17581b6616ff03c8e3d5eff7452f34655c901f75d62bd86449d9750e", + "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", + "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", + "sha256:28120ef39c92c2dd60f2721af9328479516844c6b550b077ca450c7d7dc68575", + "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", + "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", + "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", + "sha256:3d6718667da04294d7df1670d70eeddd414f313738d20a6f1d1f379e3139a545", + "sha256:3dbb986bad3ed5ceaf090200eba750b5245150bd97d3e67343a3cfed06feecf7", + "sha256:4557e1f11c5f653ebfdd924f3f9d5ebfc718283b0b9beebaa5dd6b77ec290971", + "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", + "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", + "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", + "sha256:50aae840ebbd6cdd41af1c14590e5741665e5272d2fee999306673a1bb1fdb4d", + "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", + "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", + "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", + "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", + "sha256:6a440293d802d3011028e14e4226da1434b373cbaf4a4bbb63f845761a708346", + "sha256:72c28b84b174ce8af8504ca28ae9347d317f9dba3999e5981a3cd441f3712e24", + "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", + "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", + "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", + "sha256:8958b10490125124463095bbdadda5aa22ec799f91958e410438ad6c97a7b793", + "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", + "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", + "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", + "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", + "sha256:9fe53b404f24789b5ea9003fc25b9a3988feddebd7e7b369c8fac27ad6f52f28", + "sha256:a4e46a888b54be23d03a89be510f24a7652fe6ff660787b96cd0e57a4ebcb46d", + "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", + "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", + "sha256:af148a33ff0349f53512a049c6406923e4e02bf2f26c5fb285f143faf4f0e46a", + "sha256:b11d0cfdd2b095e7b0686cf5fabeb9c67fae5b06d265d8180715b8cfa86522e3", + "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", + "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", + "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", + "sha256:b817d41d692bf286abc181f8af476c4fbef3fd05e798777492618378448ee689", + "sha256:b81ee3d84803fd42d0b154cb6892ae57ea6b7c55d8359a02379965706c7efe6c", + "sha256:be9812b766cad94a25bc63bec11f88c4ad3629a0cec1cd5d4ba48dc23860486b", + "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", + "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", + "sha256:c4ae3005ed83f5967f961fd091f2f8c5329161f69ce8480aa8168b2d7fe37f06", + "sha256:c54a1e53a0c308a8e8a7dffb59097bff7facda27c70c286f005327f21b2bd6b1", + "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", + "sha256:dc022184d3e5cacc9579e41805a681187650e170eb2fd70e28b86192a479dcaa", + "sha256:e32092c47011d113dc01ab3e1d3ce9f006a47223b18422c5c0d150af13a00687", + "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", + "sha256:f942a799516184c855e1a32fbc7b29d7e571b52612647866d4ec1c3242578fcb", + "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", + "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", + "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", + "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53" ], "markers": "python_version >= '3.7'", - "version": "==2.0.35" + "version": "==2.0.36" }, "sqlalchemy-utils": { "hashes": [ @@ -1605,11 +1623,11 @@ }, "werkzeug": { "hashes": [ - "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c", - "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306" + "sha256:8cd39dfbdfc1e051965f156163e2974e52c210f130810e9ad36858f0fd3edad4", + "sha256:a71124d1ef06008baafa3d266c02f56e1836a5984afd6dd6c9230669d60d9fb5" ], - "markers": "python_version >= '3.8'", - "version": "==3.0.4" + "markers": "python_version >= '3.9'", + "version": "==3.1.1" }, "wrapt": { "hashes": [ @@ -1689,107 +1707,91 @@ }, "yarl": { "hashes": [ - "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e", - "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c", - "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747", - "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179", - "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a", - "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936", - "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19", - "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8", - "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed", - "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2", - "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33", - "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057", - "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548", - "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c", - "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b", - "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f", - "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9", - "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f", - "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a", - "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04", - "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50", - "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2", - "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46", - "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01", - "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5", - "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf", - "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935", - "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84", - "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d", - "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5", - "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c", - "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7", - "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9", - "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367", - "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad", - "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d", - "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d", - "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea", - "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7", - "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf", - "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b", - "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036", - "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc", - "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec", - "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b", - "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627", - "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368", - "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810", - "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94", - "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50", - "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6", - "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb", - "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b", - "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7", - "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931", - "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178", - "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d", - "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f", - "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2", - "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5", - "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc", - "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84", - "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b", - "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172", - "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644", - "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f", - "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776", - "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd", - "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04", - "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956", - "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4", - "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7", - "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8", - "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb", - "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053", - "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe", - "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a", - "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b", - "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb", - "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417", - "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c", - "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980", - "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47", - "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b", - "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904", - "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8", - "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0", - "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611", - "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2", - "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d", - "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715", - "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897", - "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046", - "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b", - "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e", - "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16", - "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d", - "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75" + "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", + "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", + "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", + "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", + "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", + "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", + "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", + "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", + "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5", + "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", + "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", + "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", + "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", + "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", + "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", + "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", + "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", + "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", + "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", + "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", + "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", + "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", + "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", + "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", + "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", + "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857", + "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", + "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", + "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", + "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", + "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", + "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", + "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934", + "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473", + "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", + "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", + "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", + "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", + "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71", + "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", + "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", + "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", + "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", + "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6", + "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", + "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", + "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", + "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", + "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", + "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", + "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f", + "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", + "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", + "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", + "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95", + "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383", + "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e", + "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", + "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", + "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55", + "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", + "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", + "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", + "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", + "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", + "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", + "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", + "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", + "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", + "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c", + "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29", + "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", + "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", + "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", + "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", + "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138", + "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", + "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004", + "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159", + "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", + "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", + "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75" ], - "markers": "python_version >= '3.8'", - "version": "==1.15.2" + "markers": "python_version >= '3.9'", + "version": "==1.17.1" } }, "develop": { @@ -1914,72 +1916,72 @@ }, "coverage": { "hashes": [ - "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6", - "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2", - "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba", - "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb", - "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6", - "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4", - "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0", - "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6", - "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990", - "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3", - "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43", - "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175", - "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a", - "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6", - "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97", - "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b", - "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e", - "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39", - "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd", - "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d", - "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f", - "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc", - "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976", - "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549", - "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c", - "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5", - "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4", - "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b", - "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e", - "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3", - "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6", - "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e", - "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929", - "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234", - "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13", - "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007", - "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3", - "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167", - "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d", - "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d", - "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40", - "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181", - "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054", - "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd", - "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2", - "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91", - "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3", - "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b", - "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38", - "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd", - "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f", - "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2", - "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba", - "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f", - "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83", - "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce", - "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38", - "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c", - "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f", - "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21", - "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4", - "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92" + "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", + "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", + "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", + "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", + "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", + "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", + "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", + "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", + "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", + "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", + "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", + "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", + "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", + "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", + "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", + "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", + "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", + "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", + "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", + "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", + "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", + "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", + "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", + "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", + "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", + "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", + "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", + "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", + "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", + "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", + "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", + "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", + "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", + "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", + "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", + "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", + "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", + "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", + "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", + "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", + "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", + "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", + "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", + "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", + "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", + "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", + "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", + "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", + "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", + "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", + "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", + "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", + "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", + "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", + "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", + "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", + "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", + "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", + "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", + "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", + "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", + "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.6.3" + "version": "==7.6.4" }, "idna": { "hashes": [ diff --git a/dbrepo-search-service/init/Pipfile.lock b/dbrepo-search-service/init/Pipfile.lock index 75bdbc29f9..de0064f408 100644 --- a/dbrepo-search-service/init/Pipfile.lock +++ b/dbrepo-search-service/init/Pipfile.lock @@ -282,7 +282,7 @@ }, "dbrepo": { "hashes": [ - "sha256:84607677b0826bb9b2fa120aacdf56d16c8d9ae423f435b2bd2c22b1c965a33c" + "sha256:36316d520c23dcbd249b779ad596a979fe574321882a7d4b6c6934c62a5de57b" ], "path": "./lib/dbrepo-1.4.7.tar.gz" }, @@ -311,86 +311,101 @@ }, "frozenlist": { "hashes": [ - "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", - "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", - "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", - "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", - "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", - "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", - "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", - "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", - "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", - "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", - "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", - "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", - "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", - "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", - "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", - "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", - "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", - "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", - "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", - "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", - "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", - "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", - "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", - "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", - "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", - "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", - "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", - "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", - "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", - "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", - "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", - "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", - "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", - "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", - "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", - "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", - "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", - "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", - "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", - "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", - "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", - "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", - "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", - "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", - "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", - "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", - "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", - "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", - "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", - "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", - "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", - "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", - "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", - "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", - "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", - "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", - "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", - "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", - "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", - "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", - "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", - "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", - "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", - "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", - "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", - "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", - "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", - "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", - "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", - "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", - "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", - "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", - "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", - "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", - "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", - "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", - "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" + "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", + "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", + "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6", + "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", + "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", + "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f", + "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", + "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", + "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", + "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", + "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", + "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2", + "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c", + "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336", + "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", + "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", + "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b", + "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c", + "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10", + "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08", + "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", + "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", + "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f", + "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10", + "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", + "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", + "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", + "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", + "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d", + "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923", + "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", + "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", + "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", + "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0", + "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", + "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", + "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", + "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", + "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0", + "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", + "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", + "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", + "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3", + "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", + "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", + "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604", + "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", + "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", + "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", + "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", + "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", + "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", + "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", + "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", + "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3", + "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", + "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", + "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", + "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf", + "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", + "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", + "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171", + "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", + "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", + "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", + "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972", + "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", + "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", + "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9", + "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411", + "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723", + "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", + "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b", + "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99", + "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e", + "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", + "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", + "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", + "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", + "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", + "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca", + "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", + "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", + "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", + "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", + "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307", + "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e", + "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", + "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", + "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", + "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", + "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a" ], "markers": "python_version >= '3.8'", - "version": "==1.4.1" + "version": "==1.5.0" }, "idna": { "hashes": [ @@ -408,13 +423,6 @@ "markers": "python_version >= '3.7'", "version": "==2.0.0" }, - "isodate": { - "hashes": [ - "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", - "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" - ], - "version": "==0.6.1" - }, "itsdangerous": { "hashes": [ "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", @@ -433,70 +441,70 @@ }, "markupsafe": { "hashes": [ - "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", - "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", - "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", - "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", - "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", - "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", - "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", - "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", - "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", - "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", - "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", - "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", - "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", - "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", - "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", - "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", - "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", - "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", - "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", - "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", - "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", - "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", - "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", - "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", - "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", - "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", - "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", - "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", - "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", - "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", - "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", - "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", - "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", - "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", - "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", - "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", - "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", - "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", - "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", - "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", - "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", - "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", - "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", - "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", - "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", - "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", - "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", - "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", - "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", - "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", - "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", - "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", - "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", - "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", - "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", - "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", - "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", - "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", - "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", - "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", - "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" ], "markers": "python_version >= '3.9'", - "version": "==3.0.1" + "version": "==3.0.2" }, "multidict": { "hashes": [ @@ -598,62 +606,64 @@ }, "numpy": { "hashes": [ - "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", - "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", - "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", - "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", - "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", - "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", - "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", - "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", - "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", - "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", - "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", - "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", - "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", - "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", - "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", - "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", - "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", - "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", - "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", - "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", - "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", - "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", - "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", - "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", - "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", - "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", - "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", - "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", - "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", - "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", - "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", - "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", - "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", - "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", - "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", - "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", - "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", - "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", - "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", - "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", - "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", - "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", - "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", - "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", - "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", - "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", - "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", - "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", - "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", - "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", - "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", - "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", - "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe", + "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", + "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48", + "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", + "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", + "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", + "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17", + "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", + "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", + "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", + "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4", + "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", + "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6", + "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4", + "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", + "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", + "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f", + "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f", + "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56", + "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", + "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", + "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", + "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed", + "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", + "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", + "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", + "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", + "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f", + "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", + "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f", + "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", + "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", + "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0", + "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", + "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef", + "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", + "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e", + "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", + "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", + "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43", + "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", + "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", + "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", + "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408", + "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", + "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", + "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57", + "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", + "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", + "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", + "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a", + "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", + "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", + "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598", + "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4" ], "markers": "python_version == '3.11'", - "version": "==2.1.2" + "version": "==2.1.3" }, "opensearch-py": { "hashes": [ @@ -986,12 +996,12 @@ }, "rdflib": { "hashes": [ - "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd", - "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae" + "sha256:164de86bd3564558802ca983d84f6616a4a1a420c7a17a8152f5016076b2913e", + "sha256:e590fa9a2c34ba33a667818b5a84be3fb8a4d85868f8038f17912ec84f912a25" ], "index": "pypi", "markers": "python_full_version >= '3.8.1' and python_full_version < '4.0.0'", - "version": "==7.0.0" + "version": "==7.1.1" }, "requests": { "hashes": [ @@ -1066,11 +1076,11 @@ }, "werkzeug": { "hashes": [ - "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c", - "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306" + "sha256:8cd39dfbdfc1e051965f156163e2974e52c210f130810e9ad36858f0fd3edad4", + "sha256:a71124d1ef06008baafa3d266c02f56e1836a5984afd6dd6c9230669d60d9fb5" ], - "markers": "python_version >= '3.8'", - "version": "==3.0.4" + "markers": "python_version >= '3.9'", + "version": "==3.1.1" }, "wrapt": { "hashes": [ @@ -1150,178 +1160,162 @@ }, "yarl": { "hashes": [ - "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e", - "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c", - "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747", - "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179", - "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a", - "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936", - "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19", - "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8", - "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed", - "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2", - "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33", - "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057", - "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548", - "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c", - "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b", - "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f", - "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9", - "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f", - "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a", - "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04", - "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50", - "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2", - "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46", - "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01", - "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5", - "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf", - "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935", - "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84", - "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d", - "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5", - "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c", - "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7", - "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9", - "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367", - "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad", - "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d", - "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d", - "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea", - "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7", - "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf", - "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b", - "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036", - "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc", - "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec", - "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b", - "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627", - "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368", - "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810", - "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94", - "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50", - "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6", - "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb", - "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b", - "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7", - "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931", - "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178", - "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d", - "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f", - "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2", - "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5", - "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc", - "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84", - "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b", - "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172", - "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644", - "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f", - "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776", - "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd", - "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04", - "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956", - "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4", - "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7", - "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8", - "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb", - "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053", - "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe", - "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a", - "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b", - "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb", - "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417", - "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c", - "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980", - "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47", - "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b", - "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904", - "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8", - "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0", - "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611", - "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2", - "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d", - "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715", - "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897", - "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046", - "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b", - "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e", - "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16", - "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d", - "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75" + "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", + "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", + "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", + "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", + "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", + "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", + "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", + "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", + "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5", + "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", + "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", + "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", + "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", + "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", + "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", + "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", + "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", + "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", + "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", + "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", + "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", + "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", + "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", + "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", + "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", + "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857", + "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", + "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", + "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", + "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", + "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", + "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", + "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934", + "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473", + "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", + "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", + "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", + "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", + "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71", + "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", + "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", + "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", + "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", + "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6", + "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", + "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", + "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", + "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", + "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", + "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", + "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f", + "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", + "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", + "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", + "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95", + "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383", + "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e", + "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", + "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", + "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55", + "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", + "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", + "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", + "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", + "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", + "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", + "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", + "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", + "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", + "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c", + "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29", + "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", + "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", + "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", + "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", + "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138", + "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", + "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004", + "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159", + "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", + "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", + "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75" ], - "markers": "python_version >= '3.8'", - "version": "==1.15.2" + "markers": "python_version >= '3.9'", + "version": "==1.17.1" } }, "develop": { "coverage": { "hashes": [ - "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6", - "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2", - "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba", - "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb", - "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6", - "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4", - "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0", - "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6", - "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990", - "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3", - "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43", - "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175", - "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a", - "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6", - "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97", - "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b", - "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e", - "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39", - "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd", - "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d", - "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f", - "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc", - "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976", - "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549", - "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c", - "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5", - "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4", - "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b", - "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e", - "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3", - "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6", - "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e", - "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929", - "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234", - "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13", - "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007", - "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3", - "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167", - "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d", - "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d", - "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40", - "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181", - "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054", - "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd", - "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2", - "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91", - "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3", - "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b", - "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38", - "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd", - "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f", - "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2", - "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba", - "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f", - "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83", - "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce", - "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38", - "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c", - "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f", - "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21", - "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4", - "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92" + "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", + "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", + "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", + "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", + "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", + "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", + "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", + "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", + "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", + "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", + "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", + "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", + "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", + "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", + "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", + "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", + "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", + "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", + "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", + "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", + "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", + "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", + "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", + "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", + "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", + "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", + "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", + "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", + "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", + "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", + "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", + "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", + "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", + "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", + "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", + "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", + "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", + "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", + "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", + "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", + "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", + "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", + "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", + "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", + "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", + "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", + "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", + "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", + "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", + "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", + "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", + "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", + "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", + "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", + "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", + "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", + "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", + "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", + "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", + "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", + "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", + "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.6.3" + "version": "==7.6.4" }, "iniconfig": { "hashes": [ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.4.7.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.4.7.tar.gz index c652dbae4a60aae708eb6fe4e751977b97b72344..c85b1225ee9cc1f5386e58bced9b979ff160e982 100644 GIT binary patch literal 39237 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	>r}O$?3gP# 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 Sy?E7M`$e<9sWVitG5`S0lLKx5 literal 39442 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⋘a6uI?z25G^_MT;Y$Tki)wr6C?uqjn_+S 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 XgZy<LNMo{F{Ii#Ry6FbP0#*h9Jtb_G diff --git a/dbrepo-search-service/lib/dbrepo-1.4.7.tar.gz b/dbrepo-search-service/lib/dbrepo-1.4.7.tar.gz index c652dbae4a60aae708eb6fe4e751977b97b72344..c85b1225ee9cc1f5386e58bced9b979ff160e982 100644 GIT binary patch literal 39237 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	>r}O$?3gP# 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 Sy?E7M`$e<9sWVitG5`S0lLKx5 literal 39442 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⋘a6uI?z25G^_MT;Y$Tki)wr6C?uqjn_+S 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 XgZy<LNMo{F{Ii#Ry6FbP0#*h9Jtb_G diff --git a/dbrepo-ui/components/table/TableImport.vue b/dbrepo-ui/components/table/TableImport.vue index 84c1011c9b..14d4dae70a 100644 --- a/dbrepo-ui/components/table/TableImport.vue +++ b/dbrepo-ui/components/table/TableImport.vue @@ -32,18 +32,17 @@ </v-row> <v-row dense> <v-col md="8"> - <v-text-field - v-model.number="tableImport.skip_lines" - :rules="[ - v => isNonNegativeInteger(v) || $t('validation.integer') - ]" - type="number" + <v-select + v-model="tableImport.header" + :items="headers" + item-title="key" + item-value="value" required clearable persistent-hint :variant="inputVariant" :hint="$t('pages.table.subpages.import.skip.hint')" - :label="$t('pages.table.subpages.import.skip.label')"/> + :label="$t('pages.table.subpages.import.skip.label')" /> </v-col> </v-row> <v-row dense> @@ -265,7 +264,6 @@ </template> <script> -import { isNonNegativeInteger } from '@/utils' import { useCacheStore } from '@/stores/cache' export default { @@ -304,7 +302,7 @@ export default { quote: '"', separator: ',', line_termination: '\\n', - skip_lines: 1 + header: true }, separators: [ {key: ',', value: ','}, @@ -315,6 +313,10 @@ export default { {key: 'Double "', value: '"'}, {key: 'Single \'', value: '\''} ], + headers: [ + {key: 'First line is header', value: true}, + {key: 'Data only', value: false} + ], lineTerminationItems: [ {name: '\\r\\n (Windows)', value: '\r\n'}, {name: '\\n (UNIX)', value: '\n'}, @@ -329,7 +331,7 @@ export default { this.setQueryParamSafely('quote') this.setQueryParamSafely('separator') this.setQueryParamSafely('line_termination') - this.setQueryParamSafely('skip_lines') + this.setQueryParamSafely('header', true) if (this.$route.query.location) { this.step = 2 this.validStep2 = true @@ -407,13 +409,16 @@ export default { } }, methods: { - isNonNegativeInteger, submit() { this.$refs.form.validate() }, - setQueryParamSafely(name) { + setQueryParamSafely(name, parse_bool = false) { if (this.$route.query[name]) { - this.tableImport[name] = this.$route.query[name] + var value = this.$route.query[name] + if (parse_bool) { + value = this.$route.query[name] === 'true' + } + this.tableImport[name] = value } }, importCsv() { @@ -485,7 +490,7 @@ export default { this.columns = Object.entries(columns) .map(([name, analyse]) => { return { - name: name, + name: name.trim(), type: analyse.type, null_allowed: analyse.null_allowed, primary_key: false, @@ -507,7 +512,7 @@ export default { filename, line_termination: line_termination === '\\n' ? '\n' : JSON.stringify(line_termination).replaceAll('"', ''), separator: this.tableImport.separator, - skip_lines: this.tableImport.skip_lines, + header: this.tableImport.header, quote: this.tableImport.quote, }) this.loading = false diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json index cf2d07b8a8..46ab9b93a4 100644 --- a/dbrepo-ui/locales/en-US.json +++ b/dbrepo-ui/locales/en-US.json @@ -366,8 +366,8 @@ } }, "skip": { - "label": "Skip Rows", - "hint": "Optional. Number of rows to skip, e.g. when the first one contains header and no data" + "label": "Column Headers", + "hint": "Required. First line contains only data" }, "storage": { "text": "Dataset from Storage Service" @@ -1076,6 +1076,7 @@ }, "axios": { "connection": "Failed to contact backend", + "malformed": "Malformed request", "timeout": "Connection timed out" }, "concept": { diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue index e9173726e9..1be05e4bf1 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue @@ -344,8 +344,8 @@ export default { }, download () { this.downloadLoading = true + const tableService = useTableService() if (!this.version) { - const tableService = useTableService() tableService.exportData(this.$route.params.database_id, this.$route.params.table_id) .then((data) => { this.downloadLoading = false @@ -359,18 +359,15 @@ export default { .catch(({code}) => { this.downloadLoading = false const toast = useToastInstance() - if (typeof code !== 'string') { - return - } toast.error(this.$t(code)) }) .finally(() => { this.downloadLoading = false }) } else { - const tableService = useTableService() tableService.exportData(this.$route.params.database_id, this.$route.params.table_id, this.versionISO) .then((data) => { + this.downloadLoading = false const url = URL.createObjectURL(data) const link = document.createElement('a') link.href = url @@ -378,8 +375,10 @@ export default { document.body.appendChild(link) link.click() }) - .catch(() => { + .catch(({code}) => { this.downloadLoading = false + const toast = useToastInstance() + toast.error(this.$t(code)) }) .finally(() => { this.downloadLoading = false @@ -420,9 +419,6 @@ export default { console.debug('date columns are', this.dateColumns) } catch ({code}) { const toast = useToastInstance() - if (typeof code !== 'string') { - return - } toast.error(this.$t(code)) } this.loading = false @@ -439,8 +435,10 @@ export default { this.total = count this.loadingCount = false }) - .catch((error) => { + .catch(({code}) => { this.loadingCount = false + const toast = useToastInstance() + toast.error(this.$t(code)) }) }, loadData({ page, itemsPerPage, sortBy }) { @@ -470,9 +468,6 @@ export default { this.error = true this.loadingData = false const toast = useToastInstance() - if (typeof code !== 'string' || typeof message !== 'string') { - return - } toast.error(this.$t(code) + ": " + message) }) }, diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue index c54314abcb..d77ea94134 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue @@ -234,7 +234,6 @@ export default { rules: { required: value => !!value || 'validation.required' }, - dateFormats: [], tables: [], tableCreate: { name: null, @@ -246,7 +245,7 @@ export default { quote: '"', separator: ',', line_termination: null, - skip_lines: 1 + header: true }, loading: false, url: null, @@ -303,29 +302,11 @@ export default { return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.button.contrast : runtimeConfig.public.variant.button.normal } }, - mounted() { - this.loadDateFormats() - }, methods: { notEmpty, submit() { this.$refs.form.validate() }, - async loadDateFormats() { - this.loading = true - const databaseService = useDatabaseService() - databaseService.findOne(this.$route.params.database_id) - .then((database) => { - this.dateFormats = database.container.image.date_formats - this.loading = false - }) - .catch(() => { - this.loading = false - }) - .finally(() => { - this.loading = false - }) - }, createEmptyTableAndImport({success, columns, constraints}) { if (!success) { return @@ -356,13 +337,13 @@ export default { this.loading = false }) }, - onAnalyse({columns, filename, line_termination, separator, skip_lines, quote, null_element, true_element, false_element}) { + onAnalyse({columns, filename, line_termination, separator, header, quote}) { console.debug('analysed', columns) this.tableCreate.columns = columns this.tableImport.location = filename this.tableImport.line_termination = line_termination this.tableImport.separator = separator - this.tableImport.skip_lines = skip_lines + this.tableImport.header = header this.tableImport.quote = quote if (filename) { this.step = 4 diff --git a/dbrepo-ui/utils/index.ts b/dbrepo-ui/utils/index.ts index 995c03a827..95380474e1 100644 --- a/dbrepo-ui/utils/index.ts +++ b/dbrepo-ui/utils/index.ts @@ -1056,6 +1056,14 @@ export function axiosErrorToApiError(error: AxiosError): ApiErrorDto { message: error.message } return errorObj + } else if (error.code === 'ERR_BAD_REQUEST') { + /* timeout */ + const errorObj: ApiErrorDto = { + status: error.code, + code: 'error.axios.malformed', + message: error.message + } + return errorObj } if (error.response?.data) { const errorObj: ApiErrorDto = (error.response?.data as ApiErrorDto) diff --git a/docker-compose.yml b/docker-compose.yml index e8cec6aa89..fd5cc58613 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -194,8 +194,10 @@ services: JWT_PUBKEY: "${JWT_PUBKEY:-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB}" S3_ACCESS_KEY_ID: "${S3_ACCESS_KEY_ID:-seaweedfsadmin}" S3_BUCKET: "${S3_BUCKET:-dbrepo}" - S3_ENDPOINT: "${S3_ENDPOINT:-http://storage-service:9000}" + S3_ENDPOINT: "${S3_ENDPOINT:-storage-service:9000}" + S3_PROTO: "${S3_PROTO:-http}" S3_SECRET_ACCESS_KEY: "${S3_SECRET_ACCESS_KEY:-seaweedfsadmin}" + METADATA_SERVICE_ENDPOINT: ${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080} SYSTEM_USERNAME: "${SYSTEM_USERNAME:-admin}" SYSTEM_PASSWORD: "${SYSTEM_PASSWORD:-admin}" volumes: @@ -290,32 +292,6 @@ services: timeout: 5s retries: 12 - dbrepo-data-db-sidecar: - restart: "no" - container_name: dbrepo-data-db-sidecar - hostname: data-db-sidecar - image: dbrepo-data-db-sidecar:latest - build: - context: ./dbrepo-data-db/sidecar - network: host - ports: - - "3305:8080" - environment: - S3_ACCESS_KEY_ID: "${S3_ACCESS_KEY_ID:-seaweedfsadmin}" - S3_BUCKET: "${S3_BUCKET:-dbrepo}" - S3_ENDPOINT: "${S3_ENDPOINT:-http://storage-service:9000}" - S3_FILE_PATH: "${S3_FILE_PATH:-/tmp}" - S3_SECRET_ACCESS_KEY: "${S3_SECRET_ACCESS_KEY:-seaweedfsadmin}" - volumes: - - "${SHARED_FILESYSTEM:-/tmp}:/tmp" - healthcheck: - test: curl -sSL localhost:8080/health | grep 'UP' || exit 1 - interval: 10s - timeout: 5s - retries: 12 - logging: - driver: json-file - dbrepo-ui: restart: "no" container_name: dbrepo-ui @@ -551,6 +527,7 @@ services: BROKER_USERNAME: "${SYSTEM_USERNAME:-admin}" BROKER_VIRTUALHOST: "${BROKER_VIRTUALHOST:-dbrepo}" CONNECTION_TIMEOUT: ${CONNECTION_TIMEOUT:-60000} + COMPUTE_SERVICE_ENDPOINT: "${COMPUTE_SERVICE_ENDPOINT:-local[2]}" EXCHANGE_NAME: "${EXCHANGE_NAME:-dbrepo}" METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}" GRANT_DEFAULT_READ: "${GRANT_DEFAULT_READ:-SELECT}" @@ -568,6 +545,7 @@ services: S3_FILE_PATH: "${S3_FILE_PATH:-/tmp}" S3_IMPORT_BUCKET: "${S3_IMPORT_BUCKET:-dbrepo-upload}" S3_SECRET_ACCESS_KEY: "${S3_SECRET_ACCESS_KEY:-seaweedfsadmin}" + SPARK_USER: "${COMPUTE_SERVICE_USERNAME:-spark}" SYSTEM_USERNAME: "${SYSTEM_USERNAME:-admin}" SYSTEM_PASSWORD: "${SYSTEM_PASSWORD:-admin}" healthcheck: diff --git a/helm/dbrepo-mariadb-galera/.gitignore b/helm/dbrepo-mariadb-galera/.gitignore deleted file mode 100644 index 613d851d27..0000000000 --- a/helm/dbrepo-mariadb-galera/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# generated -*.crt -*.key -*.srl -*.csr -build/* \ No newline at end of file diff --git a/helm/dbrepo-mariadb-galera/.helmignore b/helm/dbrepo-mariadb-galera/.helmignore deleted file mode 100644 index b9029e8dea..0000000000 --- a/helm/dbrepo-mariadb-galera/.helmignore +++ /dev/null @@ -1,30 +0,0 @@ -# Dev -values.dev.yaml -Chart.tpl.yaml -hack/ -# MacOS -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Generated -build/ -artifacthub-repo.yml -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ -# Make -Makefile diff --git a/helm/dbrepo-mariadb-galera/Chart.lock b/helm/dbrepo-mariadb-galera/Chart.lock deleted file mode 100644 index fb510b79ee..0000000000 --- a/helm/dbrepo-mariadb-galera/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: mariadb-galera - repository: https://charts.bitnami.com/bitnami - version: 10.1.3 -digest: sha256:ec9ea7a577993779d520b0c93990fb04847f96e41f2bd503141ba66338340985 -generated: "2024-09-14T01:42:48.297778184+04:00" diff --git a/helm/dbrepo-mariadb-galera/Chart.yaml b/helm/dbrepo-mariadb-galera/Chart.yaml deleted file mode 100644 index 4be4337885..0000000000 --- a/helm/dbrepo-mariadb-galera/Chart.yaml +++ /dev/null @@ -1,23 +0,0 @@ -annotations: - licenses: Apache-2.0 -apiVersion: v2 -name: dbrepo-mariadb-galera -description: Helm Chart for installing DBRepo Data Database -sources: - - https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services -type: application -version: "1.4.6" -appVersion: "1.4.6" -keywords: - - dbrepo -maintainers: - - name: Martin Weise - email: martin.weise@tuwien.ac.at -home: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/ -icon: https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/dbrepo-ui/public/favicon.png -dependencies: - - name: mariadb-galera - alias: database - version: 10.1.3 # app version: 11.1.3 - repository: https://charts.bitnami.com/bitnami - condition: database.enabled \ No newline at end of file diff --git a/helm/dbrepo-mariadb-galera/README.md b/helm/dbrepo-mariadb-galera/README.md deleted file mode 100644 index c5aa55100a..0000000000 --- a/helm/dbrepo-mariadb-galera/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# DBRepo MariaDB Helm chart - -tbd - -## Parameters - diff --git a/helm/dbrepo-mariadb-galera/charts/mariadb-galera-10.1.3.tgz b/helm/dbrepo-mariadb-galera/charts/mariadb-galera-10.1.3.tgz deleted file mode 100644 index c906aaf7634b20f0eaf9358b435b01086bdc4f55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48716 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 O|3@u)S;|ny!T<noB{bsz diff --git a/helm/dbrepo-mariadb-galera/templates/_compatibility.tpl b/helm/dbrepo-mariadb-galera/templates/_compatibility.tpl deleted file mode 100644 index 6fc2aa8fa4..0000000000 --- a/helm/dbrepo-mariadb-galera/templates/_compatibility.tpl +++ /dev/null @@ -1,42 +0,0 @@ -{{/* -Copyright Broadcom, Inc. All Rights Reserved. -SPDX-License-Identifier: APACHE-2.0 -*/}} - -{{/* vim: set filetype=mustache: */}} - -{{/* -Return true if the detected platform is Openshift -Usage: -{{- include "common.compatibility.isOpenshift" . -}} -*/}} -{{- define "common.compatibility.isOpenshift" -}} -{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}} -{{- true -}} -{{- end -}} -{{- end -}} - -{{/* -Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC -Usage: -{{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) -}} -*/}} -{{- define "common.compatibility.renderSecurityContext" -}} -{{- $adaptedContext := .secContext -}} - -{{- if (((.context.Values.global).compatibility).openshift) -}} - {{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "common.compatibility.isOpenshift" .context)) -}} - {{/* Remove incompatible user/group values that do not work in Openshift out of the box */}} - {{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}} - {{- if not .secContext.seLinuxOptions -}} - {{/* If it is an empty object, we remove it from the resulting context because it causes validation issues */}} - {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{/* Remove fields that are disregarded when running the container in privileged mode */}} -{{- if $adaptedContext.privileged -}} - {{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}} -{{- end -}} -{{- omit $adaptedContext "enabled" | toYaml -}} -{{- end -}} \ No newline at end of file diff --git a/helm/dbrepo-mariadb-galera/templates/_helpers.tpl b/helm/dbrepo-mariadb-galera/templates/_helpers.tpl deleted file mode 100644 index b17e44d2df..0000000000 --- a/helm/dbrepo-mariadb-galera/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "kubernetes.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "kubernetes.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "kubernetes.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "kubernetes.labels" -}} -helm.sh/chart: {{ include "kubernetes.chart" . }} -{{ include "kubernetes.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "kubernetes.selectorLabels" -}} -app.kubernetes.io/name: {{ include "kubernetes.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "kubernetes.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "kubernetes.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/helm/dbrepo-mariadb-galera/templates/_names.tpl b/helm/dbrepo-mariadb-galera/templates/_names.tpl deleted file mode 100644 index cea9dae390..0000000000 --- a/helm/dbrepo-mariadb-galera/templates/_names.tpl +++ /dev/null @@ -1,6 +0,0 @@ -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts. -*/}} -{{- define "common.names.namespace" -}} -{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} \ No newline at end of file diff --git a/helm/dbrepo-mariadb-galera/templates/configmap.yaml b/helm/dbrepo-mariadb-galera/templates/configmap.yaml deleted file mode 100644 index 066a0d1afb..0000000000 --- a/helm/dbrepo-mariadb-galera/templates/configmap.yaml +++ /dev/null @@ -1,580 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: database-setup - namespace: {{ .Values.namespace }} -data: - {{- with .Values.database.extraInitDbScripts }} - {{ toYaml . | nindent 2 }} - {{- end }} - 02-setup-data.sql: | - BEGIN; - INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, sidecar_host, sidecar_port, privileged_username, privileged_password) - VALUES ('MariaDB 11.1.3', 'mariadb_11_1_3', 1, 'data-db', 3306, 'data-db', 8080, 'root', 'dbrepo'); - COMMIT; - 01-setup-schema.sql: | - BEGIN; - - CREATE TABLE IF NOT EXISTS `mdb_users` - ( - id character varying(36) NOT NULL, - username character varying(255) NOT NULL, - firstname character varying(255), - lastname character varying(255), - email character varying(255) NOT NULL, - orcid character varying(255), - affiliation character varying(255), - mariadb_password character varying(255) NOT NULL, - theme character varying(255) NOT NULL default ('light'), - language character varying(3) NOT NULL default ('en'), - PRIMARY KEY (id), - UNIQUE (username), - UNIQUE (email) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_images` - ( - id bigint NOT NULL AUTO_INCREMENT, - registry character varying(255) NOT NULL DEFAULT 'docker.io', - name character varying(255) NOT NULL, - version character varying(255) NOT NULL, - default_port integer NOT NULL, - dialect character varying(255) NOT NULL, - driver_class character varying(255) NOT NULL, - jdbc_method character varying(255) NOT NULL, - is_default BOOLEAN NOT NULL DEFAULT FALSE, - created timestamp NOT NULL DEFAULT NOW(), - last_modified timestamp, - PRIMARY KEY (id), - UNIQUE (name, version), - UNIQUE (is_default) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_images_date` - ( - id bigint NOT NULL AUTO_INCREMENT, - iid bigint NOT NULL, - database_format character varying(255) NOT NULL, - unix_format character varying(255) NOT NULL, - example character varying(255) NOT NULL, - has_time boolean NOT NULL, - created_at timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id), - FOREIGN KEY (iid) REFERENCES mdb_images (id), - UNIQUE (database_format, unix_format, example) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_containers` - ( - id bigint NOT NULL AUTO_INCREMENT, - internal_name character varying(255) NOT NULL, - name character varying(255) NOT NULL, - host character varying(255) NOT NULL, - port integer NOT NULL default 3306, - ui_host character varying(255) NOT NULL default host, - ui_port integer NOT NULL default port, - ui_additional_flags text, - sidecar_host character varying(255), - sidecar_port integer, - image_id bigint NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - last_modified timestamp, - privileged_username character varying(255) NOT NULL, - privileged_password character varying(255) NOT NULL, - quota integer NOT NULL DEFAULT 50, - PRIMARY KEY (id), - FOREIGN KEY (image_id) REFERENCES mdb_images (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_data` - ( - ID bigint NOT NULL AUTO_INCREMENT, - PROVENANCE text, - FileEncoding text, - FileType character varying(100), - Version text, - Seperator text, - PRIMARY KEY (ID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_licenses` - ( - identifier character varying(255) NOT NULL, - uri text NOT NULL, - description text NOT NULL, - PRIMARY KEY (identifier), - UNIQUE (uri(200)) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_databases` - ( - id bigint NOT NULL AUTO_INCREMENT, - cid bigint NOT NULL, - name character varying(255) NOT NULL, - internal_name character varying(255) NOT NULL, - exchange_name character varying(255) NOT NULL, - description text, - engine character varying(20), - is_public boolean NOT NULL DEFAULT TRUE, - image longblob, - created_by character varying(36), - owned_by character varying(36), - contact_person character varying(36), - created timestamp NOT NULL DEFAULT NOW(), - last_modified timestamp, - PRIMARY KEY (id), - FOREIGN KEY (cid) REFERENCES mdb_containers (id) /* currently we only support one-to-one */, - FOREIGN KEY (created_by) REFERENCES mdb_users (id), - FOREIGN KEY (owned_by) REFERENCES mdb_users (id), - FOREIGN KEY (contact_person) REFERENCES mdb_users (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_databases_subjects` - ( - dbid BIGINT NOT NULL, - subjects character varying(255) NOT NULL, - PRIMARY KEY (dbid, subjects) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_tables` - ( - ID bigint NOT NULL AUTO_INCREMENT, - tDBID bigint NOT NULL, - tName VARCHAR(64) NOT NULL, - internal_name VARCHAR(64) NOT NULL, - queue_name VARCHAR(255) NOT NULL, - routing_key VARCHAR(255), - tDescription VARCHAR(2048), - num_rows BIGINT, - data_length BIGINT, - max_data_length BIGINT, - avg_row_length BIGINT, - `separator` CHAR(1), - quote CHAR(1), - element_null VARCHAR(50), - skip_lines BIGINT, - element_true VARCHAR(50), - element_false VARCHAR(50), - Version TEXT, - created timestamp NOT NULL DEFAULT NOW(), - versioned boolean not null default true, - created_by character varying(36) NOT NULL, - owned_by character varying(36) NOT NULL, - last_modified timestamp, - PRIMARY KEY (ID), - UNIQUE (tDBID, internal_name), - FOREIGN KEY (tDBID) REFERENCES mdb_databases (id), - FOREIGN KEY (created_by) REFERENCES mdb_users (id), - FOREIGN KEY (owned_by) REFERENCES mdb_users (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns` - ( - ID BIGINT NOT NULL AUTO_INCREMENT, - tID BIGINT NOT NULL, - dfID BIGINT, - cName VARCHAR(64), - internal_name VARCHAR(64) NOT NULL, - Datatype ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), - length BIGINT NULL, - ordinal_position INTEGER NOT NULL, - index_length BIGINT NULL, - description VARCHAR(2048), - size BIGINT, - d BIGINT, - auto_generated BOOLEAN DEFAULT false, - is_null_allowed BOOLEAN NOT NULL DEFAULT true, - val_min NUMERIC NULL, - val_max NUMERIC NULL, - mean NUMERIC NULL, - median NUMERIC NULL, - std_dev Numeric NULL, - created timestamp NOT NULL DEFAULT NOW(), - last_modified timestamp, - FOREIGN KEY (tID) REFERENCES mdb_tables (ID) ON DELETE CASCADE, - PRIMARY KEY (ID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_enums` - ( - id bigint NOT NULL AUTO_INCREMENT, - column_id bigint NOT NULL, - value CHARACTER VARYING(255) NOT NULL, - FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE, - PRIMARY KEY (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_sets` - ( - id bigint NOT NULL AUTO_INCREMENT, - column_id bigint NOT NULL, - value CHARACTER VARYING(255) NOT NULL, - FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE, - PRIMARY KEY (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_nom` - ( - tID bigint, - cID bigint, - maxlength INTEGER, - last_modified timestamp, - created timestamp NOT NULL DEFAULT NOW(), - FOREIGN KEY (tID, cID) REFERENCES mdb_columns (tID, ID), - PRIMARY KEY (tID, cID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_cat` - ( - tID bigint, - cID bigint, - num_cat INTEGER, - -- cat_array TEXT[], - last_modified timestamp, - created timestamp NOT NULL DEFAULT NOW(), - FOREIGN KEY (tID, cID) REFERENCES mdb_columns (tID, ID), - PRIMARY KEY (tID, cID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_constraints_foreign_key` - ( - fkid BIGINT NOT NULL AUTO_INCREMENT, - tid BIGINT NOT NULL, - rtid BIGINT NOT NULL, - name VARCHAR(255) NOT NULL, - on_update VARCHAR(50) NULL, - on_delete VARCHAR(50) NULL, - position INT NULL, - PRIMARY KEY (fkid), - FOREIGN KEY (tid) REFERENCES mdb_tables (id) ON DELETE CASCADE, - FOREIGN KEY (rtid) REFERENCES mdb_tables (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_constraints_primary_key` - ( - pkid BIGINT NOT NULL AUTO_INCREMENT, - tID BIGINT NOT NULL, - cid BIGINT NOT NULL, - PRIMARY KEY (pkid), - FOREIGN KEY (tID) REFERENCES mdb_tables (id) ON DELETE CASCADE, - FOREIGN KEY (cid) REFERENCES mdb_columns (id) ON DELETE CASCADE - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_constraints_foreign_key_reference` - ( - id BIGINT NOT NULL AUTO_INCREMENT, - fkid BIGINT NOT NULL, - cid BIGINT NOT NULL, - rcid BIGINT NOT NULL, - PRIMARY KEY (id), - UNIQUE (fkid, cid, rcid), - FOREIGN KEY (fkid) REFERENCES mdb_constraints_foreign_key (fkid) ON UPDATE CASCADE, - FOREIGN KEY (cid) REFERENCES mdb_columns (id), - FOREIGN KEY (rcid) REFERENCES mdb_columns (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_constraints_unique` - ( - uid BIGINT NOT NULL AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - tid BIGINT NOT NULL, - position INT NULL, - PRIMARY KEY (uid), - FOREIGN KEY (tid) REFERENCES mdb_tables (id) ON DELETE CASCADE - ); - - CREATE TABLE IF NOT EXISTS `mdb_constraints_unique_columns` - ( - id BIGINT NOT NULL AUTO_INCREMENT, - uid BIGINT NOT NULL, - cid BIGINT NOT NULL, - PRIMARY KEY (id), - FOREIGN KEY (uid) REFERENCES mdb_constraints_unique (uid), - FOREIGN KEY (cid) REFERENCES mdb_columns (id) ON DELETE CASCADE - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_constraints_checks` - ( - id BIGINT NOT NULL AUTO_INCREMENT, - tid BIGINT NOT NULL, - checks VARCHAR(255) NOT NULL, - PRIMARY KEY (id), - FOREIGN KEY (tid) REFERENCES mdb_tables (id) ON DELETE CASCADE - ) WITH SYSTEM VERSIONING; - - - CREATE TABLE IF NOT EXISTS `mdb_concepts` - ( - id bigint NOT NULL AUTO_INCREMENT, - uri text not null, - name VARCHAR(255) null, - description TEXT null, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id), - UNIQUE (uri(200)) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_units` - ( - id bigint NOT NULL AUTO_INCREMENT, - uri text not null, - name VARCHAR(255) null, - description TEXT null, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id), - UNIQUE (uri(200)) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_concepts` - ( - id bigint NOT NULL, - cID bigint NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id, cid), - FOREIGN KEY (cID) REFERENCES mdb_columns (ID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_columns_units` - ( - id bigint NOT NULL, - cID bigint NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (id, cID), - FOREIGN KEY (cID) REFERENCES mdb_columns (ID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_view` - ( - id bigint NOT NULL AUTO_INCREMENT, - vdbid bigint NOT NULL, - vName VARCHAR(64) NOT NULL, - internal_name VARCHAR(64) NOT NULL, - Query TEXT NOT NULL, - query_hash VARCHAR(255) NOT NULL, - Public BOOLEAN NOT NULL, - InitialView BOOLEAN NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - last_modified timestamp, - created_by character varying(36) NOT NULL, - PRIMARY KEY (id), - FOREIGN KEY (vdbid) REFERENCES mdb_databases (id), - FOREIGN KEY (created_by) REFERENCES mdb_users (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_banner_messages` - ( - id bigint NOT NULL AUTO_INCREMENT, - type ENUM ('ERROR', 'WARNING', 'INFO') NOT NULL default 'INFO', - message TEXT NOT NULL, - link TEXT NULL, - link_text VARCHAR(255) NULL, - display_start timestamp NULL, - display_end timestamp NULL, - PRIMARY KEY (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_ontologies` - ( - id bigint NOT NULL AUTO_INCREMENT, - prefix VARCHAR(8) NOT NULL, - uri TEXT NOT NULL, - uri_pattern TEXT, - sparql_endpoint TEXT NULL, - rdf_path TEXT NULL, - last_modified timestamp, - created timestamp NOT NULL DEFAULT NOW(), - UNIQUE (prefix), - UNIQUE (uri(200)), - PRIMARY KEY (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_view_columns` - ( - id BIGINT NOT NULL AUTO_INCREMENT, - view_id BIGINT NOT NULL, - dfID BIGINT, - name VARCHAR(64), - internal_name VARCHAR(64) NOT NULL, - column_type ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), - ordinal_position INTEGER NOT NULL, - size BIGINT, - d BIGINT, - auto_generated BOOLEAN DEFAULT false, - is_null_allowed BOOLEAN NOT NULL DEFAULT true, - PRIMARY KEY (id), - FOREIGN KEY (view_id) REFERENCES mdb_view (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifiers` - ( - id BIGINT NOT NULL AUTO_INCREMENT, - dbid BIGINT NOT NULL, - qid BIGINT, - vid BIGINT, - tid BIGINT, - publisher VARCHAR(255) NOT NULL, - language VARCHAR(2), - publication_year INTEGER NOT NULL, - publication_month INTEGER, - publication_day INTEGER, - identifier_type ENUM ('DATABASE', 'SUBSET', 'VIEW', 'TABLE') NOT NULL, - status ENUM ('DRAFT', 'PUBLISHED') NOT NULL DEFAULT ('PUBLISHED'), - query TEXT, - query_normalized TEXT, - query_hash VARCHAR(255), - execution TIMESTAMP, - result_hash VARCHAR(255), - result_number BIGINT, - doi VARCHAR(255), - created TIMESTAMP NOT NULL DEFAULT NOW(), - created_by VARCHAR(36) NOT NULL, - last_modified TIMESTAMP, - PRIMARY KEY (id), /* must be a single id from persistent identifier concept */ - FOREIGN KEY (dbid) REFERENCES mdb_databases (id), - FOREIGN KEY (created_by) REFERENCES mdb_users (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifier_licenses` - ( - pid bigint NOT NULL, - license_id VARCHAR(255) NOT NULL, - PRIMARY KEY (pid, license_id), - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id), - FOREIGN KEY (license_id) REFERENCES mdb_licenses (identifier) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifier_titles` - ( - id bigint NOT NULL AUTO_INCREMENT, - pid bigint NOT NULL, - title text NOT NULL, - title_type ENUM ('ALTERNATIVE_TITLE', 'SUBTITLE', 'TRANSLATED_TITLE', 'OTHER'), - language VARCHAR(2), - PRIMARY KEY (id), - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifier_funders` - ( - id bigint NOT NULL AUTO_INCREMENT, - pid bigint NOT NULL, - funder_name VARCHAR(255) NOT NULL, - funder_identifier TEXT, - funder_identifier_type ENUM ('CROSSREF_FUNDER_ID', 'GRID', 'ISNI', 'ROR', 'OTHER'), - scheme_uri text, - award_number VARCHAR(255), - award_title text, - language VARCHAR(255), - PRIMARY KEY (id), - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifier_descriptions` - ( - id bigint NOT NULL AUTO_INCREMENT, - pid bigint NOT NULL, - description text NOT NULL, - description_type ENUM ('ABSTRACT', 'METHODS', 'SERIES_INFORMATION', 'TABLE_OF_CONTENTS', 'TECHNICAL_INFO', 'OTHER'), - language VARCHAR(2), - PRIMARY KEY (id), - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_related_identifiers` - ( - id bigint NOT NULL AUTO_INCREMENT, - pid bigint NOT NULL, - value varchar(255) NOT NULL, - type varchar(255) NOT NULL, - relation varchar(255) NOT NULL, - PRIMARY KEY (id), /* must be a single id from persistent identifier concept */ - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id), - UNIQUE (pid, value) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_identifier_creators` - ( - id bigint NOT NULL AUTO_INCREMENT, - pid bigint NOT NULL, - given_names text, - family_name text, - creator_name VARCHAR(255) NOT NULL, - name_type ENUM ('PERSONAL', 'ORGANIZATIONAL') default 'PERSONAL', - name_identifier text, - name_identifier_scheme ENUM ('ROR', 'GRID', 'ISNI', 'ORCID'), - name_identifier_scheme_uri text, - affiliation VARCHAR(255), - affiliation_identifier text, - affiliation_identifier_scheme ENUM ('ROR', 'GRID', 'ISNI'), - affiliation_identifier_scheme_uri text, - PRIMARY KEY (id), - FOREIGN KEY (pid) REFERENCES mdb_identifiers (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_update` - ( - uUserID character varying(255) NOT NULL, - uDBID bigint NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (uUserID, uDBID), - FOREIGN KEY (uDBID) REFERENCES mdb_databases (id) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_access` - ( - aUserID character varying(255) NOT NULL, - aDBID bigint REFERENCES mdb_databases (id), - attime TIMESTAMP, - download BOOLEAN, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (aUserID, aDBID) - ) WITH SYSTEM VERSIONING; - - CREATE TABLE IF NOT EXISTS `mdb_have_access` - ( - user_id character varying(36) NOT NULL, - database_id bigint REFERENCES mdb_databases (id), - access_type ENUM ('READ', 'WRITE_OWN', 'WRITE_ALL') NOT NULL, - created timestamp NOT NULL DEFAULT NOW(), - PRIMARY KEY (user_id, database_id), - FOREIGN KEY (user_id) REFERENCES mdb_users (id) - ) WITH SYSTEM VERSIONING; - - COMMIT; - BEGIN; - - INSERT INTO `mdb_licenses` (identifier, uri, description) - VALUES ('CC0-1.0', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', - 'CC0 waives copyright interest in a work you''ve created and dedicates it to the world-wide public domain. Use CC0 to opt out of copyright entirely and ensure your work has the widest reach.'), - ('CC-BY-4.0', 'https://creativecommons.org/licenses/by/4.0/legalcode', - 'The Creative Commons Attribution license allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited.'); - - INSERT INTO `mdb_images` (name, registry, version, default_port, dialect, driver_class, jdbc_method) - VALUES ('mariadb', 'docker.io', '11.1.3', 3306, 'org.hibernate.dialect.MariaDBDialect', 'org.mariadb.jdbc.Driver', - 'mariadb'); - - INSERT INTO `mdb_images_date` (iid, database_format, unix_format, example, has_time) - VALUES (1, '%Y-%c-%d %H:%i:%S.%f', 'yyyy-MM-dd HH:mm:ss.SSSSSS', '2022-01-30 13:44:25.499', true), - (1, '%Y-%c-%d %H:%i:%S', 'yyyy-MM-dd HH:mm:ss', '2022-01-30 13:44:25', true), - (1, '%Y-%c-%d', 'yyyy-MM-dd', '2022-01-30', false), - (1, '%H:%i:%S', 'HH:mm:ss', '13:44:25', true), - (1, '%d.%c.%Y', 'dd.MM.yyyy', '30.01.2022', false); - - INSERT INTO `mdb_ontologies` (prefix, uri, uri_pattern, sparql_endpoint, rdf_path) - VALUES ('om', 'http://www.ontology-of-units-of-measure.org/resource/om-2/', - 'http://www.ontology-of-units-of-measure.org/resource/om-2/.*', null, 'rdf/om-2.0.rdf'), - ('wd', 'http://www.wikidata.org/', 'http://www.wikidata.org/entity/.*', 'https://query.wikidata.org/sparql', - null), - ('mo', 'http://purl.org/ontology/mo/', 'http://purl.org/ontology/mo/.*', null, null), - ('dc', 'http://purl.org/dc/elements/1.1/', null, null, null), - ('xsd', 'http://www.w3.org/2001/XMLSchema#', null, null, null), - ('tl', 'http://purl.org/NET/c4dm/timeline.owl#', null, null, null), - ('foaf', 'http://xmlns.com/foaf/0.1/', null, null, null), - ('schema', 'http://schema.org/', null, null, null), - ('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', null, null, null), - ('rdfs', 'http://www.w3.org/2000/01/rdf-schema#', null, null, null), - ('owl', 'http://www.w3.org/2002/07/owl#', null, null, null), - ('prov', 'http://www.w3.org/ns/prov#', null, null, null), - ('db', 'http://dbpedia.org', 'http://dbpedia.org/ontology/.*', 'http://dbpedia.org/sparql', null); - COMMIT; - diff --git a/helm/dbrepo-mariadb-galera/templates/secret.yaml b/helm/dbrepo-mariadb-galera/templates/secret.yaml deleted file mode 100644 index fc5a2a7c5d..0000000000 --- a/helm/dbrepo-mariadb-galera/templates/secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: sidecar-secret - namespace: {{ .Values.namespace }} -stringData: - S3_ACCESS_KEY_ID: "{{ .Values.s3.auth.adminAccessKeyId }}" - S3_SECRET_ACCESS_KEY: "{{ .Values.s3.auth.adminSecretAccessKey }}" - S3_STORAGE_ENDPOINT: "{{ .Values.s3.endpoint }}" diff --git a/helm/dbrepo-mariadb-galera/values.schema.json b/helm/dbrepo-mariadb-galera/values.schema.json deleted file mode 100644 index 336e7dc1e5..0000000000 --- a/helm/dbrepo-mariadb-galera/values.schema.json +++ /dev/null @@ -1,301 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "database": { - "properties": { - "db": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "enabled": { - "type": "boolean" - }, - "extraInitDbScripts": { - "properties": {}, - "type": "object" - }, - "extraVolumeMounts": { - "items": { - "properties": { - "mountPath": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "extraVolumes": { - "items": { - "properties": { - "emptyDir": { - "properties": {}, - "type": "object" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "fullnameOverride": { - "type": "string" - }, - "galera": { - "properties": { - "mariabackup": { - "properties": { - "password": { - "type": "string" - }, - "user": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "host": { - "type": "string" - }, - "initdbScriptsConfigMap": { - "type": "string" - }, - "jdbcExtraArgs": { - "type": "string" - }, - "metrics": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "persistence": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "replicaCount": { - "type": "integer" - }, - "rootUser": { - "properties": { - "password": { - "type": "string" - }, - "user": { - "type": "string" - } - }, - "type": "object" - }, - "service": { - "properties": { - "extraPorts": { - "items": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "protocol": { - "type": "string" - }, - "targetPort": { - "type": "integer" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "sidecars": { - "items": { - "properties": { - "envFrom": { - "items": { - "properties": { - "secretRef": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "type": "array" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "livenessProbe": { - "properties": { - "exec": { - "properties": { - "command": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - } - }, - "type": "object" - }, - "name": { - "type": "string" - }, - "ports": { - "items": { - "properties": { - "containerPort": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "protocol": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "readinessProbe": { - "properties": { - "exec": { - "properties": { - "command": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - } - }, - "type": "object" - }, - "securityContext": { - "properties": { - "allowPrivilegeEscalation": { - "type": "boolean" - }, - "capabilities": { - "properties": { - "drop": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "runAsGroup": { - "type": "integer" - }, - "runAsNonRoot": { - "type": "boolean" - }, - "runAsUser": { - "type": "integer" - }, - "seccompProfile": { - "properties": { - "type": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "volumeMounts": { - "items": { - "properties": { - "mountPath": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "s3": { - "properties": { - "auth": { - "properties": { - "adminAccessKeyId": { - "type": "string" - }, - "adminSecretAccessKey": { - "type": "string" - } - }, - "type": "object" - }, - "endpoint": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" -} diff --git a/helm/dbrepo-mariadb-galera/values.yaml b/helm/dbrepo-mariadb-galera/values.yaml deleted file mode 100644 index f5026a3b5b..0000000000 --- a/helm/dbrepo-mariadb-galera/values.yaml +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright the DBRepo developers -# SPDX-License-Identifier: APACHE-2.0 - -## @param namespaceOverride The namespace to install the chart - -s3: - endpoint: http://storage-service-s3:8333 - auth: - adminAccessKeyId: seaweedfsadmin - adminSecretAccessKey: seaweedfsadmin - -database: - ## @param database.enabled Enable the Metadata Database. - enabled: true - ## @skip database.fullnameOverride - fullnameOverride: data-db - ## @param database.host The hostname for the microservices. - host: data-db - rootUser: - ## @param database.rootUser.user The root username. - user: root - ## @param database.rootUser.password The root user password. - password: dbrepo - db: - ## @param database.db.name The database name. - name: dbrepo - galera: - mariabackup: - ## @param database.galera.mariabackup.user The database backup username. - user: backup - ## @param database.galera.mariabackup.password The database backup user password - password: backup - ## @param database.jdbcExtraArgs The extra arguments for JDBC connections in the microservices. - jdbcExtraArgs: "" - metrics: - ## @skip database.metrics.enabled The Prometheus settings. - enabled: false - ## @skip database.initdbScriptsConfigMap The initial database scripts. - initdbScriptsConfigMap: database-setup - ## @param database.extraInitDbScripts Additional init.db scripts that are executed on the first start. - extraInitDbScripts: { } - # 03-additional-data.sql: | - # BEGIN; - # INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, sidecar_host, sidecar_port, privileged_username, privileged_password) - # VALUES ('MariaDB Galera TEST', 'mariadb_11_1_3', 1, 'data-db', 3306, 'data-db', 80, 'root', 'dbrepo'); - # COMMIT; - ## @param database.replicaCount The number of cluster nodes, should be uneven i.e. 2n+1 - replicaCount: 3 - persistence: - ## @param database.persistence.enabled Enable persistent storage. - enabled: true - ## @skip database.service - service: - extraPorts: - - name: "sidecar" - port: 8080 - targetPort: 8080 - protocol: TCP - ## @skip database.sidecars - sidecars: - - name: sidecar - image: registry.datalab.tuwien.ac.at/dbrepo/data-db-sidecar:1.4.5 - imagePullPolicy: Always - securityContext: - runAsUser: 1001 - runAsGroup: 0 - runAsNonRoot: true - allowPrivilegeEscalation: false - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - ports: - - name: "sidecar" - containerPort: 8080 - protocol: TCP - envFrom: - - secretRef: - name: data-service-secret - livenessProbe: - exec: - command: - - /bin/bash - - -ec - - "curl -sSL localhost:8080/health | grep 'UP' || exit 1" - initialDelaySeconds: 120 - periodSeconds: 30 - readinessProbe: - exec: - command: - - /bin/bash - - -ec - - "curl -sSL localhost:8080/health | grep 'UP' || exit 1" - initialDelaySeconds: 30 - periodSeconds: 30 - volumeMounts: - - name: s3 - mountPath: /s3 - ## @skip database.extraVolumeMounts - extraVolumeMounts: - - name: s3 - mountPath: /s3 - ## @skip database.extraVolumes - extraVolumes: - - name: s3 - emptyDir: { } diff --git a/helm/dbrepo/Chart.lock b/helm/dbrepo/Chart.lock index 0937dd527a..29ab55f1a1 100644 --- a/helm/dbrepo/Chart.lock +++ b/helm/dbrepo/Chart.lock @@ -5,9 +5,9 @@ dependencies: - name: keycloak repository: https://charts.bitnami.com/bitnami version: 21.6.1 -- name: dbrepo-mariadb-galera - repository: file://../dbrepo-mariadb-galera - version: 1.4.7 +- name: mariadb-galera + repository: https://charts.bitnami.com/bitnami + version: 10.1.3 - name: mariadb-galera repository: https://charts.bitnami.com/bitnami version: 10.1.3 @@ -29,5 +29,5 @@ dependencies: - name: prometheus repository: https://charts.bitnami.com/bitnami version: 1.3.22 -digest: sha256:840d2ea4b1e36fe8fa399fc4170b6274a3de161c13a4a1a3b18ce3107ab71f79 -generated: "2024-10-01T07:48:55.174297756+02:00" +digest: sha256:54cb4dc867a23b7b265fba49608a0aaa8add75ec697c2446fbf013169c4489cd +generated: "2024-11-02T18:34:23.0903882+01:00" diff --git a/helm/dbrepo/Chart.yaml b/helm/dbrepo/Chart.yaml index 9e09e7f8e3..301352c6b2 100644 --- a/helm/dbrepo/Chart.yaml +++ b/helm/dbrepo/Chart.yaml @@ -26,11 +26,11 @@ dependencies: version: 21.6.1 # app version: 24.0.5 repository: https://charts.bitnami.com/bitnami condition: authservice.enabled - - name: dbrepo-mariadb-galera + - name: mariadb-galera alias: datadb - version: 1.4.7 - repository: file://../dbrepo-mariadb-galera - condition: datadb.enabled + version: 10.1.3 # app version: 11.1.3 + repository: https://charts.bitnami.com/bitnami + condition: database.enabled - name: mariadb-galera alias: metadatadb version: 10.1.3 # app version: 11.1.3 diff --git a/helm/dbrepo/charts/dbrepo-mariadb-galera-1.4.6.tgz b/helm/dbrepo/charts/dbrepo-mariadb-galera-1.4.6.tgz deleted file mode 100644 index 4af22ff6e998199f69a8e1ff43fd96c3f55aa8ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57156 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˥FkO3tuH3BYY{|dFX7K%Ac3-Sn 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 bw*KcYe|~WOKR*M*|Nl2W%z4WY!pZ;u!>ayS diff --git a/helm/dbrepo/templates/analyse-secret.yaml b/helm/dbrepo/templates/analyse-secret.yaml index 49aa893829..8baf598c93 100644 --- a/helm/dbrepo/templates/analyse-secret.yaml +++ b/helm/dbrepo/templates/analyse-secret.yaml @@ -6,8 +6,6 @@ metadata: name: analyse-service-secret namespace: {{ include "common.names.namespace" . | quote }} stringData: - ADMIN_USERNAME: "{{ .Values.identityservice.users }}" - ADMIN_PASSWORD: "{{ .Values.identityservice.userPasswords }}" AUTH_SERVICE_ADMIN: "{{ .Values.authservice.auth.adminUser }}" AUTH_SERVICE_ADMIN_PASSWORD: "{{ .Values.authservice.auth.adminPassword }}" AUTH_SERVICE_CLIENT: "{{ .Values.authservice.client.id }}" @@ -20,4 +18,7 @@ stringData: S3_BUCKET: "{{ .Values.storageservice.s3.bucket }}" S3_ENDPOINT: "{{ .Values.analyseservice.s3.endpoint }}" S3_SECRET_ACCESS_KEY: "{{ .Values.storageservice.s3.auth.adminSecretAccessKey }}" + METADATA_SERVICE_ENDPOINT: "{{ .Values.metadataservice.endpoint }}" + SYSTEM_USERNAME: "{{ .Values.identityservice.users }}" + SYSTEM_PASSWORD: "{{ .Values.identityservice.userPasswords }}" {{- end }} diff --git a/helm/dbrepo/templates/data-deployment.yaml b/helm/dbrepo/templates/data-deployment.yaml index fae3250738..3e3c308bf0 100644 --- a/helm/dbrepo/templates/data-deployment.yaml +++ b/helm/dbrepo/templates/data-deployment.yaml @@ -33,7 +33,7 @@ spec: securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.dataservice.containerSecurityContext "context" $) | nindent 12 }} {{- end }} ports: - - containerPort: 80 + - containerPort: 8080 protocol: TCP envFrom: - secretRef: diff --git a/helm/dbrepo/templates/data-secret.yaml b/helm/dbrepo/templates/data-secret.yaml index dd40e3e649..12d2697183 100644 --- a/helm/dbrepo/templates/data-secret.yaml +++ b/helm/dbrepo/templates/data-secret.yaml @@ -24,9 +24,6 @@ stringData: GATEWAY_SERVICE_ENDPOINT: "{{ .Values.gateway }}" GRANT_DEFAULT_READ: "{{ .Values.dataservice.grant.read }}" GRANT_DEFAULT_WRITE: "{{ .Values.dataservice.grant.write }}" - DEFAULT_DATE_FORMAT_ID: "{{ .Values.dataservice.default.date }}" - DEFAULT_TIME_FORMAT_ID: "{{ .Values.dataservice.default.time }}" - DEFAULT_TIMESTAMP_FORMAT_ID: "{{ .Values.dataservice.default.timestamp }}" JWT_PUBKEY: "{{ .Values.authservice.jwt.pubkey }}" LOG_LEVEL: "{{ ternary "trace" "info" .Values.dataservice.image.debug }}" METADATA_SERVICE_ENDPOINT: "{{ .Values.metadataservice.endpoint }}" diff --git a/helm/dbrepo/templates/metadata-configmap.yaml b/helm/dbrepo/templates/metadata-configmap.yaml index 893f255627..bdd2cdbcf8 100644 --- a/helm/dbrepo/templates/metadata-configmap.yaml +++ b/helm/dbrepo/templates/metadata-configmap.yaml @@ -11,8 +11,8 @@ data: {{- end }} 02-setup-data.sql: | BEGIN; - INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, sidecar_host, sidecar_port, privileged_username, privileged_password) - VALUES ('mariadb:11.1.3-debian-11-r6', 'mariadb_11_1_3', 1, 'data-db', 3306, 'data-db', 8080, 'root', 'dbrepo'); + INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, privileged_username, privileged_password) + VALUES ('mariadb:11.1.3-debian-11-r6', 'mariadb_11_1_3', 1, 'data-db', 3306, '{{ .Values.datadb.rootUser.user }}', '{{ .Values.datadb.rootUser.password }}'); COMMIT; 01-setup-schema.sql: | BEGIN; @@ -161,14 +161,13 @@ data: tID BIGINT UNSIGNED NOT NULL, cName VARCHAR(64), internal_name VARCHAR(64) NOT NULL, - Datatype ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), + Datatype ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','SERIAL','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), length BIGINT UNSIGNED NULL, ordinal_position INTEGER NOT NULL, index_length BIGINT UNSIGNED NULL, description VARCHAR(2048), size BIGINT UNSIGNED, d BIGINT UNSIGNED, - auto_generated BOOLEAN DEFAULT false, is_null_allowed BOOLEAN NOT NULL DEFAULT true, val_min NUMERIC NULL, val_max NUMERIC NULL, @@ -225,7 +224,7 @@ data: CREATE TABLE IF NOT EXISTS `mdb_constraints_foreign_key` ( - fkid BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + fkid SERIAL, tid BIGINT UNSIGNED NOT NULL, rtid BIGINT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, @@ -262,7 +261,7 @@ data: CREATE TABLE IF NOT EXISTS `mdb_constraints_unique` ( - uid BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + uid SERIAL, name VARCHAR(255) NOT NULL, tid BIGINT UNSIGNED NOT NULL, position INT NULL, @@ -379,17 +378,16 @@ data: ( id SERIAL, view_id BIGINT UNSIGNED NOT NULL, - dfID BIGINT UNSIGNED, name VARCHAR(64), internal_name VARCHAR(64) NOT NULL, column_type ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), ordinal_position INTEGER NOT NULL, size BIGINT UNSIGNED, d BIGINT UNSIGNED, - auto_generated BOOLEAN DEFAULT false, is_null_allowed BOOLEAN NOT NULL DEFAULT true, PRIMARY KEY (id), - FOREIGN KEY (view_id) REFERENCES mdb_view (id) ON DELETE CASCADE + FOREIGN KEY (view_id) REFERENCES mdb_view (id) ON DELETE CASCADE, + UNIQUE (view_id, internal_name) ) WITH SYSTEM VERSIONING; CREATE TABLE IF NOT EXISTS `mdb_identifiers` @@ -470,10 +468,10 @@ data: CREATE TABLE IF NOT EXISTS `mdb_related_identifiers` ( id SERIAL, - pid BIGINT UNSIGNED NOT NULL, - value varchar(255) NOT NULL, - type varchar(255) NOT NULL, - relation varchar(255) NOT NULL, + pid BIGINT UNSIGNED NOT NULL, + value varchar(255) NOT NULL, + type ENUM ('DOI','URL','URN','ARK','ARXIV','BIBCODE','EAN13','EISSN','HANDLE','IGSN','ISBN','ISTC','LISSN','LSID','PMID','PURL','UPC','W3ID') NOT NULL, + relation ENUM ('IS_CITED_BY','CITES','IS_SUPPLEMENT_TO','IS_SUPPLEMENTED_BY','IS_CONTINUED_BY','CONTINUES','IS_DESCRIBED_BY','DESCRIBES','HAS_METADATA','IS_METADATA_FOR','HAS_VERSION','IS_VERSION_OF','IS_NEW_VERSION_OF','IS_PREVIOUS_VERSION_OF','IS_PART_OF','HAS_PART','IS_PUBLISHED_IN','IS_REFERENCED_BY','REFERENCES','IS_DOCUMENTED_BY','DOCUMENTS','IS_COMPILED_BY','COMPILES','IS_VARIANT_FORM_OF','IS_ORIGINAL_FORM_OF','IS_IDENTICAL_TO','IS_REVIEWED_BY','REVIEWS','IS_DERIVED_FROM','IS_SOURCE_OF','IS_REQUIRED_BY','REQUIRES','IS_OBSOLETED_BY','OBSOLETES') NOT NULL, PRIMARY KEY (id), /* must be a single id from persistent identifier concept */ FOREIGN KEY (pid) REFERENCES mdb_identifiers (id), UNIQUE (pid, value) @@ -543,8 +541,10 @@ data: d_default INT UNSIGNED, d_required BOOLEAN COMMENT 'When setting NULL, the service assumes the data type has no d', d_step INT UNSIGNED, - hint TEXT, + type_hint TEXT, + data_hint TEXT, documentation TEXT NOT NULL, + is_generated BOOLEAN NOT NULL, is_quoted BOOLEAN NOT NULL, is_buildable BOOLEAN NOT NULL, PRIMARY KEY (id), @@ -567,67 +567,74 @@ data: 'mariadb'); INSERT INTO `mdb_image_types` (image_id, display_name, value, size_min, size_max, size_default, size_required, - size_step, d_min, d_max, d_default, d_required, d_step, hint, documentation, is_quoted, - is_buildable) - VALUES (1, 'BIGINT(size)', 'bigint', 0, null, null, false, 1, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/bigint/', false, true), - (1, 'BINARY(size)', 'binary', 0, 255, 255, true, 1, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/binary/', false, true), - (1, 'BIT(size)', 'bit', 0, 64, null, false, 1, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/bit/', false, true), - (1, 'BLOB(size)', 'blob', 0, 65535, null, false, 1, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/blob/', false, false), - (1, 'BOOL', 'bool', null, null, null, null, null, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/bool/', false, true), - (1, 'CHAR(size)', 'char', 0, 255, 255, false, 1, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/char/', false, true), + size_step, d_min, d_max, d_default, d_required, d_step, type_hint, data_hint, + documentation, is_quoted, is_buildable, is_generated) + VALUES (1, 'BIGINT(size)', 'bigint', 0, null, null, false, 1, null, null, null, null, null, null, null, + 'https://mariadb.com/kb/en/bigint/', false, true, false), + (1, 'BINARY(size)', 'binary', 0, 255, 255, true, 1, null, null, null, null, null, 'size in Bytes', null, + 'https://mariadb.com/kb/en/binary/', false, true, false), + (1, 'BIT(size)', 'bit', 0, 64, null, false, 1, null, null, null, null, null, null, null, + 'https://mariadb.com/kb/en/bit/', false, true, false), + (1, 'BLOB(size)', 'blob', 0, 65535, null, false, 1, null, null, null, null, null, 'size in Bytes', null, + 'https://mariadb.com/kb/en/blob/', false, false, false), + (1, 'BOOL', 'bool', null, null, null, null, null, null, null, null, null, null, null, null, + 'https://mariadb.com/kb/en/bool/', false, true, false), + (1, 'CHAR(size)', 'char', 0, 255, 255, false, 1, null, null, null, null, null, null, null, + 'https://mariadb.com/kb/en/char/', false, true, false), (1, 'DATE', 'date', null, null, null, null, null, null, null, null, null, null, - 'min. 1000-01-01, max. 9999-12-31', 'https://mariadb.com/kb/en/date/', true, true), + 'min. 1000-01-01, max. 9999-12-31', 'e.g. YYYY-MM-DD, YY-MM-DD, YYMMDD, YYYY/MM/DD', + 'https://mariadb.com/kb/en/date/', true, true, false), (1, 'DATETIME(fsp)', 'datetime', 0, 6, null, null, 1, null, null, null, null, null, 'fsp=microsecond precision, min. 1000-01-01 00:00:00.0, max. 9999-12-31 23:59:59.9', - 'https://mariadb.com/kb/en/datetime/', true, true), - (1, 'DECIMAL(size, d)', 'decimal', 0, 65, null, false, 1, 0, 38, null, false, null, null, - 'https://mariadb.com/kb/en/decimal/', false, true), - (1, 'DOUBLE(size, d)', 'double', null, null, null, false, null, null, null, null, false, null, null, - 'https://mariadb.com/kb/en/double/', false, true), + 'e.g. YYYY-MM-DD HH:MM:SS, YY-MM-DD HH:MM:SS, YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD, YYMMDD', + 'https://mariadb.com/kb/en/datetime/', true, true, false), + (1, 'DECIMAL(size, d)', 'decimal', 0, 65, null, false, 1, 0, 38, null, false, null, null, null, + 'https://mariadb.com/kb/en/decimal/', false, true, false), + (1, 'DOUBLE(size, d)', 'double', null, null, null, false, null, null, null, null, false, null, null, null, + 'https://mariadb.com/kb/en/double/', false, true, false), (1, 'ENUM(v1,v2,...)', 'enum', null, null, null, null, null, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/enum/', true, true), - (1, 'FLOAT(size)', 'float', null, null, null, false, null, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/float/', false, true), - (1, 'INT(size)', 'int', null, null, null, false, null, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/int/', false, true), - (1, 'LONGBLOB', 'longblob', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', - 'https://mariadb.com/kb/en/longblob/', false, true), - (1, 'LONGTEXT', 'longtext', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', - 'https://mariadb.com/kb/en/longtext/', true, true), + 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/enum/', true, true, false), + (1, 'FLOAT(size)', 'float', null, null, null, false, null, null, null, null, null, null, null, null, + 'https://mariadb.com/kb/en/float/', false, true, false), + (1, 'INT(size)', 'int', null, null, null, false, null, null, null, null, null, null, 'size in Bytes', null, + 'https://mariadb.com/kb/en/int/', false, true, false), + (1, 'LONGBLOB', 'longblob', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', null, + 'https://mariadb.com/kb/en/longblob/', false, true, false), + (1, 'LONGTEXT', 'longtext', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', null, + 'https://mariadb.com/kb/en/longtext/', true, true, false), (1, 'MEDIUMBLOB', 'mediumblob', null, null, null, null, null, null, null, null, null, null, 'max. 15.999 MiB', - 'https://mariadb.com/kb/en/mediumblob/', false, true), - (1, 'MEDIUMINT', 'mediumint', null, null, null, null, null, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/mediumint/', false, true), + null, 'https://mariadb.com/kb/en/mediumblob/', false, true, false), + (1, 'MEDIUMINT', 'mediumint', null, null, null, null, null, null, null, null, null, null, 'size in Bytes', null, + 'https://mariadb.com/kb/en/mediumint/', false, true, false), (1, 'MEDIUMTEXT', 'mediumtext', null, null, null, null, null, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/mediumtext/', true, true), + null, 'https://mariadb.com/kb/en/mediumtext/', true, true, false), + (1, 'SERIAL', 'serial', null, null, null, null, null, null, null, null, null, null, null, + null, 'https://mariadb.com/kb/en/bigint/', true, true, true), (1, 'SET(v1,v2,...)', 'set', null, null, null, null, null, null, null, null, null, null, null, - 'https://mariadb.com/kb/en/set/', true, true), + 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/set/', true, true, false), (1, 'SMALLINT(size)', 'smallint', 0, null, null, false, null, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/smallint/', false, true), - (1, 'TEXT(size)', 'text', 0, null, null, false, null, null, null, null, null, null, 'size in Bytes', - 'https://mariadb.com/kb/en/text/', true, true), + null, 'https://mariadb.com/kb/en/smallint/', false, true, false), + (1, 'TEXT(size)', 'text', 0, null, null, false, null, null, null, null, null, null, 'size in Bytes', null, + 'https://mariadb.com/kb/en/text/', true, true, false), (1, 'TIME(fsp)', 'time', 0, 6, 0, false, null, null, null, null, null, null, - 'fsp=microsecond precision, min. 0, max. 6', 'https://mariadb.com/kb/en/time/', true, true), + 'fsp=microsecond precision, min. 0, max. 6', 'e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S', + 'https://mariadb.com/kb/en/time/', true, true, false), (1, 'TIMESTAMP(fsp)', 'timestamp', 0, 6, 0, false, null, null, null, null, null, null, - 'fsp=microsecond precision, min. 0, max. 6', 'https://mariadb.com/kb/en/timestamp/', true, true), - (1, 'TINYBLOB', 'tinyblob', null, null, null, null, null, null, null, null, null, null, - 'fsp=microsecond precision, min. 0, max. 6', 'https://mariadb.com/kb/en/timestamp/', false, true), - (1, 'TINYINT(size)', 'tinyint', 0, null, null, false, null, null, null, null, null, null, - 'size in Bytes', 'https://mariadb.com/kb/en/tinyint/', false, true), - (1, 'TINYTEXT', 'tinytext', null, null, null, null, null, null, null, null, null, null, - 'max. 255 characters', 'https://mariadb.com/kb/en/tinytext/', true, true), - (1, 'YEAR', 'year', 2, 4, null, false, 2, null, null, null, null, null, 'min. 1901, max. 2155', - 'https://mariadb.com/kb/en/year/', false, true), - (1, 'VARBINARY(size)', 'varbinary', 0, null, null, true, null, null, null, null, null, null, - null, 'https://mariadb.com/kb/en/varbinary/', false, true), - (1, 'VARCHAR(size)', 'varchar', 0, 65532, 255, true, null, null, null, null, null, null, - null, 'https://mariadb.com/kb/en/varchar/', false, true); + 'fsp=microsecond precision, min. 0, max. 6', + 'e.g. YYYY-MM-DD HH:MM:SS, YY-MM-DD HH:MM:SS, YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD, YYMMDD', + 'https://mariadb.com/kb/en/timestamp/', true, true, false), + (1, 'TINYBLOB', 'tinyblob', null, null, null, null, null, null, null, null, null, null, null, + 'fsp=microsecond precision, min. 0, max. 6', 'https://mariadb.com/kb/en/timestamp/', false, true, false), + (1, 'TINYINT(size)', 'tinyint', 0, null, null, false, null, null, null, null, null, null, null, + 'size in Bytes', 'https://mariadb.com/kb/en/tinyint/', false, true, false), + (1, 'TINYTEXT', 'tinytext', null, null, null, null, null, null, null, null, null, null, null, + 'max. 255 characters', 'https://mariadb.com/kb/en/tinytext/', true, true, false), + (1, 'YEAR', 'year', 2, 4, null, false, 2, null, null, null, null, null, 'min. 1901, max. 2155', 'e.g. YYYY, YY', + 'https://mariadb.com/kb/en/year/', false, true, false), + (1, 'VARBINARY(size)', 'varbinary', 0, null, null, true, null, null, null, null, null, null, null, + null, 'https://mariadb.com/kb/en/varbinary/', false, true, false), + (1, 'VARCHAR(size)', 'varchar', 0, 65532, 255, true, null, null, null, null, null, null, null, + null, 'https://mariadb.com/kb/en/varchar/', false, true, false); INSERT INTO `mdb_ontologies` (prefix, uri, uri_pattern, sparql_endpoint, rdf_path) diff --git a/helm/dbrepo/templates/metadata-deployment.yaml b/helm/dbrepo/templates/metadata-deployment.yaml index 46c96a331d..9919e301dc 100644 --- a/helm/dbrepo/templates/metadata-deployment.yaml +++ b/helm/dbrepo/templates/metadata-deployment.yaml @@ -33,7 +33,7 @@ spec: securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.metadataservice.containerSecurityContext "context" $) | nindent 12 }} {{- end }} ports: - - containerPort: 80 + - containerPort: 8080 protocol: TCP envFrom: - secretRef: diff --git a/helm/dbrepo/values.schema.json b/helm/dbrepo/values.schema.json index a8e7bbbf74..6f83a1d170 100644 --- a/helm/dbrepo/values.schema.json +++ b/helm/dbrepo/values.schema.json @@ -516,16 +516,18 @@ "properties": { "database": { "properties": { - "auth": { + "galera": { "properties": { - "replicationPassword": { - "type": "string" - }, - "replicationUser": { - "type": "string" - }, - "rootPassword": { - "type": "string" + "mariabackup": { + "properties": { + "password": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" } }, "type": "object" @@ -546,10 +548,13 @@ }, "type": "object" }, - "secondary": { + "rootUser": { "properties": { - "replicaCount": { - "type": "integer" + "password": { + "type": "string" + }, + "user": { + "type": "string" } }, "type": "object" diff --git a/helm/dbrepo/values.yaml b/helm/dbrepo/values.yaml index 68c2e4e06f..36dceda681 100644 --- a/helm/dbrepo/values.yaml +++ b/helm/dbrepo/values.yaml @@ -27,7 +27,7 @@ clusterDomain: cluster.local ## @section Metadata Database metadatadb: - ## @param metadatadb.enabled Enable the Metadata Database. + ## @param metadatadb.enabled Enable the Metadata datadb. enabled: true ## @skip metadatadb.fullnameOverride fullnameOverride: metadata-db @@ -122,32 +122,39 @@ authservice: ## @section Data Database datadb: - ## @param datadb.enabled Enable the Data Database. - enabled: true ## @skip datadb.fullnameOverride fullnameOverride: data-db - database: - image: - ## @param datadb.database.image.debug Set the logging level to `trace`. Otherwise, set to `info`. - debug: false - metrics: - ## @skip datadb.database.metrics.enabled - enabled: true - ## @skip datadb.database.secondary - secondary: - replicaCount: 2 - auth: - ## @param datadb.auth.rootPassword The root user password. - rootPassword: dbrepo - ## @param datadb.auth.replicationUser The database replication user password - replicationUser: replication - ## @param datadb.auth.replicationPassword The database replication user password - replicationPassword: replication + ## @param datadb.host The hostname for the microservices. + host: data-db + rootUser: + ## @param datadb.rootUser.user The root username. + user: root + ## @param datadb.rootUser.password The root user password. + password: dbrepo + db: + ## @param datadb.db.name The database name. + name: dbrepo + galera: + mariabackup: + ## @param datadb.galera.mariabackup.user The database backup username. + user: backup + ## @param datadb.galera.mariabackup.password The database backup user password + password: backup + ## @param datadb.jdbcExtraArgs The extra arguments for JDBC connections in the microservices. + jdbcExtraArgs: "" + metrics: + ## @skip datadb.metrics.enabled The Prometheus settings. + enabled: false + ## @param datadb.replicaCount The number of cluster nodes, should be uneven i.e. 2n+1 + replicaCount: 3 + persistence: + ## @param datadb.persistence.enabled Enable persistent storage. + enabled: true ## @section Search Database searchdb: - ## @param searchdb.enabled Enable the Data Database. + ## @param searchdb.enabled Enable the Data datadb. enabled: true ## @skip searchdb.fullnameOverride fullnameOverride: search-db @@ -335,8 +342,10 @@ analyseservice: ## @param analyseservice.endpoint The url of the endpoint. endpoint: http://analyse-service s3: - ## @param analyseservice.s3.endpoint The S3-capable endpoint the microservice connects to. - endpoint: http://storage-service-s3:8333 + ## @param analyseservice.s3.proto The protocol of the storage service endpoint. + proto: http + ## @param analyseservice.s3.endpoint The hostname and port of the storage service endpoint. + endpoint: storage-service-s3:8333 ## @param analyseservice.replicaCount The number of replicas. replicaCount: 2 @@ -490,13 +499,6 @@ dataservice: read: SELECT ## @param dataservice.grant.write The default database permissions for users with write access. write: SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE - default: - ## @param dataservice.default.date The default date format id for dates. Default: YYYY-MM-dd (e.g. 2024-06-15). - date: 3 - ## @param dataservice.default.time The default date format id for times. Default: HH:mm:ss (e.g. 14:23:42). - time: 4 - ## @param dataservice.default.timestamp The default date format id for timestamps. Default: YYYY-MM-dd HH:mm:ss (e.g. 2024-06-15 14:23:42). - timestamp: 1 rabbitmq: ## @param dataservice.rabbitmq.consumerConcurrentMin The minimal number of RabbitMQ consumers. consumerConcurrentMin: 2 @@ -649,6 +651,9 @@ identityservice: adminPassword: admin ## @skip identityservice.global.configUserEnabled configUserEnabled: false + containerSecurityContext: + ## @skip identityservice.containerSecurityContext.enabled + enabled: true ## @param identityservice.users The admin username for internal authentication. users: admin ## @param identityservice.userPasswords The admin user password for internal authentication. @@ -767,7 +772,7 @@ ui: ## @param ui.public.broker.extra Extra metadata displayed. extra: "" database: - ## @param ui.public.database.extra Extra metadata displayed. + ## @param ui.public.datadb.extra Extra metadata displayed. extra: "" ## @skip ui.public.links links: diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py index 8e0e782bb8..b80daff7d0 100644 --- a/lib/python/dbrepo/RestClient.py +++ b/lib/python/dbrepo/RestClient.py @@ -1102,7 +1102,7 @@ class RestClient: f'201 (CREATED): {response.text}') def import_table_data(self, database_id: int, table_id: int, file_name_or_data_frame: str | DataFrame, - separator: str = ",", quote: str = "\"", skip_lines: int = 0, + separator: str = ",", quote: str = "\"", header: bool = False, line_encoding: str = "\n") -> None: """ Import a csv dataset from a file into a table in a database with given database id and table id. ATTENTION: @@ -1114,7 +1114,7 @@ class RestClient: :param file_name_or_data_frame: The path of the file that is imported on the storage service or pandas dataframe. :param separator: The csv column separator. Optional. :param quote: The column data quotation character. Optional. - :param skip_lines: The number of lines to skip. Optional. Default: 0. + :param header: If `True`, the first line contains column names, otherwise the first line is data. Optional. Default: `False`. :param line_encoding: The encoding of the line termination. Optional. Default: CR (Windows). :raises MalformedError: If the payload is rejected by the service (e.g. LOB could not be imported). @@ -1134,7 +1134,7 @@ class RestClient: url = f'/api/database/{database_id}/table/{table_id}/data/import' response = self._wrapper(method="post", url=url, force_auth=True, payload=Import(location=filename, separator=separator, quote=quote, - skip_lines=skip_lines, line_termination=line_encoding)) + header=header, line_termination=line_encoding)) if response.status_code == 202: return if response.status_code == 400: diff --git a/lib/python/dbrepo/api/dto.py b/lib/python/dbrepo/api/dto.py index fc97c2b8d7..4de986e870 100644 --- a/lib/python/dbrepo/api/dto.py +++ b/lib/python/dbrepo/api/dto.py @@ -52,8 +52,6 @@ class CreateContainer(BaseModel): name: str host: str image_id: int - sidecar_host: str - sidecar_port: int privileged_username: str privileged_password: str ui_host: Optional[str] = None @@ -94,8 +92,6 @@ class Container(BaseModel): port: int image: Image created: Timestamp - sidecar_host: Optional[str] = None - sidecar_port: Optional[int] = None ui_host: Optional[str] = None ui_port: Optional[int] = None @@ -478,8 +474,8 @@ class DeleteData(BaseModel): class Import(BaseModel): location: str separator: str + header: bool quote: Optional[str] = None - skip_lines: Optional[int] = None line_termination: Optional[str] = None diff --git a/make/dev.mk b/make/dev.mk index 76c05989eb..e95dee62fe 100644 --- a/make/dev.mk +++ b/make/dev.mk @@ -2,6 +2,8 @@ .PHONY: start-dev start-dev: build-images ## Start the development deployment. + docker container stop dbrepo-gateway-service || true + docker container rm dbrepo-gateway-service || true docker compose up -d diff --git a/make/rel.mk b/make/rel.mk index 042b93d568..f32f34dc22 100644 --- a/make/rel.mk +++ b/make/rel.mk @@ -3,7 +3,6 @@ .PHONY: tag-images tag-images: build-images ## Tag the docker images. docker tag dbrepo-analyse-service:latest "${REPOSITORY_URL}/analyse-service:${APP_VERSION}" - docker tag dbrepo-auth-service:latest "${REPOSITORY_URL}/auth-service:${APP_VERSION}" docker tag dbrepo-dashboard-service:latest "${REPOSITORY_URL}/dashboard-service:${APP_VERSION}" docker tag dbrepo-ui:latest "${REPOSITORY_URL}/ui:${APP_VERSION}" docker tag dbrepo-data-service:latest "${REPOSITORY_URL}/data-service:${APP_VERSION}" @@ -17,7 +16,6 @@ tag-images: build-images ## Tag the docker images. .PHONY: release-images release-images: tag-images ## Release the docker images. docker push "${REPOSITORY_URL}/analyse-service:${APP_VERSION}" - docker push "${REPOSITORY_URL}/auth-service:${APP_VERSION}" docker push "${REPOSITORY_URL}/dashboard-service:${APP_VERSION}" docker push "${REPOSITORY_URL}/ui:${APP_VERSION}" docker push "${REPOSITORY_URL}/data-service:${APP_VERSION}" -- GitLab