From 4e8eae979b5eb7d1a062075de4028826a2630693 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 19 May 2024 19:14:33 +0530 Subject: [PATCH 1/9] write initial rocrate operation specs --- README.md | 0 crate-db/__init__.py | 0 crate-db/api/crate-db-specs.modified.yaml | 289 +++++++++++++++++ crate-db/api/crate-db-specs.yaml | 374 ++++++++++++++++++++++ crate-db/app.py | 29 ++ crate-db/config.yaml | 68 ++++ crate-db/exceptions.py | 60 ++++ crate-db/ga4gh/__init__.py | 0 crate-db/ga4gh/controllers/server.py | 26 ++ crate-db/version.py | 0 requirements.txt | 2 + setup.py | 38 +++ 12 files changed, 886 insertions(+) create mode 100644 README.md create mode 100644 crate-db/__init__.py create mode 100644 crate-db/api/crate-db-specs.modified.yaml create mode 100644 crate-db/api/crate-db-specs.yaml create mode 100644 crate-db/app.py create mode 100644 crate-db/config.yaml create mode 100644 crate-db/exceptions.py create mode 100644 crate-db/ga4gh/__init__.py create mode 100644 crate-db/ga4gh/controllers/server.py create mode 100644 crate-db/version.py create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/crate-db/__init__.py b/crate-db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/crate-db/api/crate-db-specs.modified.yaml b/crate-db/api/crate-db-specs.modified.yaml new file mode 100644 index 0000000..d2b3863 --- /dev/null +++ b/crate-db/api/crate-db-specs.modified.yaml @@ -0,0 +1,289 @@ +components: + parameters: + rocrate_id: + description: ID of the ROCrate + in: path + name: rocrate_id + required: true + schema: + example: 609d4b156f6d1972e7f78c87 + type: string + schemas: + Error: + properties: + code: + format: int32 + type: integer + message: + type: string + required: + - code + - message + type: object + ROCrateBase: + description: The base schema for an ROCrate. + properties: + description: + description: A description of the ROCrate. + example: This is an example description of an ROCrate. + type: string + title: + description: The title of the ROCrate. + example: Example ROCrate + type: string + zenodo_info: + description: Additional information for Zenodo. + example: + doi: 10.1234/example.doi + metadata: + '...': null + type: object + required: + - title + - description + type: object + ROCrateRequest: + allOf: + - $ref: '#/components/schemas/ROCrateBase' + - properties: + rocrate: + description: The ROCrate file to upload. + example: rocrate.zip + format: binary + type: string + required: + - rocrate + type: object + ROCrateResponse: + allOf: + - $ref: '#/components/schemas/ROCrateBase' + - properties: + _id: + description: The unique identifier for the ROCrate. + example: 60b6c0f9f1d2c12a5c7d6b8e + type: string + created_at: + description: The creation date of the ROCrate. + example: 2023-01-01 12:00:00+00:00 + format: date-time + type: string + rocrate: + description: The link to the ROCrate file in MinIO. + example: https://minio.example.com/rocrates/rocrate.zip + type: string + updated_at: + description: The last update date of the ROCrate. + example: 2023-01-02 12:00:00+00:00 + format: date-time + type: string + user_id: + description: The user ID extracted from the access token. + example: 1234567890abcdef + type: string + type: object +info: + description: Microservice for managing ROCrates + title: Crate DB Microservice + version: 1.0.0 +openapi: 3.0.0 +paths: + /rocrates: + get: + description: Returns a list of all ROCrates stored in the database. + operationId: listROCrates + responses: + '200': + content: + application/json: + schema: + items: + $ref: '#/components/schemas/ROCrateResponse' + type: array + description: OK + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The request is unauthorized. + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The requester is not authorized to perform this action. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Resource not found + default: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: unexpected error + summary: Get all ROCrates + x-openapi-router-controller: ga4gh.controllers.server + post: + description: Stores a new crate in the database and uploads the zip file to + MinIO. + operationId: createROCrate + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/ROCrateRequest' + x-body-name: rocrate_data + required: true + responses: + '201': + $ref: '#/components/schemas/ROCrateResponse' + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Bad Request + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The request is unauthorized. + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The requester is not authorized to perform this action. + default: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: unexpected error + summary: Creates a new ROCrate + x-openapi-router-controller: ga4gh.controllers.server + /rocrates/{rocrate_id}: + delete: + description: Delete an existing ROCrate + operationId: deleteROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + responses: + '204': + description: No Content + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The request is unauthorized. + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The requester is not authorized to perform this action. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Resource not found + default: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: unexpected error + summary: Delete a specific ROCrate by ID + x-openapi-router-controller: ga4gh.controllers.server + get: + description: Returns a specific ROCrate stored in the database. + operationId: getROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ROCrateResponse' + description: OK + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The request is unauthorized. + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The requester is not authorized to perform this action. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Resource not found + default: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: unexpected error + summary: Get a specific ROCrate by ID + x-openapi-router-controller: ga4gh.controllers.server + put: + description: Updates an existing crate in the database and uploads the zip file + to MinIO. + operationId: updateROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/ROCrateRequest' + x-body-name: rocrate + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ROCrateResponse' + description: Crate updated successfully + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The request is unauthorized. + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The requester is not authorized to perform this action. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Resource not found + default: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: unexpected error + summary: Update an existing RO-Crate + x-openapi-router-controller: ga4gh.controllers.server +servers: +- url: http://localhost/ diff --git a/crate-db/api/crate-db-specs.yaml b/crate-db/api/crate-db-specs.yaml new file mode 100644 index 0000000..a9cc01f --- /dev/null +++ b/crate-db/api/crate-db-specs.yaml @@ -0,0 +1,374 @@ +openapi: "3.0.0" +info: + title: "Crate DB Microservice" + description: "Microservice for managing ROCrates" + version: "1.0.0" +servers: + - url: "http://localhost/" + +paths: + /rocrates: + post: + summary: Creates a new ROCrate + description: |- + Stores a new crate in the database and uploads the zip file to MinIO. + operationId: createROCrate + requestBody: + required: true + content: + multipart/form-data: + schema: + x-body-name: rocrate_data + $ref: '#/components/schemas/ROCrateRequest' + responses: + '201': + $ref: '#/components/schemas/ROCrateResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: The request is unauthorized. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: The requester is not authorized to perform this action. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + get: + summary: Get all ROCrates + description: |- + Returns a list of all ROCrates stored in the database. + operationId: listROCrates + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/ROCrateResponse" + '404': + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: The request is unauthorized. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: The requester is not authorized to perform this action. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /rocrates/{rocrate_id}: + get: + summary: Get a specific ROCrate by ID + description: |- + Returns a specific ROCrate stored in the database. + operationId: getROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/ROCrateResponse" + '404': + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: The request is unauthorized. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: The requester is not authorized to perform this action. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + put: + summary: Update an existing RO-Crate + description: |- + Updates an existing crate in the database and uploads the zip file to MinIO. + operationId: updateROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + requestBody: + required: true + content: + multipart/form-data: + schema: + x-body-name: rocrate + $ref: '#/components/schemas/ROCrateRequest' + responses: + '200': + description: Crate updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ROCrateResponse' + '404': + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: The request is unauthorized. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: The requester is not authorized to perform this action. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + + delete: + summary: Delete a specific ROCrate by ID + description: |- + Delete an existing ROCrate + operationId: deleteROCrate + parameters: + - $ref: '#/components/parameters/rocrate_id' + responses: + '204': + description: No Content + '404': + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: The request is unauthorized. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: The requester is not authorized to perform this action. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + +components: + schemas: + # ROCrateBase: + # description: The base schema for an ROCrate. + # type: object + # properties: + # title: + # type: string + # description: The title of the ROCrate. + # example: Example ROCrate + # description: + # type: string + # description: A description of the ROCrate. + # example: This is an example description of an ROCrate. + # zenodo_info: + # type: object + # description: Additional information for Zenodo. + # example: + # doi: 10.1234/example.doi + # metadata: {...} + # required: + # - title + # - description + + # ROCrateRequest: + # allOf: + # - $ref: '#/components/schemas/ROCrateBase' + # - type: object + # properties: + # rocrate: + # type: string + # format: binary + # description: The ROCrate file to upload. + # example: rocrate.zip + # required: + # - rocrate + + # ROCrateResponse: + # allOf: + # - $ref: '#/components/schemas/ROCrateBase' + # - type: object + # properties: + # _id: + # type: string + # description: The unique identifier for the ROCrate. + # example: 60b6c0f9f1d2c12a5c7d6b8e + # rocrate: + # type: string + # description: The link to the ROCrate file in MinIO. + # example: https://minio.example.com/rocrates/rocrate.zip + # created_at: + # type: string + # format: date-time + # description: The creation date of the ROCrate. + # example: 2023-01-01T12:00:00Z + # updated_at: + # type: string + # format: date-time + # description: The last update date of the ROCrate. + # example: 2023-01-02T12:00:00Z + # user_id: + # type: string + # description: The user ID extracted from the access token. + # example: 1234567890abcdef + + ROCrateRequest: + description: The base schema for an ROCrate. + type: object + properties: + rocrate: + type: string + format: binary + description: The ROCrate file to upload. + example: rocrate.zip + description: + type: string + description: A description of the ROCrate. + example: This is an example description of an ROCrate. + title: + type: string + description: The title of the ROCrate. + example: Example ROCrate + zenodo_info: + type: object + description: Additional information for Zenodo. + example: + doi: 10.1234/example.doi + metadata: {...} + required: + - rocrate + - title + - description + + ROCrateResponse: + description: The base schema for an ROCrate. + type: object + properties: + _id: + type: string + description: The unique identifier for the ROCrate. + example: 60b6c0f9f1d2c12a5c7d6b8e + rocrate: + type: string + description: The link to the ROCrate file in MinIO. + example: https://minio.example.com/rocrates/rocrate.zip + created_at: + type: string + format: date-time + description: The creation date of the ROCrate. + example: 2023-01-01T12:00:00Z + updated_at: + type: string + format: date-time + description: The last update date of the ROCrate. + example: 2023-01-02T12:00:00Z + user_id: + type: string + description: The user ID extracted from the access token. + example: 1234567890abcdef + title: + type: string + description: The title of the ROCrate. + example: Example ROCrate + description: + type: string + description: A description of the ROCrate. + example: This is an example description of an ROCrate + zenodo_info: + type: object + description: Additional information for Zenodo. + example: + doi: 10.1234/example.doi + metadata: {...} + required: + - _id + - rocrate + - created_at + - updated_at + - user_id + - title + - description + + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + + parameters: + rocrate_id: + name: rocrate_id + in: path + description: ID of the ROCrate + required: true + schema: + type: string + example: "609d4b156f6d1972e7f78c87" \ No newline at end of file diff --git a/crate-db/app.py b/crate-db/app.py new file mode 100644 index 0000000..8b16a3e --- /dev/null +++ b/crate-db/app.py @@ -0,0 +1,29 @@ +"""API server entry point.""" + +from pathlib import Path + +from connexion import FlaskApp # type: ignore +from foca import Foca # type: ignore + + +def init_app() -> FlaskApp: + """Initialize FOCA application. + + Returns: + FOCA application. + """ + foca = Foca( + config_file=Path(__file__).resolve().parent / "config.yaml", + ) + app = foca.create_app() + return app + + +def run_app(app: FlaskApp) -> None: + """Run FOCA application.""" + app.run(port=app.port) + + +if __name__ == "__main__": + my_app = init_app() + run_app(my_app) diff --git a/crate-db/config.yaml b/crate-db/config.yaml new file mode 100644 index 0000000..d2a4977 --- /dev/null +++ b/crate-db/config.yaml @@ -0,0 +1,68 @@ +# FOCA configuration +# Available in app context as attributes of `current_app.config.foca` +# Automatically validated via FOCA +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html + +# Server configuration +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.ServerConfig +server: + host: "0.0.0.0" + port: 8080 + debug: True + environment: development + testing: False + use_reloader: True + +# Security configuration +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.SecurityConfig +security: + auth: + required: True + add_key_to_claims: True + algorithms: + - RS256 + allow_expired: False + audience: null + validation_methods: + - userinfo + - public_key + validation_checks: all + + +# Database configuration +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.DBConfig +db: + host: mongodb + port: 27017 + dbs: + ro-crate-db: + collections: + ro-crates: + indexes: null + +# API configuration +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.APIConfig +api: + specs: + - path: + - api/crate-db-specs.yaml + add_operation_fields: + x-openapi-router-controller: ga4gh.controllers.server + security: + - bearerAuth: [] + add_security_fields: + x-bearerInfoFunc: app.validate_token + disable_auth: True + connexion: + strict_validation: True + validate_responses: False + options: + swagger_ui: True + serve_spec: True + +# Exception configuration +# Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.ExceptionConfig +Exceptions: + required_members: [['message'], ['code']] + status_member: ['code'] + exceptions: exceptions.exceptions \ No newline at end of file diff --git a/crate-db/exceptions.py b/crate-db/exceptions.py new file mode 100644 index 0000000..b561d42 --- /dev/null +++ b/crate-db/exceptions.py @@ -0,0 +1,60 @@ +"""Petstore exceptions.""" + +from connexion.exceptions import ( + BadRequestProblem, + ExtraParameterProblem, + Forbidden, + Unauthorized, + OAuthProblem, +) +from werkzeug.exceptions import ( + BadRequest, + InternalServerError, + NotFound, +) + +exceptions = { + Exception: { + "message": "Oops, something unexpected happened.", + "code": 500, + }, + BadRequestProblem: { + "message": "We don't quite understand what it is you are looking for.", + "code": 400, + }, + BadRequest: { + "message": "We don't quite understand what it is you are looking for.", + "code": 400, + }, + ExtraParameterProblem: { + "message": "We don't quite understand what it is you are looking for.", + "code": 400, + }, + OAuthProblem: { + "message": ( + "Unauthorized! You need to be logged in to" + "perform this action." + ), + "code": 401, + }, + Unauthorized: { + "message": ( + "Unauthorized!" + ), + "code": 401, + }, + Forbidden: { + "message": ( + "Not authorized to perform this action." + ), + "code": 403, + }, + NotFound: { + "message": "Not sure what you are looking for, but it's not here.", + "code": 404, + }, + InternalServerError: { + "message": "Oops, something unexpected happened.", + "code": 500, + }, +} \ No newline at end of file diff --git a/crate-db/ga4gh/__init__.py b/crate-db/ga4gh/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/crate-db/ga4gh/controllers/server.py b/crate-db/ga4gh/controllers/server.py new file mode 100644 index 0000000..605cc11 --- /dev/null +++ b/crate-db/ga4gh/controllers/server.py @@ -0,0 +1,26 @@ +from typing import Dict, List + + +def createROCrate(rocrate_data, rocrate) -> Dict: + print(rocrate_data) + print(rocrate) + return "Demo request" + + +def listROCrates() -> List: + return "Demo request" + + +def getROCrate(rocrate_id: str) -> Dict: + print(rocrate_id) + return "Demo request" + + +def updateROCrate(rocrate_id: str) -> Dict: + print(rocrate_id) + return "Demo request" + + +def deleteROCrate(rocrate_id: str) -> Dict: + print(rocrate_id) + return "Demo request" diff --git a/crate-db/version.py b/crate-db/version.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dd0e5d6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +connexion>=2.11.2,<3 +foca>=0.12.1 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..92f4389 --- /dev/null +++ b/setup.py @@ -0,0 +1,38 @@ +"""Package setup.""" + +from pathlib import Path +from setuptools import setup, find_packages + +root_dir = Path(__file__).parent.resolve() + +__version__ = exec(open(root_dir / "crate-db" / "version.py").read()) + +file_name = root_dir / "README.md" +with open(file_name, "r") as _file: + long_description = _file.read() + +install_requires = [] +req = root_dir / 'requirements.txt' +with open(req, "r") as _file: + install_requires = _file.read().splitlines() + +setup( + name="foca", + version=__version__, # noqa: F821 + description=( + "Microservice for managing ROCrates" + ), + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/elixir-cloud-aai/crate-db", + project_urls={ + "Repository": "https://github.com/elixir-cloud-aai/crate-db", + "Tracker": "https://github.com/elixir-cloud-aai/crate-db/issues", + }, + packages=find_packages(), + setup_requires=[ + "setuptools_git==1.2", + "twine==3.8.0" + ], + install_requires=install_requires, +) From dd8f4693f9c10c985b132d976f849846599bc202 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 14:56:04 +0530 Subject: [PATCH 2/9] refactor package setup using poetry --- .github/workflows/checks.yaml | 35 + .gitignore | 1 + README.md | 18 + crate-db/api/crate-db-specs.modified.yaml | 289 ----- crate-db/api/crate-db-specs.yaml | 374 ------ crate-db/exceptions.py | 60 - crate-db/ga4gh/__init__.py | 0 crate-db/ga4gh/controllers/server.py | 26 - crate-db/version.py | 0 crate_db/__init__.py | 1 + {crate-db => crate_db/api}/__init__.py | 0 crate_db/api/crate_db_specs.yaml | 454 +++++++ {crate-db => crate_db}/app.py | 7 +- {crate-db => crate_db}/config.yaml | 7 +- crate_db/exceptions.py | 49 + crate_db/ga4gh/__init__.py | 1 + crate_db/ga4gh/controllers/server.py | 42 + crate_db/ga4gh/service_info.py | 81 ++ crate_db/ga4gh/services/__init__.py | 1 + poetry.lock | 1322 +++++++++++++++++++++ pyproject.toml | 19 + setup.py | 38 - tests/__init__.py | 1 + 23 files changed, 2034 insertions(+), 792 deletions(-) create mode 100644 .github/workflows/checks.yaml delete mode 100644 crate-db/api/crate-db-specs.modified.yaml delete mode 100644 crate-db/api/crate-db-specs.yaml delete mode 100644 crate-db/exceptions.py delete mode 100644 crate-db/ga4gh/__init__.py delete mode 100644 crate-db/ga4gh/controllers/server.py delete mode 100644 crate-db/version.py create mode 100644 crate_db/__init__.py rename {crate-db => crate_db/api}/__init__.py (100%) create mode 100644 crate_db/api/crate_db_specs.yaml rename {crate-db => crate_db}/app.py (71%) rename {crate-db => crate_db}/config.yaml (96%) create mode 100644 crate_db/exceptions.py create mode 100644 crate_db/ga4gh/__init__.py create mode 100644 crate_db/ga4gh/controllers/server.py create mode 100644 crate_db/ga4gh/service_info.py create mode 100644 crate_db/ga4gh/services/__init__.py create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 setup.py create mode 100644 tests/__init__.py diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml new file mode 100644 index 0000000..814d185 --- /dev/null +++ b/.github/workflows/checks.yaml @@ -0,0 +1,35 @@ +name: crate_db checks + +on: [push, pull_request] + +jobs: + lint-and-test: + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: [3.10, 3.11] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install poetry + poetry install + + - name: Lint with flake8 + run: | + pip install flake8 + flake8 crate_db tests + + - name: Run tests + run: | + poetry run pytest diff --git a/.gitignore b/.gitignore index 68bc17f..ae0eade 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ var/ wheels/ share/python-wheels/ *.egg-info/ +*.modified.yaml .installed.cfg *.egg MANIFEST diff --git a/README.md b/README.md index e69de29..8e43d1c 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,18 @@ +# ELIXIR Crate DB + +[![License][badge-license]][badge-url-license] +[![Docs][badge-docs]][badge-url-docs] +[![Build_status][badge-build-status]][badge-url-build-status] +[![Coverage][badge-coverage]][badge-url-coverage] + +## Description + +Various research artifacts are produced daily around the world, but managing +them is a tedious task for a researcher as any researcher will want to spend +more time researching new stuff rather than finding a way to efficiently store, +retrieve, or share them. The management of these research artifacts becomes a +problem, that's where exactly Crate DB comes into play. + +Crate DB mainly focuses on developing a versatile backend to +manage and share RO_Crates using various technologies. The end goal is to +make it easy for a user to manage any RO_Crate. \ No newline at end of file diff --git a/crate-db/api/crate-db-specs.modified.yaml b/crate-db/api/crate-db-specs.modified.yaml deleted file mode 100644 index d2b3863..0000000 --- a/crate-db/api/crate-db-specs.modified.yaml +++ /dev/null @@ -1,289 +0,0 @@ -components: - parameters: - rocrate_id: - description: ID of the ROCrate - in: path - name: rocrate_id - required: true - schema: - example: 609d4b156f6d1972e7f78c87 - type: string - schemas: - Error: - properties: - code: - format: int32 - type: integer - message: - type: string - required: - - code - - message - type: object - ROCrateBase: - description: The base schema for an ROCrate. - properties: - description: - description: A description of the ROCrate. - example: This is an example description of an ROCrate. - type: string - title: - description: The title of the ROCrate. - example: Example ROCrate - type: string - zenodo_info: - description: Additional information for Zenodo. - example: - doi: 10.1234/example.doi - metadata: - '...': null - type: object - required: - - title - - description - type: object - ROCrateRequest: - allOf: - - $ref: '#/components/schemas/ROCrateBase' - - properties: - rocrate: - description: The ROCrate file to upload. - example: rocrate.zip - format: binary - type: string - required: - - rocrate - type: object - ROCrateResponse: - allOf: - - $ref: '#/components/schemas/ROCrateBase' - - properties: - _id: - description: The unique identifier for the ROCrate. - example: 60b6c0f9f1d2c12a5c7d6b8e - type: string - created_at: - description: The creation date of the ROCrate. - example: 2023-01-01 12:00:00+00:00 - format: date-time - type: string - rocrate: - description: The link to the ROCrate file in MinIO. - example: https://minio.example.com/rocrates/rocrate.zip - type: string - updated_at: - description: The last update date of the ROCrate. - example: 2023-01-02 12:00:00+00:00 - format: date-time - type: string - user_id: - description: The user ID extracted from the access token. - example: 1234567890abcdef - type: string - type: object -info: - description: Microservice for managing ROCrates - title: Crate DB Microservice - version: 1.0.0 -openapi: 3.0.0 -paths: - /rocrates: - get: - description: Returns a list of all ROCrates stored in the database. - operationId: listROCrates - responses: - '200': - content: - application/json: - schema: - items: - $ref: '#/components/schemas/ROCrateResponse' - type: array - description: OK - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The request is unauthorized. - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The requester is not authorized to perform this action. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Resource not found - default: - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: unexpected error - summary: Get all ROCrates - x-openapi-router-controller: ga4gh.controllers.server - post: - description: Stores a new crate in the database and uploads the zip file to - MinIO. - operationId: createROCrate - requestBody: - content: - multipart/form-data: - schema: - $ref: '#/components/schemas/ROCrateRequest' - x-body-name: rocrate_data - required: true - responses: - '201': - $ref: '#/components/schemas/ROCrateResponse' - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Bad Request - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The request is unauthorized. - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The requester is not authorized to perform this action. - default: - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: unexpected error - summary: Creates a new ROCrate - x-openapi-router-controller: ga4gh.controllers.server - /rocrates/{rocrate_id}: - delete: - description: Delete an existing ROCrate - operationId: deleteROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - responses: - '204': - description: No Content - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The request is unauthorized. - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The requester is not authorized to perform this action. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Resource not found - default: - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: unexpected error - summary: Delete a specific ROCrate by ID - x-openapi-router-controller: ga4gh.controllers.server - get: - description: Returns a specific ROCrate stored in the database. - operationId: getROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/ROCrateResponse' - description: OK - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The request is unauthorized. - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The requester is not authorized to perform this action. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Resource not found - default: - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: unexpected error - summary: Get a specific ROCrate by ID - x-openapi-router-controller: ga4gh.controllers.server - put: - description: Updates an existing crate in the database and uploads the zip file - to MinIO. - operationId: updateROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - requestBody: - content: - multipart/form-data: - schema: - $ref: '#/components/schemas/ROCrateRequest' - x-body-name: rocrate - required: true - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/ROCrateResponse' - description: Crate updated successfully - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The request is unauthorized. - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: The requester is not authorized to perform this action. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Resource not found - default: - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: unexpected error - summary: Update an existing RO-Crate - x-openapi-router-controller: ga4gh.controllers.server -servers: -- url: http://localhost/ diff --git a/crate-db/api/crate-db-specs.yaml b/crate-db/api/crate-db-specs.yaml deleted file mode 100644 index a9cc01f..0000000 --- a/crate-db/api/crate-db-specs.yaml +++ /dev/null @@ -1,374 +0,0 @@ -openapi: "3.0.0" -info: - title: "Crate DB Microservice" - description: "Microservice for managing ROCrates" - version: "1.0.0" -servers: - - url: "http://localhost/" - -paths: - /rocrates: - post: - summary: Creates a new ROCrate - description: |- - Stores a new crate in the database and uploads the zip file to MinIO. - operationId: createROCrate - requestBody: - required: true - content: - multipart/form-data: - schema: - x-body-name: rocrate_data - $ref: '#/components/schemas/ROCrateRequest' - responses: - '201': - $ref: '#/components/schemas/ROCrateResponse' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: The request is unauthorized. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: The requester is not authorized to perform this action. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - default: - description: unexpected error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - get: - summary: Get all ROCrates - description: |- - Returns a list of all ROCrates stored in the database. - operationId: listROCrates - responses: - '200': - description: OK - content: - application/json: - schema: - type: array - items: - $ref: "#/components/schemas/ROCrateResponse" - '404': - description: Resource not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: The request is unauthorized. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: The requester is not authorized to perform this action. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - default: - description: unexpected error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /rocrates/{rocrate_id}: - get: - summary: Get a specific ROCrate by ID - description: |- - Returns a specific ROCrate stored in the database. - operationId: getROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: "#/components/schemas/ROCrateResponse" - '404': - description: Resource not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: The request is unauthorized. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: The requester is not authorized to perform this action. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - default: - description: unexpected error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - put: - summary: Update an existing RO-Crate - description: |- - Updates an existing crate in the database and uploads the zip file to MinIO. - operationId: updateROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - requestBody: - required: true - content: - multipart/form-data: - schema: - x-body-name: rocrate - $ref: '#/components/schemas/ROCrateRequest' - responses: - '200': - description: Crate updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ROCrateResponse' - '404': - description: Resource not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: The request is unauthorized. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: The requester is not authorized to perform this action. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - default: - description: unexpected error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - - delete: - summary: Delete a specific ROCrate by ID - description: |- - Delete an existing ROCrate - operationId: deleteROCrate - parameters: - - $ref: '#/components/parameters/rocrate_id' - responses: - '204': - description: No Content - '404': - description: Resource not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: The request is unauthorized. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: The requester is not authorized to perform this action. - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - default: - description: unexpected error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - -components: - schemas: - # ROCrateBase: - # description: The base schema for an ROCrate. - # type: object - # properties: - # title: - # type: string - # description: The title of the ROCrate. - # example: Example ROCrate - # description: - # type: string - # description: A description of the ROCrate. - # example: This is an example description of an ROCrate. - # zenodo_info: - # type: object - # description: Additional information for Zenodo. - # example: - # doi: 10.1234/example.doi - # metadata: {...} - # required: - # - title - # - description - - # ROCrateRequest: - # allOf: - # - $ref: '#/components/schemas/ROCrateBase' - # - type: object - # properties: - # rocrate: - # type: string - # format: binary - # description: The ROCrate file to upload. - # example: rocrate.zip - # required: - # - rocrate - - # ROCrateResponse: - # allOf: - # - $ref: '#/components/schemas/ROCrateBase' - # - type: object - # properties: - # _id: - # type: string - # description: The unique identifier for the ROCrate. - # example: 60b6c0f9f1d2c12a5c7d6b8e - # rocrate: - # type: string - # description: The link to the ROCrate file in MinIO. - # example: https://minio.example.com/rocrates/rocrate.zip - # created_at: - # type: string - # format: date-time - # description: The creation date of the ROCrate. - # example: 2023-01-01T12:00:00Z - # updated_at: - # type: string - # format: date-time - # description: The last update date of the ROCrate. - # example: 2023-01-02T12:00:00Z - # user_id: - # type: string - # description: The user ID extracted from the access token. - # example: 1234567890abcdef - - ROCrateRequest: - description: The base schema for an ROCrate. - type: object - properties: - rocrate: - type: string - format: binary - description: The ROCrate file to upload. - example: rocrate.zip - description: - type: string - description: A description of the ROCrate. - example: This is an example description of an ROCrate. - title: - type: string - description: The title of the ROCrate. - example: Example ROCrate - zenodo_info: - type: object - description: Additional information for Zenodo. - example: - doi: 10.1234/example.doi - metadata: {...} - required: - - rocrate - - title - - description - - ROCrateResponse: - description: The base schema for an ROCrate. - type: object - properties: - _id: - type: string - description: The unique identifier for the ROCrate. - example: 60b6c0f9f1d2c12a5c7d6b8e - rocrate: - type: string - description: The link to the ROCrate file in MinIO. - example: https://minio.example.com/rocrates/rocrate.zip - created_at: - type: string - format: date-time - description: The creation date of the ROCrate. - example: 2023-01-01T12:00:00Z - updated_at: - type: string - format: date-time - description: The last update date of the ROCrate. - example: 2023-01-02T12:00:00Z - user_id: - type: string - description: The user ID extracted from the access token. - example: 1234567890abcdef - title: - type: string - description: The title of the ROCrate. - example: Example ROCrate - description: - type: string - description: A description of the ROCrate. - example: This is an example description of an ROCrate - zenodo_info: - type: object - description: Additional information for Zenodo. - example: - doi: 10.1234/example.doi - metadata: {...} - required: - - _id - - rocrate - - created_at - - updated_at - - user_id - - title - - description - - Error: - type: object - required: - - code - - message - properties: - code: - type: integer - format: int32 - message: - type: string - - parameters: - rocrate_id: - name: rocrate_id - in: path - description: ID of the ROCrate - required: true - schema: - type: string - example: "609d4b156f6d1972e7f78c87" \ No newline at end of file diff --git a/crate-db/exceptions.py b/crate-db/exceptions.py deleted file mode 100644 index b561d42..0000000 --- a/crate-db/exceptions.py +++ /dev/null @@ -1,60 +0,0 @@ -"""Petstore exceptions.""" - -from connexion.exceptions import ( - BadRequestProblem, - ExtraParameterProblem, - Forbidden, - Unauthorized, - OAuthProblem, -) -from werkzeug.exceptions import ( - BadRequest, - InternalServerError, - NotFound, -) - -exceptions = { - Exception: { - "message": "Oops, something unexpected happened.", - "code": 500, - }, - BadRequestProblem: { - "message": "We don't quite understand what it is you are looking for.", - "code": 400, - }, - BadRequest: { - "message": "We don't quite understand what it is you are looking for.", - "code": 400, - }, - ExtraParameterProblem: { - "message": "We don't quite understand what it is you are looking for.", - "code": 400, - }, - OAuthProblem: { - "message": ( - "Unauthorized! You need to be logged in to" - "perform this action." - ), - "code": 401, - }, - Unauthorized: { - "message": ( - "Unauthorized!" - ), - "code": 401, - }, - Forbidden: { - "message": ( - "Not authorized to perform this action." - ), - "code": 403, - }, - NotFound: { - "message": "Not sure what you are looking for, but it's not here.", - "code": 404, - }, - InternalServerError: { - "message": "Oops, something unexpected happened.", - "code": 500, - }, -} \ No newline at end of file diff --git a/crate-db/ga4gh/__init__.py b/crate-db/ga4gh/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/crate-db/ga4gh/controllers/server.py b/crate-db/ga4gh/controllers/server.py deleted file mode 100644 index 605cc11..0000000 --- a/crate-db/ga4gh/controllers/server.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Dict, List - - -def createROCrate(rocrate_data, rocrate) -> Dict: - print(rocrate_data) - print(rocrate) - return "Demo request" - - -def listROCrates() -> List: - return "Demo request" - - -def getROCrate(rocrate_id: str) -> Dict: - print(rocrate_id) - return "Demo request" - - -def updateROCrate(rocrate_id: str) -> Dict: - print(rocrate_id) - return "Demo request" - - -def deleteROCrate(rocrate_id: str) -> Dict: - print(rocrate_id) - return "Demo request" diff --git a/crate-db/version.py b/crate-db/version.py deleted file mode 100644 index e69de29..0000000 diff --git a/crate_db/__init__.py b/crate_db/__init__.py new file mode 100644 index 0000000..772d776 --- /dev/null +++ b/crate_db/__init__.py @@ -0,0 +1 @@ +"""Crate DB root package""" diff --git a/crate-db/__init__.py b/crate_db/api/__init__.py similarity index 100% rename from crate-db/__init__.py rename to crate_db/api/__init__.py diff --git a/crate_db/api/crate_db_specs.yaml b/crate_db/api/crate_db_specs.yaml new file mode 100644 index 0000000..9efa5bf --- /dev/null +++ b/crate_db/api/crate_db_specs.yaml @@ -0,0 +1,454 @@ +openapi: "3.1.0" +info: + title: "OpenAPI specification for managing RO-Crates" + description: "Microservice for managing RO-Crates" + version: "0.1.0" +servers: + - url: /elixircloud/roc/v1 + +paths: + /service-info: + post: + summary: 'Create new service information' + description: 'Create a new service information resource.' + operationId: createServiceInfo + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + responses: + 201: + description: Identifier of the created RO-Crate resource + content: + application/json: + schema: + $ref: '#/components/schemas/CreateROCResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 500: + $ref: '#/components/responses/UnexpectedError' + + get: + description: |- + Provides information about the service, this structure is based on the + standardized GA4GH service info structure. In addition, this endpoint + will also provide information about customized storage endpoints offered + by the TES server. + operationId: getServiceInfo + responses: + 200: + description: 'A successful operation to request the service information about this running service.' + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/UnexpectedError' + + put: + summary: 'Update existing service information' + description: 'Update an existing service information resource.' + operationId: updateServiceInfo + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + responses: + 204: + description: No Content + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/UnexpectedError' + + /ro-crates: + post: + summary: Create RO-Crate resource + description: Create a new RO-Crate resource. + operationId: createROC + requestBody: + required: true + content: + multipart/form-data: + schema: + x-body-name: createROCRequestBody + $ref: '#/components/schemas/CreateROCRequestBody' + responses: + 201: + description: Identifier of the created RO-Crate resource + content: + application/json: + schema: + $ref: '#/components/schemas/CreateROCResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 500: + $ref: '#/components/responses/UnexpectedError' + + get: + summary: List all RO-Crate resources + description: Retrieve a list of all RO-Crate resources stored in the database. + operationId: listROCs + responses: + 200: + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ROCrateResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/UnexpectedError' + + /ro-crates/{roc-id}: + get: + summary: Retrieve a specific RO-Crate resource by ID + description: Retrieve a specific RO-Crate resource stored in the database. + operationId: getROC + parameters: + - name: roc-id + in: path + description: An identifier referencing an RO-Crate resource. + required: true + schema: + type: string + example: "260e7aa0-2e07-484e-9da7-ee19fdd1800d" + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ROCrateResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/UnexpectedError' + + put: + summary: Update an existing RO-Crate resource + description: Update an existing RO-Crate resource. + operationId: updateROC + parameters: + - name: roc-id + in: path + description: An identifier referencing an RO-Crate resource. + required: true + schema: + type: string + example: "260e7aa0-2e07-484e-9da7-ee19fdd1800d" + requestBody: + required: true + content: + multipart/form-data: + schema: + x-body-name: updateROCRequestBody + $ref: '#/components/schemas/UpdateROCRequestBody' + responses: + 204: + description: No Content + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/UnexpectedError' + +components: + schemas: + Service: + description: 'GA4GH service' + type: object + required: + - id + - name + - type + - organization + - version + properties: + id: + type: string + description: 'Unique ID of this service. Reverse domain name notation is recommended, though not required. The identifier should attempt to be globally unique so it can be used in downstream aggregator services e.g. Service Registry.' + example: 'org.ga4gh.myservice' + name: + type: string + description: 'Name of this service. Should be human readable.' + example: 'My project' + type: + $ref: '#/components/schemas/ServiceType' + description: + type: string + description: 'Description of the service. Should be human readable and provide information about the service.' + example: 'This service provides...' + organization: + type: object + description: 'Organization providing the service' + required: + - name + - url + properties: + name: + type: string + description: 'Name of the organization responsible for the service' + example: 'My organization' + url: + type: string + format: uri + description: 'URL of the website of the organization (RFC 3986 format)' + example: 'https://example.com' + contactUrl: + type: string + format: uri + description: 'URL of the contact for the provider of this service, e.g. a link to a contact form (RFC 3986 format), or an email (RFC 2368 format).' + example: 'mailto:support@example.com' + documentationUrl: + type: string + format: uri + description: 'URL of the documentation of this service (RFC 3986 format). This should help someone learn how to use your service, including any specifics required to access data, e.g. authentication.' + example: 'https://docs.myservice.example.com' + createdAt: + type: string + format: date-time + description: 'Timestamp describing when the service was first deployed and available (RFC 3339 format)' + example: '2019-06-04T12:58:19Z' + updatedAt: + type: string + format: date-time + description: 'Timestamp describing when the service was last updated (RFC 3339 format)' + example: '2019-06-04T12:58:19Z' + environment: + type: string + description: 'Environment the service is running in. Use this to distinguish between production, development and testing/staging deployments. Suggested values are prod, test, dev, staging. However this is advised and not enforced.' + example: 'test' + version: + type: string + description: 'Version of the service being described. Semantic versioning is recommended, but other identifiers, such as dates or commit hashes, are also allowed. The version should be changed whenever the service is updated.' + example: '1.0.0' + + ServiceType: + description: 'Type of a GA4GH service' + type: object + required: + - group + - artifact + - version + properties: + group: + type: string + description: 'Namespace in reverse domain name format. Use `org.ga4gh` for implementations compliant with official GA4GH specifications. For services with custom APIs not standardized by GA4GH, or implementations diverging from official GA4GH specifications, use a different namespace (e.g. your organization''s reverse domain name).' + example: 'org.ga4gh' + artifact: + type: string + description: 'Name of the API or GA4GH specification implemented. Official GA4GH types should be assigned as part of standards approval process. Custom artifacts are supported.' + example: 'beacon' + version: + type: string + description: 'Version of the API or specification. GA4GH specifications use semantic versioning.' + example: '1.0.0' + + CreateROCRequestBody: + type: object + properties: + rocrate: + type: string + format: binary + description: The RO-Crate file to upload. + example: rocrate.zip + description: + type: string + description: A description of the RO-Crate. + example: This is an example description of an RO-Crate. + title: + type: string + description: The title of the RO-Crate. + example: Example RO-Crate + zenodo_info: + type: object + description: Additional information for Zenodo. + example: + doi: 10.1234/example.doi + metadata: {...} + required: + - rocrate + - title + - description + + CreateROCResponse: + type: object + properties: + _id: + type: string + format: uuid + description: The unique identifier for the RO-Crate. + example: 260e7aa0-2e07-484e-9da7-ee19fdd1800d + + ROCrateResponse: + type: object + properties: + _id: + type: string + description: The unique identifier for the RO-Crate. + example: 60b6c0f9f1d2c12a5c7d6b8e + rocrate: + type: string + description: The link to the RO-Crate file in MinIO. + example: https://minio.example.com/ro-crates/rocrate.zip + created_at: + type: string + format: date-time + description: The creation date of the RO-Crate. + example: 2023-01-01T12:00:00Z + updated_at: + type: string + format: date-time + description: The last update date of the RO-Crate. + example: 2023-01-02T12:00:00Z + user_id: + type: string + format: uuid + description: The user ID extracted from the access token. + example: 260e7aa0-2e07-484e-9da7-ee19fdd1800d + title: + type: string + description: The title of the RO-Crate. + example: Example RO-Crate + description: + type: string + description: A description of the RO-Crate. + example: This is an example description of an RO-Crate. + zenodo_info: + type: object + description: Additional information for Zenodo. + example: + doi: 10.1234/example.doi + metadata: {...} + required: + - _id + - rocrate + - created_at + - updated_at + - user_id + - title + - description + + responses: + BadRequest: + description: Bad Request + content: + application/json: + schema: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + + Unauthorized: + description: Unauthorized + content: + application/json: + schema: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + + Forbidden: + description: Forbidden + content: + application/json: + schema: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + + NotFound: + description: Resource Not Found + content: + application/json: + schema: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + + UnexpectedError: + description: Unexpected Error + content: + application/json: + schema: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + + parameters: + roc-id: + name: roc-id + in: path + description: An identifier referencing an RO-Crate resource. + required: true + schema: + type: string + format: uuid + example: 260e7aa0-2e07-484e-9da7-ee19fdd1800d diff --git a/crate-db/app.py b/crate_db/app.py similarity index 71% rename from crate-db/app.py rename to crate_db/app.py index 8b16a3e..5665ca4 100644 --- a/crate-db/app.py +++ b/crate_db/app.py @@ -3,7 +3,9 @@ from pathlib import Path from connexion import FlaskApp # type: ignore -from foca import Foca # type: ignore +from foca import Foca + +from crate_db.ga4gh.service_info import ServiceInfo # type: ignore def init_app() -> FlaskApp: @@ -16,6 +18,9 @@ def init_app() -> FlaskApp: config_file=Path(__file__).resolve().parent / "config.yaml", ) app = foca.create_app() + with app.app.app_context(): + service_info = ServiceInfo() + service_info.init_service_info_from_config() return app diff --git a/crate-db/config.yaml b/crate_db/config.yaml similarity index 96% rename from crate-db/config.yaml rename to crate_db/config.yaml index d2a4977..ad7de8e 100644 --- a/crate-db/config.yaml +++ b/crate_db/config.yaml @@ -28,16 +28,15 @@ security: - public_key validation_checks: all - # Database configuration # Cf. https://foca.readthedocs.io/en/latest/modules/foca.models.html#foca.models.config.DBConfig db: host: mongodb port: 27017 dbs: - ro-crate-db: + ro_crate_db: collections: - ro-crates: + ro_crates: indexes: null # API configuration @@ -45,7 +44,7 @@ db: api: specs: - path: - - api/crate-db-specs.yaml + - api/crate_db_specs.yaml add_operation_fields: x-openapi-router-controller: ga4gh.controllers.server security: diff --git a/crate_db/exceptions.py b/crate_db/exceptions.py new file mode 100644 index 0000000..0667061 --- /dev/null +++ b/crate_db/exceptions.py @@ -0,0 +1,49 @@ +"""Crate exceptions.""" + +from foca.errors.exceptions import ( + ExtraParameterProblem, + Forbidden, + Unauthorized, + OAuthProblem, + BadRequest, + InternalServerError, + NotFound, +) + +exceptions = { + Exception: { + "message": "An unexpected error occurred.", + "code": "500", + }, + BadRequest: { + "message": "The request is malformed.", + "code": "400", + }, + ExtraParameterProblem: { + "message": "The request is malformed.", + "code": "400", + }, + Unauthorized: { + "message": " The request is unauthorized.", + "code": "401", + }, + OAuthProblem: { + "message": ( + "Unauthorized! You need to be logged in to" + "perform this action." + ), + "code": 401, + }, + Forbidden: { + "message": "The requester is not authorized to perform this action.", + "code": "403", + }, + NotFound: { + "message": "The requested resource wasn't found.", + "code": "404", + }, + InternalServerError: { + "message": "An unexpected error occurred.", + "code": "500", + } +} diff --git a/crate_db/ga4gh/__init__.py b/crate_db/ga4gh/__init__.py new file mode 100644 index 0000000..f8a4833 --- /dev/null +++ b/crate_db/ga4gh/__init__.py @@ -0,0 +1 @@ +""" Contains functional module for the crate_db service""" diff --git a/crate_db/ga4gh/controllers/server.py b/crate_db/ga4gh/controllers/server.py new file mode 100644 index 0000000..2283113 --- /dev/null +++ b/crate_db/ga4gh/controllers/server.py @@ -0,0 +1,42 @@ +""" +Operations implementation for the RO-Crate API +""" + + +def createROC(ro_crate_data, ro_crate) -> dict: + print(ro_crate_data) + print(ro_crate) + return "Demo request" + + +def listROCs() -> list: + return "Demo request" + + +def getROC(ro_crate_id: str) -> dict: + print(ro_crate_id) + return "Demo request" + + +def updateROC(ro_crate_id: str) -> dict: + print(ro_crate_id) + return "Demo request" + + +def deleteROC(ro_crate_id: str) -> dict: + print(ro_crate_id) + return "Demo request" + + +def createServiceInfo(service_info) -> dict: + print(service_info) + return "Demo request" + + +def getServiceInfo() -> dict: + return "Demo request" + + +def updateServiceInfo(service_info) -> dict: + print(service_info) + return "Demo request" diff --git a/crate_db/ga4gh/service_info.py b/crate_db/ga4gh/service_info.py new file mode 100644 index 0000000..e2f15d8 --- /dev/null +++ b/crate_db/ga4gh/service_info.py @@ -0,0 +1,81 @@ +"""Controller for the `/service-info route.""" + +import logging + +from bson.objectid import ObjectId # type: ignore +from flask import current_app +from pymongo.collection import Collection # type: ignore + +from foca.errors.exceptions import NotFound + +logger = logging.getLogger(__name__) + + +class ServiceInfo: + """Class for service info server-side controller methods. + + Creates service info upon first request, if it does not exist. + + Attributes: + db_client: Database collection storing service info objects. + object_id: Database identifier for service info. + """ + + def __init__(self) -> None: + """Construct class instance.""" + self.db_client: Collection = ( + current_app.config.foca.db.dbs["ro_crates"] # type: ignore + .collections["service_info"] + .client + ) + self.object_id: str = "000000000000000000000000" + + def get_service_info(self) -> dict: + """Get latest service info from database. + + Returns: + Latest service info details. + + Raises: + NotFound: Service info was not found. + """ + service_info = self.db_client.find_one( + {"_id": ObjectId(self.object_id)}, + {"_id": False}, + ) + if service_info is None: + raise NotFound + return service_info + + def set_service_info(self, data: dict) -> None: + """Create or update service info. + + Arguments: + data: Dictionary of service info values. Cf. + """ + self.db_client.replace_one( + filter={"_id": ObjectId(self.object_id)}, + replacement=data, + upsert=True, + ) + logger.info(f"Service info set: {data}") + + def init_service_info_from_config(self) -> None: + """Initialize service info from config. + + Set service info only if it does not yet exist. + """ + service_info_conf = current_app.config.foca.serviceInfo # type: ignore + try: + service_info_db = self.get_service_info() + except NotFound: + logger.info("Initializing service info.") + self.set_service_info(data=service_info_conf) + return + if service_info_db != service_info_conf: + logger.info( + "Service info configuration changed. Updating service info." + ) + self.set_service_info(data=service_info_conf) + return + logger.debug("Service info already initialized and up to date.") diff --git a/crate_db/ga4gh/services/__init__.py b/crate_db/ga4gh/services/__init__.py new file mode 100644 index 0000000..0b92878 --- /dev/null +++ b/crate_db/ga4gh/services/__init__.py @@ -0,0 +1 @@ +""" Services to handle the crate_db API.""" diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..497717e --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1322 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "addict" +version = "2.4.0" +description = "Addict is a dictionary whose items can be set using both attribute and item syntax." +optional = false +python-versions = "*" +files = [ + {file = "addict-2.4.0-py3-none-any.whl", hash = "sha256:249bb56bbfd3cdc2a004ea0ff4c2b6ddc84d53bc2194761636eb314d5cfa5dfc"}, + {file = "addict-2.4.0.tar.gz", hash = "sha256:b3b2210e0e067a281f5646c8c5db92e99b7231ea8b0eb5f74dbdf9e259d4e494"}, +] + +[[package]] +name = "amqp" +version = "5.2.0" +description = "Low-level AMQP client for Python (fork of amqplib)." +optional = false +python-versions = ">=3.6" +files = [ + {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, + {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, +] + +[package.dependencies] +vine = ">=5.0.0,<6.0.0" + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "billiard" +version = "4.2.0" +description = "Python multiprocessing fork with improvements and bugfixes" +optional = false +python-versions = ">=3.7" +files = [ + {file = "billiard-4.2.0-py3-none-any.whl", hash = "sha256:07aa978b308f334ff8282bd4a746e681b3513db5c9a514cbdd810cbbdc19714d"}, + {file = "billiard-4.2.0.tar.gz", hash = "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c"}, +] + +[[package]] +name = "casbin" +version = "1.36.1" +description = "An authorization library that supports access control models like ACL, RBAC, ABAC in Python" +optional = false +python-versions = ">=3.3" +files = [ + {file = "casbin-1.36.1-py3-none-any.whl", hash = "sha256:442fa6eaa7a8e0fb6690581d475ed0da96ee39c891104ee46a3f934a3b17a9c0"}, + {file = "casbin-1.36.1.tar.gz", hash = "sha256:1817ed84c77d185edeab0856fa6e56f7ed5d986091d8ae9f292a0740b7edfd70"}, +] + +[package.dependencies] +simpleeval = ">=0.9.11" + +[[package]] +name = "celery" +version = "5.4.0" +description = "Distributed Task Queue." +optional = false +python-versions = ">=3.8" +files = [ + {file = "celery-5.4.0-py3-none-any.whl", hash = "sha256:369631eb580cf8c51a82721ec538684994f8277637edde2dfc0dacd73ed97f64"}, + {file = "celery-5.4.0.tar.gz", hash = "sha256:504a19140e8d3029d5acad88330c541d4c3f64c789d85f94756762d8bca7e706"}, +] + +[package.dependencies] +billiard = ">=4.2.0,<5.0" +click = ">=8.1.2,<9.0" +click-didyoumean = ">=0.3.0" +click-plugins = ">=1.1.1" +click-repl = ">=0.2.0" +kombu = ">=5.3.4,<6.0" +python-dateutil = ">=2.8.2" +tzdata = ">=2022.7" +vine = ">=5.1.0,<6.0" + +[package.extras] +arangodb = ["pyArango (>=2.0.2)"] +auth = ["cryptography (==42.0.5)"] +azureblockblob = ["azure-storage-blob (>=12.15.0)"] +brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +cassandra = ["cassandra-driver (>=3.25.0,<4)"] +consul = ["python-consul2 (==0.1.5)"] +cosmosdbsql = ["pydocumentdb (==2.3.5)"] +couchbase = ["couchbase (>=3.0.0)"] +couchdb = ["pycouchdb (==1.14.2)"] +django = ["Django (>=2.2.28)"] +dynamodb = ["boto3 (>=1.26.143)"] +elasticsearch = ["elastic-transport (<=8.13.0)", "elasticsearch (<=8.13.0)"] +eventlet = ["eventlet (>=0.32.0)"] +gcs = ["google-cloud-storage (>=2.10.0)"] +gevent = ["gevent (>=1.5.0)"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +memcache = ["pylibmc (==1.6.3)"] +mongodb = ["pymongo[srv] (>=4.0.2)"] +msgpack = ["msgpack (==1.0.8)"] +pymemcache = ["python-memcached (>=1.61)"] +pyro = ["pyro4 (==4.82)"] +pytest = ["pytest-celery[all] (>=1.0.0)"] +redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] +s3 = ["boto3 (>=1.26.143)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +solar = ["ephem (==4.1.5)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.4)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] +zstd = ["zstandard (==0.22.0)"] + +[[package]] +name = "certifi" +version = "2024.6.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, +] + +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-didyoumean" +version = "0.3.1" +description = "Enables git-like *did-you-mean* feature in click" +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c"}, + {file = "click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463"}, +] + +[package.dependencies] +click = ">=7" + +[[package]] +name = "click-plugins" +version = "1.1.1" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[[package]] +name = "click-repl" +version = "0.3.0" +description = "REPL plugin for Click" +optional = false +python-versions = ">=3.6" +files = [ + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, +] + +[package.dependencies] +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] + +[[package]] +name = "clickclick" +version = "20.10.2" +description = "Click utility functions" +optional = false +python-versions = "*" +files = [ + {file = "clickclick-20.10.2-py2.py3-none-any.whl", hash = "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5"}, + {file = "clickclick-20.10.2.tar.gz", hash = "sha256:4efb13e62353e34c5eef7ed6582c4920b418d7dedc86d819e22ee089ba01802c"}, +] + +[package.dependencies] +click = ">=4.0" +PyYAML = ">=3.11" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "connexion" +version = "2.14.2" +description = "Connexion - API first applications with OpenAPI/Swagger and Flask" +optional = false +python-versions = ">=3.6" +files = [ + {file = "connexion-2.14.2-py2.py3-none-any.whl", hash = "sha256:a73b96a0e07b16979a42cde7c7e26afe8548099e352cf350f80c57185e0e0b36"}, + {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, +] + +[package.dependencies] +clickclick = ">=1.2,<21" +flask = ">=1.0.4,<2.3" +inflection = ">=0.3.1,<0.6" +itsdangerous = ">=0.24" +jsonschema = ">=2.5.1,<5" +packaging = ">=20" +PyYAML = ">=5.1,<7" +requests = ">=2.9.1,<3" +werkzeug = ">=1.0,<2.3" + +[package.extras] +aiohttp = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)"] +docs = ["sphinx-autoapi (==1.8.1)"] +flask = ["flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)"] +swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] +tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] + +[[package]] +name = "cryptography" +version = "42.0.7" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"}, + {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"}, + {file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"}, + {file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"}, + {file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"}, + {file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"}, + {file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"}, + {file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "dnspython" +version = "2.6.1" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, + {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, +] + +[package.extras] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] +dnssec = ["cryptography (>=41)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] +doq = ["aioquic (>=0.9.25)"] +idna = ["idna (>=3.6)"] +trio = ["trio (>=0.23)"] +wmi = ["wmi (>=1.5.1)"] + +[[package]] +name = "flask" +version = "2.2.5" +description = "A simple framework for building complex web applications." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Flask-2.2.5-py3-none-any.whl", hash = "sha256:58107ed83443e86067e41eff4631b058178191a355886f8e479e347fa1285fdf"}, + {file = "Flask-2.2.5.tar.gz", hash = "sha256:edee9b0a7ff26621bd5a8c10ff484ae28737a2410d99b0bb9a6850c7fb977aa0"}, +] + +[package.dependencies] +click = ">=8.0" +itsdangerous = ">=2.0" +Jinja2 = ">=3.0" +Werkzeug = ">=2.2.2" + +[package.extras] +async = ["asgiref (>=3.2)"] +dotenv = ["python-dotenv"] + +[[package]] +name = "flask-authz" +version = "2.6.0" +description = "An authorization middleware for Flask that supports ACL, RBAC, ABAC, based on Casbin" +optional = false +python-versions = ">=3.5" +files = [ + {file = "flask-authz-2.6.0.tar.gz", hash = "sha256:9d55275634a64b421f54932370455946819cf48d794b0327360594731e02a46f"}, + {file = "flask_authz-2.6.0-py2.py3-none-any.whl", hash = "sha256:575cd0c99d49c7c5945601b84f56d48c2f94fa639351315f0598b5af5282a3c4"}, +] + +[package.dependencies] +casbin = ">=1.0.0" +flask = ">=1.1.0" +PyJWT = ">=2.0.1" + +[[package]] +name = "flask-cors" +version = "4.0.1" +description = "A Flask extension adding a decorator for CORS support" +optional = false +python-versions = "*" +files = [ + {file = "Flask_Cors-4.0.1-py2.py3-none-any.whl", hash = "sha256:f2a704e4458665580c074b714c4627dd5a306b333deb9074d0b1794dfa2fb677"}, + {file = "flask_cors-4.0.1.tar.gz", hash = "sha256:eeb69b342142fdbf4766ad99357a7f3876a2ceb77689dc10ff912aac06c389e4"}, +] + +[package.dependencies] +Flask = ">=0.9" + +[[package]] +name = "flask-pymongo" +version = "2.3.0" +description = "PyMongo support for Flask applications" +optional = false +python-versions = "*" +files = [ + {file = "Flask-PyMongo-2.3.0.tar.gz", hash = "sha256:620eb02dc8808a5fcb90f26cab6cba9d6bf497b15032ae3ca99df80366e33314"}, + {file = "Flask_PyMongo-2.3.0-py2.py3-none-any.whl", hash = "sha256:8a9577a2c6d00b49f21cb5a5a8d72561730364a2d745551a85349ab02f86fc73"}, +] + +[package.dependencies] +Flask = ">=0.11" +PyMongo = ">=3.3" + +[[package]] +name = "foca" +version = "0.13.0" +description = "Archetype for OpenAPI microservices based on Flask and Connexion" +optional = false +python-versions = "*" +files = [ + {file = "foca-0.13.0-py3-none-any.whl", hash = "sha256:bde43a704c156b23808c4a8e8653c62b0d876be6a69b37e0ed6cc05d7a4fbb2b"}, +] + +[package.dependencies] +addict = ">=2.2,<3.0" +celery = ">=5.2,<6.0" +connexion = ">=2.11,<3.0" +cryptography = ">=42.0,<43.0" +Flask = ">=2.2,<3.0" +flask-authz = ">=2.5,<3.0" +Flask-Cors = ">=4.0,<5.0" +Flask-PyMongo = ">=2.3,<3.0" +pydantic = ">=1.10,<2.0" +PyJWT = ">=2.4,<3.0" +pymongo = ">=4.7,<5.0" +PyYAML = ">=6.0,<7.0" +requests = ">=2.31,<3.0" +swagger-ui-bundle = ">=0.0,<1.0" +toml = ">=0.10,<1.0" +typing = ">=3.7,<4.0" +Werkzeug = ">=2.2,<3.0" + +[package.extras] +dev = ["coverage (>=6.5)", "flake8 (>=6.1)", "mongomock (>=4.1)", "mypy (>=0.991)", "mypy-extensions (>=0.4.4)", "pylint (>=3.2)", "pytest (>=7.4)", "python-semantic-release (>=7.34,<8.2)", "types-PyYAML", "types-requests", "types-setuptools", "types-urllib3"] +docs = ["Sphinx (>=7.2)", "readthedocs-sphinx-ext (>=2.2)", "sphinx-rtd-theme (>=1.3)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "inflection" +version = "0.5.1" +description = "A port of Ruby on Rails inflector to Python" +optional = false +python-versions = ">=3.5" +files = [ + {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, + {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, +] + +[[package]] +name = "itsdangerous" +version = "2.2.0" +description = "Safely pass data to untrusted environments and back." +optional = false +python-versions = ">=3.8" +files = [ + {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, + {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jsonschema" +version = "4.22.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "kombu" +version = "5.3.7" +description = "Messaging library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "kombu-5.3.7-py3-none-any.whl", hash = "sha256:5634c511926309c7f9789f1433e9ed402616b56836ef9878f01bd59267b4c7a9"}, + {file = "kombu-5.3.7.tar.gz", hash = "sha256:011c4cd9a355c14a1de8d35d257314a1d2456d52b7140388561acac3cf1a97bf"}, +] + +[package.dependencies] +amqp = ">=5.1.1,<6.0.0" +vine = "*" + +[package.extras] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (>=2.2.0)"] +consul = ["python-consul2"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +mongodb = ["pymongo (>=4.1.1)"] +msgpack = ["msgpack"] +pyro = ["pyro4"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=4.5.2,!=4.5.5,!=5.0.2)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=2.8.0)"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.45" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.45-py3-none-any.whl", hash = "sha256:a29b89160e494e3ea8622b09fa5897610b437884dcdcd054fdc1308883326c2a"}, + {file = "prompt_toolkit-3.0.45.tar.gz", hash = "sha256:07c60ee4ab7b7e90824b61afa840c8f5aad2d46b3e2e10acc33d8ecc94a49089"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "1.10.15" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:22ed12ee588b1df028a2aa5d66f07bf8f8b4c8579c2e96d5a9c1f96b77f3bb55"}, + {file = "pydantic-1.10.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75279d3cac98186b6ebc2597b06bcbc7244744f6b0b44a23e4ef01e5683cc0d2"}, + {file = "pydantic-1.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50f1666a9940d3d68683c9d96e39640f709d7a72ff8702987dab1761036206bb"}, + {file = "pydantic-1.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82790d4753ee5d00739d6cb5cf56bceb186d9d6ce134aca3ba7befb1eedbc2c8"}, + {file = "pydantic-1.10.15-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d207d5b87f6cbefbdb1198154292faee8017d7495a54ae58db06762004500d00"}, + {file = "pydantic-1.10.15-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e49db944fad339b2ccb80128ffd3f8af076f9f287197a480bf1e4ca053a866f0"}, + {file = "pydantic-1.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:d3b5c4cbd0c9cb61bbbb19ce335e1f8ab87a811f6d589ed52b0254cf585d709c"}, + {file = "pydantic-1.10.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c3d5731a120752248844676bf92f25a12f6e45425e63ce22e0849297a093b5b0"}, + {file = "pydantic-1.10.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c365ad9c394f9eeffcb30a82f4246c0006417f03a7c0f8315d6211f25f7cb654"}, + {file = "pydantic-1.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3287e1614393119c67bd4404f46e33ae3be3ed4cd10360b48d0a4459f420c6a3"}, + {file = "pydantic-1.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be51dd2c8596b25fe43c0a4a59c2bee4f18d88efb8031188f9e7ddc6b469cf44"}, + {file = "pydantic-1.10.15-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6a51a1dd4aa7b3f1317f65493a182d3cff708385327c1c82c81e4a9d6d65b2e4"}, + {file = "pydantic-1.10.15-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4e316e54b5775d1eb59187f9290aeb38acf620e10f7fd2f776d97bb788199e53"}, + {file = "pydantic-1.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:0d142fa1b8f2f0ae11ddd5e3e317dcac060b951d605fda26ca9b234b92214986"}, + {file = "pydantic-1.10.15-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7ea210336b891f5ea334f8fc9f8f862b87acd5d4a0cbc9e3e208e7aa1775dabf"}, + {file = "pydantic-1.10.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3453685ccd7140715e05f2193d64030101eaad26076fad4e246c1cc97e1bb30d"}, + {file = "pydantic-1.10.15-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bea1f03b8d4e8e86702c918ccfd5d947ac268f0f0cc6ed71782e4b09353b26f"}, + {file = "pydantic-1.10.15-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:005655cabc29081de8243126e036f2065bd7ea5b9dff95fde6d2c642d39755de"}, + {file = "pydantic-1.10.15-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:af9850d98fc21e5bc24ea9e35dd80a29faf6462c608728a110c0a30b595e58b7"}, + {file = "pydantic-1.10.15-cp37-cp37m-win_amd64.whl", hash = "sha256:d31ee5b14a82c9afe2bd26aaa405293d4237d0591527d9129ce36e58f19f95c1"}, + {file = "pydantic-1.10.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5e09c19df304b8123938dc3c53d3d3be6ec74b9d7d0d80f4f4b5432ae16c2022"}, + {file = "pydantic-1.10.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7ac9237cd62947db00a0d16acf2f3e00d1ae9d3bd602b9c415f93e7a9fc10528"}, + {file = "pydantic-1.10.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:584f2d4c98ffec420e02305cf675857bae03c9d617fcfdc34946b1160213a948"}, + {file = "pydantic-1.10.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbc6989fad0c030bd70a0b6f626f98a862224bc2b1e36bfc531ea2facc0a340c"}, + {file = "pydantic-1.10.15-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d573082c6ef99336f2cb5b667b781d2f776d4af311574fb53d908517ba523c22"}, + {file = "pydantic-1.10.15-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6bd7030c9abc80134087d8b6e7aa957e43d35714daa116aced57269a445b8f7b"}, + {file = "pydantic-1.10.15-cp38-cp38-win_amd64.whl", hash = "sha256:3350f527bb04138f8aff932dc828f154847fbdc7a1a44c240fbfff1b57f49a12"}, + {file = "pydantic-1.10.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:51d405b42f1b86703555797270e4970a9f9bd7953f3990142e69d1037f9d9e51"}, + {file = "pydantic-1.10.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a980a77c52723b0dc56640ced396b73a024d4b74f02bcb2d21dbbac1debbe9d0"}, + {file = "pydantic-1.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67f1a1fb467d3f49e1708a3f632b11c69fccb4e748a325d5a491ddc7b5d22383"}, + {file = "pydantic-1.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:676ed48f2c5bbad835f1a8ed8a6d44c1cd5a21121116d2ac40bd1cd3619746ed"}, + {file = "pydantic-1.10.15-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:92229f73400b80c13afcd050687f4d7e88de9234d74b27e6728aa689abcf58cc"}, + {file = "pydantic-1.10.15-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2746189100c646682eff0bce95efa7d2e203420d8e1c613dc0c6b4c1d9c1fde4"}, + {file = "pydantic-1.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:394f08750bd8eaad714718812e7fab615f873b3cdd0b9d84e76e51ef3b50b6b7"}, + {file = "pydantic-1.10.15-py3-none-any.whl", hash = "sha256:28e552a060ba2740d0d2aabe35162652c1459a0b9069fe0db7f4ee0e18e74d58"}, + {file = "pydantic-1.10.15.tar.gz", hash = "sha256:ca832e124eda231a60a041da4f013e3ff24949d94a01154b137fc2f2a43c3ffb"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pyjwt" +version = "2.8.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, + {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pymongo" +version = "4.7.2" +description = "Python driver for MongoDB " +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymongo-4.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:268d8578c0500012140c5460755ea405cbfe541ef47c81efa9d6744f0f99aeca"}, + {file = "pymongo-4.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:827611beb6c483260d520cfa6a49662d980dfa5368a04296f65fa39e78fccea7"}, + {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a754e366c404d19ff3f077ddeed64be31e0bb515e04f502bf11987f1baa55a16"}, + {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44efab10d9a3db920530f7bcb26af8f408b7273d2f0214081d3891979726328"}, + {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35b3f0c7d49724859d4df5f0445818d525824a6cd55074c42573d9b50764df67"}, + {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e37faf298a37ffb3e0809e77fbbb0a32b6a2d18a83c59cfc2a7b794ea1136b0"}, + {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1bcd58669e56c08f1e72c5758868b5df169fe267501c949ee83c418e9df9155"}, + {file = "pymongo-4.7.2-cp310-cp310-win32.whl", hash = "sha256:c72d16fede22efe7cdd1f422e8da15760e9498024040429362886f946c10fe95"}, + {file = "pymongo-4.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:12d1fef77d25640cb78893d07ff7d2fac4c4461d8eec45bd3b9ad491a1115d6e"}, + {file = "pymongo-4.7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc5af24fcf5fc6f7f40d65446400d45dd12bea933d0299dc9e90c5b22197f1e9"}, + {file = "pymongo-4.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:730778b6f0964b164c187289f906bbc84cb0524df285b7a85aa355bbec43eb21"}, + {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47a1a4832ef2f4346dcd1a10a36ade7367ad6905929ddb476459abb4fd1b98cb"}, + {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6eab12c6385526d386543d6823b07187fefba028f0da216506e00f0e1855119"}, + {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37e9ea81fa59ee9274457ed7d59b6c27f6f2a5fe8e26f184ecf58ea52a019cb8"}, + {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e9d9d2c0aae73aa4369bd373ac2ac59f02c46d4e56c4b6d6e250cfe85f76802"}, + {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6e00a79dff22c9a72212ad82021b54bdb3b85f38a85f4fc466bde581d7d17a"}, + {file = "pymongo-4.7.2-cp311-cp311-win32.whl", hash = "sha256:02efd1bb3397e24ef2af45923888b41a378ce00cb3a4259c5f4fc3c70497a22f"}, + {file = "pymongo-4.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:87bb453ac3eb44db95cb6d5a616fbc906c1c00661eec7f55696253a6245beb8a"}, + {file = "pymongo-4.7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:12c466e02133b7f8f4ff1045c6b5916215c5f7923bc83fd6e28e290cba18f9f6"}, + {file = "pymongo-4.7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f91073049c43d14e66696970dd708d319b86ee57ef9af359294eee072abaac79"}, + {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87032f818bf5052ab742812c715eff896621385c43f8f97cdd37d15b5d394e95"}, + {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a87eef394039765679f75c6a47455a4030870341cb76eafc349c5944408c882"}, + {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d275596f840018858757561840767b39272ac96436fcb54f5cac6d245393fd97"}, + {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82102e353be13f1a6769660dd88115b1da382447672ba1c2662a0fbe3df1d861"}, + {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194065c9d445017b3c82fb85f89aa2055464a080bde604010dc8eb932a6b3c95"}, + {file = "pymongo-4.7.2-cp312-cp312-win32.whl", hash = "sha256:db4380d1e69fdad1044a4b8f3bb105200542c49a0dde93452d938ff9db1d6d29"}, + {file = "pymongo-4.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:fadc6e8db7707c861ebe25b13ad6aca19ea4d2c56bf04a26691f46c23dadf6e4"}, + {file = "pymongo-4.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2cb77d09bd012cb4b30636e7e38d00b5f9be5eb521c364bde66490c45ee6c4b4"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56bf8b706946952acdea0fe478f8e44f1ed101c4b87f046859e6c3abe6c0a9f4"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcf337d1b252405779d9c79978d6ca15eab3cdaa2f44c100a79221bddad97c8a"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ffd1519edbe311df73c74ec338de7d294af535b2748191c866ea3a7c484cd15"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d59776f435564159196d971aa89422ead878174aff8fe18e06d9a0bc6d648c"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:347c49cf7f0ba49ea87c1a5a1984187ecc5516b7c753f31938bf7b37462824fd"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:84bc00200c3cbb6c98a2bb964c9e8284b641e4a33cf10c802390552575ee21de"}, + {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fcaf8c911cb29316a02356f89dbc0e0dfcc6a712ace217b6b543805690d2aefd"}, + {file = "pymongo-4.7.2-cp37-cp37m-win32.whl", hash = "sha256:b48a5650ee5320d59f6d570bd99a8d5c58ac6f297a4e9090535f6561469ac32e"}, + {file = "pymongo-4.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5239ef7e749f1326ea7564428bf861d5250aa39d7f26d612741b1b1273227062"}, + {file = "pymongo-4.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2dcf608d35644e8d276d61bf40a93339d8d66a0e5f3e3f75b2c155a421a1b71"}, + {file = "pymongo-4.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25eeb2c18ede63891cbd617943dd9e6b9cbccc54f276e0b2e693a0cc40f243c5"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9349f0bb17a31371d4cacb64b306e4ca90413a3ad1fffe73ac7cd495570d94b5"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffd4d7cb2e6c6e100e2b39606d38a9ffc934e18593dc9bb326196afc7d93ce3d"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a8bd37f5dabc86efceb8d8cbff5969256523d42d08088f098753dba15f3b37a"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c78f156edc59b905c80c9003e022e1a764c54fd40ac4fea05b0764f829790e2"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d892fb91e81cccb83f507cdb2ea0aa026ec3ced7f12a1d60f6a5bf0f20f9c1f"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87832d6076c2c82f42870157414fd876facbb6554d2faf271ffe7f8f30ce7bed"}, + {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ce1a374ea0e49808e0380ffc64284c0ce0f12bd21042b4bef1af3eb7bdf49054"}, + {file = "pymongo-4.7.2-cp38-cp38-win32.whl", hash = "sha256:eb0642e5f0dd7e86bb358749cc278e70b911e617f519989d346f742dc9520dfb"}, + {file = "pymongo-4.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:4bdb5ffe1cd3728c9479671a067ef44dacafc3743741d4dc700c377c4231356f"}, + {file = "pymongo-4.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:743552033c63f0afdb56b9189ab04b5c1dbffd7310cf7156ab98eebcecf24621"}, + {file = "pymongo-4.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5239776633f7578b81207e5646245415a5a95f6ae5ef5dff8e7c2357e6264bfc"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:727ad07952c155cd20045f2ce91143c7dc4fb01a5b4e8012905a89a7da554b0c"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9385654f01a90f73827af4db90c290a1519f7d9102ba43286e187b373e9a78e9"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d833651f1ba938bb7501f13e326b96cfbb7d98867b2d545ca6d69c7664903e0"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf17ea9cea14d59b0527403dd7106362917ced7c4ec936c4ba22bd36c912c8e0"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cecd2df037249d1c74f0af86fb5b766104a5012becac6ff63d85d1de53ba8b98"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65b4c00dedbd333698b83cd2095a639a6f0d7c4e2a617988f6c65fb46711f028"}, + {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d9b6cbc037108ff1a0a867e7670d8513c37f9bcd9ee3d2464411bfabf70ca002"}, + {file = "pymongo-4.7.2-cp39-cp39-win32.whl", hash = "sha256:cf28430ec1924af1bffed37b69a812339084697fd3f3e781074a0148e6475803"}, + {file = "pymongo-4.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:e004527ea42a6b99a8b8d5b42b42762c3bdf80f88fbdb5c3a9d47f3808495b86"}, + {file = "pymongo-4.7.2.tar.gz", hash = "sha256:9024e1661c6e40acf468177bf90ce924d1bc681d2b244adda3ed7b2f4c4d17d7"}, +] + +[package.dependencies] +dnspython = ">=1.16.0,<3.0.0" + +[package.extras] +aws = ["pymongo-auth-aws (>=1.1.0,<2.0.0)"] +encryption = ["certifi", "pymongo-auth-aws (>=1.1.0,<2.0.0)", "pymongocrypt (>=1.6.0,<2.0.0)"] +gssapi = ["pykerberos", "winkerberos (>=0.5.0)"] +ocsp = ["certifi", "cryptography (>=2.5)", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)"] +snappy = ["python-snappy"] +test = ["pytest (>=7)"] +zstd = ["zstandard"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rpds-py" +version = "0.18.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, +] + +[[package]] +name = "simpleeval" +version = "0.9.13" +description = "A simple, safe single expression evaluator library." +optional = false +python-versions = "*" +files = [ + {file = "simpleeval-0.9.13-py2.py3-none-any.whl", hash = "sha256:22a2701a5006e4188d125d34accf2405c2c37c93f6b346f2484b6422415ae54a"}, + {file = "simpleeval-0.9.13.tar.gz", hash = "sha256:4a30f9cc01825fe4c719c785e3762623e350c4840d5e6855c2a8496baaa65fac"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "swagger-ui-bundle" +version = "0.0.9" +description = "swagger_ui_bundle - swagger-ui files in a pip package" +optional = false +python-versions = "*" +files = [ + {file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"}, + {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"}, +] + +[package.dependencies] +Jinja2 = ">=2.0" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + +[[package]] +name = "typing" +version = "3.7.4.3" +description = "Type Hints for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"}, + {file = "typing-3.7.4.3.tar.gz", hash = "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.1" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, + {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "vine" +version = "5.1.0" +description = "Python promises." +optional = false +python-versions = ">=3.6" +files = [ + {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, + {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "werkzeug" +version = "2.2.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Werkzeug-2.2.3-py3-none-any.whl", hash = "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612"}, + {file = "Werkzeug-2.2.3.tar.gz", hash = "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "d0f7ae1d64ba6dde1b8a4fc4a506fa73def84b8d39bce2c2441f572a57e58509" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..756dfa3 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "crate_db" +version = "0.1.0" +description = "This service focuses on developing a versatile backend to manage and share RO-Crates using various technologies. The end goal is to make it easy for a user to manage any RO-Crate." +license = "Apache-2.0" +maintainers = ["Elixir Cloud AAI "] +authors = ["Elixir Cloud AAI "] +repository = "https://github.com/elixir-cloud-aai/crate-db" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.10" +connexion = ">=2.11.2,<3" +foca = ">=0.12.1" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/setup.py b/setup.py deleted file mode 100644 index 92f4389..0000000 --- a/setup.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Package setup.""" - -from pathlib import Path -from setuptools import setup, find_packages - -root_dir = Path(__file__).parent.resolve() - -__version__ = exec(open(root_dir / "crate-db" / "version.py").read()) - -file_name = root_dir / "README.md" -with open(file_name, "r") as _file: - long_description = _file.read() - -install_requires = [] -req = root_dir / 'requirements.txt' -with open(req, "r") as _file: - install_requires = _file.read().splitlines() - -setup( - name="foca", - version=__version__, # noqa: F821 - description=( - "Microservice for managing ROCrates" - ), - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/elixir-cloud-aai/crate-db", - project_urls={ - "Repository": "https://github.com/elixir-cloud-aai/crate-db", - "Tracker": "https://github.com/elixir-cloud-aai/crate-db/issues", - }, - packages=find_packages(), - setup_requires=[ - "setuptools_git==1.2", - "twine==3.8.0" - ], - install_requires=install_requires, -) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..d7090dd --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +""" Contains the tests for the crate_db service """ From 0e56a0eb276cb65a24035bce57a92ace55719cfa Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 15:01:23 +0530 Subject: [PATCH 3/9] change python version to 3.10 --- .github/workflows/checks.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 814d185..1463cfe 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -6,18 +6,14 @@ jobs: lint-and-test: runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.10, 3.11] - steps: - name: Checkout code uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python 3.10 uses: actions/setup-python@v4 with: - python-version: ${{ matrix.python-version }} + python-version: "3.10" - name: Install dependencies run: | From c2128bbb413fe2cae1c5ba571b2b59816dfe7fd5 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 15:04:20 +0530 Subject: [PATCH 4/9] add dev dependencies in pyproject.toml --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 756dfa3..73b7c6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,9 @@ python = "^3.10" connexion = ">=2.11.2,<3" foca = ">=0.12.1" +[tool.poetry.dev-dependencies] +pytest = "^6.2.4" +flake8 = "^3.9.2" [build-system] requires = ["poetry-core"] From 4deaa4d27615059caf7e03d15f890551d6c3d2a5 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 15:09:39 +0530 Subject: [PATCH 5/9] update poetry.lock file --- .github/workflows/checks.yaml | 1 + poetry.lock | 122 +++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 1463cfe..9d6050d 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -28,4 +28,5 @@ jobs: - name: Run tests run: | + pip install pytest poetry run pytest diff --git a/poetry.lock b/poetry.lock index 497717e..42ead79 100644 --- a/poetry.lock +++ b/poetry.lock @@ -25,6 +25,16 @@ files = [ [package.dependencies] vine = ">=5.0.0,<6.0.0" +[[package]] +name = "atomicwrites" +version = "1.4.1" +description = "Atomic file writes." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] + [[package]] name = "attrs" version = "23.2.0" @@ -491,6 +501,22 @@ idna = ["idna (>=3.6)"] trio = ["trio (>=0.23)"] wmi = ["wmi (>=1.5.1)"] +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + [[package]] name = "flask" version = "2.2.5" @@ -612,6 +638,17 @@ files = [ {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -776,6 +813,17 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = "*" +files = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] + [[package]] name = "packaging" version = "24.0" @@ -787,6 +835,21 @@ files = [ {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + [[package]] name = "prompt-toolkit" version = "3.0.45" @@ -801,6 +864,28 @@ files = [ [package.dependencies] wcwidth = "*" +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] + [[package]] name = "pycparser" version = "2.22" @@ -864,6 +949,17 @@ typing-extensions = ">=4.2.0" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] + [[package]] name = "pyjwt" version = "2.8.0" @@ -962,6 +1058,30 @@ snappy = ["python-snappy"] test = ["pytest (>=7)"] zstd = ["zstandard"] +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1319,4 +1439,4 @@ watchdog = ["watchdog"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "d0f7ae1d64ba6dde1b8a4fc4a506fa73def84b8d39bce2c2441f572a57e58509" +content-hash = "324c62e5bad5e63b83c756471df826d731ad3de1bf9a23b233be382b9f50be83" From 92b03b0e88c5ea337d72957c3c23759774ecf1c2 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 15:18:05 +0530 Subject: [PATCH 6/9] add example test --- .github/workflows/checks.yaml | 1 - tests/test_example.py | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 tests/test_example.py diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 9d6050d..1463cfe 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -28,5 +28,4 @@ jobs: - name: Run tests run: | - pip install pytest poetry run pytest diff --git a/tests/test_example.py b/tests/test_example.py new file mode 100644 index 0000000..c054e69 --- /dev/null +++ b/tests/test_example.py @@ -0,0 +1,4 @@ +# tests/test_example.py + +def test_example(): + assert True From 4ea8b3a03fbcf1ea97ca139b5c3dc10afd218896 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 19:45:29 +0530 Subject: [PATCH 7/9] change error messages to RFC7807 format --- crate_db/api/crate_db_specs.yaml | 93 ++++++++++++++++---------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/crate_db/api/crate_db_specs.yaml b/crate_db/api/crate_db_specs.yaml index 9efa5bf..d6c282a 100644 --- a/crate_db/api/crate_db_specs.yaml +++ b/crate_db/api/crate_db_specs.yaml @@ -1,8 +1,8 @@ -openapi: "3.1.0" +openapi: 3.1.0 info: title: "OpenAPI specification for managing RO-Crates" description: "Microservice for managing RO-Crates" - version: "0.1.0" + version: 0.1.0 servers: - url: /elixircloud/roc/v1 @@ -123,7 +123,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/ROCrateResponse' + $ref: '#/components/schemas/CreateROCResponse' 400: $ref: '#/components/responses/BadRequest' 401: @@ -154,7 +154,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ROCrateResponse' + $ref: '#/components/schemas/CreateROCResponse' 400: $ref: '#/components/responses/BadRequest' 401: @@ -184,7 +184,7 @@ paths: multipart/form-data: schema: x-body-name: updateROCRequestBody - $ref: '#/components/schemas/UpdateROCRequestBody' + $ref: '#/components/schemas/CreateROCResponse' responses: 204: description: No Content @@ -326,14 +326,6 @@ components: format: uuid description: The unique identifier for the RO-Crate. example: 260e7aa0-2e07-484e-9da7-ee19fdd1800d - - ROCrateResponse: - type: object - properties: - _id: - type: string - description: The unique identifier for the RO-Crate. - example: 60b6c0f9f1d2c12a5c7d6b8e rocrate: type: string description: The link to the RO-Crate file in MinIO. @@ -376,71 +368,76 @@ components: - title - description + ProblemDetails: + type: object + properties: + type: + type: string + format: uri + description: A URI reference that identifies the problem type. When dereferenced, it might provide human-readable documentation for the problem type. + title: + type: string + description: A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for localization purposes. + status: + type: integer + format: int32 + description: The HTTP status code generated by the origin server for this occurrence of the problem. + detail: + type: string + description: A human-readable explanation specific to this occurrence of the problem. + instance: + type: string + format: uri + description: A URI reference that identifies the specific occurrence of the problem. It might provide further information if dereferenced. + code: + type: integer + format: int32 + description: Application-specific error code. + message: + type: string + description: A detailed error message. + + required: + - type + - title + - status + - detail + responses: BadRequest: description: Bad Request content: application/json: schema: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string + $ref: '#/components/schemas/ProblemDetails' Unauthorized: description: Unauthorized content: application/json: schema: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string + $ref: '#/components/schemas/ProblemDetails' Forbidden: description: Forbidden content: application/json: schema: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string + $ref: '#/components/schemas/ProblemDetails' NotFound: description: Resource Not Found content: application/json: schema: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string + $ref: '#/components/schemas/ProblemDetails' UnexpectedError: description: Unexpected Error content: application/json: schema: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string + $ref: '#/components/schemas/ProblemDetails' parameters: roc-id: From 6e4bc10c566e268629ab89d57255bd6a37515225 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 19:58:37 +0530 Subject: [PATCH 8/9] limit the response data for post and put in specs --- crate_db/api/crate_db_specs.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crate_db/api/crate_db_specs.yaml b/crate_db/api/crate_db_specs.yaml index d6c282a..ce10151 100644 --- a/crate_db/api/crate_db_specs.yaml +++ b/crate_db/api/crate_db_specs.yaml @@ -123,7 +123,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/CreateROCResponse' + $ref: '#/components/schemas/ROCrateBody' 400: $ref: '#/components/responses/BadRequest' 401: @@ -154,7 +154,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CreateROCResponse' + $ref: '#/components/schemas/ROCrateBody' 400: $ref: '#/components/responses/BadRequest' 401: @@ -319,6 +319,15 @@ components: - description CreateROCResponse: + type: object + properties: + _id: + type: string + format: uuid + description: The unique identifier for the RO-Crate. + example: 260e7aa0-2e07-484e-9da7-ee19fdd1800d + + ROCrateBody: type: object properties: _id: From ecce08c8b4c79116c01f38303ab4715b7966aeb4 Mon Sep 17 00:00:00 2001 From: Rahuljagwani Date: Sun, 2 Jun 2024 20:01:33 +0530 Subject: [PATCH 9/9] fix error in response for POST in service-info --- crate_db/api/crate_db_specs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crate_db/api/crate_db_specs.yaml b/crate_db/api/crate_db_specs.yaml index ce10151..4d946be 100644 --- a/crate_db/api/crate_db_specs.yaml +++ b/crate_db/api/crate_db_specs.yaml @@ -24,7 +24,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CreateROCResponse' + $ref: '#/components/schemas/Service' 400: $ref: '#/components/responses/BadRequest' 401: