From c915e193c364ad71c6ca39369b0f33e7c5a1599b Mon Sep 17 00:00:00 2001 From: Martin Vrachev Date: Fri, 1 Mar 2024 21:20:30 +0200 Subject: [PATCH 1/3] Change POST bootstrap payload (#554) Make POST bootstrap payload more consistent especially considering that we are on our way to adding support for custom targets. We want to have a cohesive payload that will make custom targets delegations information similar to the BINS information as those two functionally take the same role - describe artifacts. We would add custom delegation roles as optional, so it wouldn't disturb the payload contract. Signed-off-by: Martin Vrachev --- docs/swagger.json | 133 ++++++++++++------ repository_service_tuf_api/bootstrap.py | 23 ++- .../data_examples/bootstrap/das-payload.json | 28 ++-- tests/data_examples/bootstrap/payload.json | 87 ------------ .../data_examples/bootstrap/payload_bins.json | 93 ++++++++++++ tests/data_examples/config/settings.json | 1 - tests/unit/api/test_bootstrap.py | 63 ++------- tests/unit/api/test_metadata.py | 4 +- 8 files changed, 224 insertions(+), 208 deletions(-) delete mode 100644 tests/data_examples/bootstrap/payload.json create mode 100644 tests/data_examples/bootstrap/payload_bins.json diff --git a/docs/swagger.json b/docs/swagger.json index be296855..357a5ecc 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -528,6 +528,27 @@ ] } }, + "BinsRole": { + "properties": { + "expiration": { + "type": "integer", + "exclusiveMinimum": 0.0, + "title": "Expiration" + }, + "number_of_delegated_bins": { + "type": "integer", + "exclusiveMaximum": 16385.0, + "exclusiveMinimum": 1.0, + "title": "Number Of Delegated Bins" + } + }, + "type": "object", + "required": [ + "expiration", + "number_of_delegated_bins" + ], + "title": "BinsRole" + }, "BootstrapGetResponse": { "properties": { "data": { @@ -662,17 +683,23 @@ } }, "settings": { - "expiration": { - "bins": 1, - "root": 365, - "snapshot": 1, - "targets": 365, - "timestamp": 1 - }, - "services": { - "number_of_delegated_bins": 4, - "targets_base_url": "http://www.example.com/repository/", - "targets_online_key": true + "roles": { + "bins": { + "expiration": 30, + "number_of_delegated_bins": 4 + }, + "root": { + "expiration": 365 + }, + "snapshot": { + "expiration": 1 + }, + "targets": { + "expiration": 365 + }, + "timestamp": { + "expiration": 1 + } } } } @@ -827,7 +854,6 @@ "snapshot_expiration": 1, "snapshot_num_keys": 1, "snapshot_threshold": 1, - "targets_base_url": "http://www.example.com/repository/", "targets_expiration": 365, "targets_num_keys": 1, "targets_online_key": true, @@ -1293,15 +1319,38 @@ ], "title": "ResponseData" }, - "RolesData": { + "Role": { + "properties": { + "expiration": { + "type": "integer", + "exclusiveMinimum": 0.0, + "title": "Expiration" + } + }, + "type": "object", + "required": [ + "expiration" + ], + "title": "Role" + }, + "RolesData-Input": { "properties": { "root": { - "$ref": "#/components/schemas/TUFMetadata-Output" + "$ref": "#/components/schemas/Role" }, - "trusted_root": { + "targets": { + "$ref": "#/components/schemas/Role" + }, + "snapshot": { + "$ref": "#/components/schemas/Role" + }, + "timestamp": { + "$ref": "#/components/schemas/Role" + }, + "bins": { "anyOf": [ { - "$ref": "#/components/schemas/TUFMetadata-Output" + "$ref": "#/components/schemas/BinsRole" }, { "type": "null" @@ -1311,39 +1360,39 @@ }, "type": "object", "required": [ - "root" + "root", + "targets", + "snapshot", + "timestamp" ], "title": "RolesData" }, - "ServiceSettings": { + "RolesData-Output": { "properties": { - "targets_base_url": { - "type": "string", - "title": "Targets Base Url" - }, - "number_of_delegated_bins": { - "type": "integer", - "exclusiveMaximum": 16385.0, - "exclusiveMinimum": 1.0, - "title": "Number Of Delegated Bins" + "root": { + "$ref": "#/components/schemas/TUFMetadata-Output" }, - "targets_online_key": { - "type": "boolean", - "title": "Targets Online Key" + "trusted_root": { + "anyOf": [ + { + "$ref": "#/components/schemas/TUFMetadata-Output" + }, + { + "type": "null" + } + ] } }, "type": "object", "required": [ - "targets_base_url", - "number_of_delegated_bins", - "targets_online_key" + "root" ], - "title": "ServiceSettings" + "title": "RolesData" }, "SigningData": { "properties": { "metadata": { - "$ref": "#/components/schemas/RolesData" + "$ref": "#/components/schemas/RolesData-Output" } }, "type": "object", @@ -2078,21 +2127,13 @@ }, "repository_service_tuf_api__bootstrap__Settings": { "properties": { - "expiration": { - "additionalProperties": { - "type": "integer" - }, - "type": "object", - "title": "Expiration" - }, - "services": { - "$ref": "#/components/schemas/ServiceSettings" + "roles": { + "$ref": "#/components/schemas/RolesData-Input" } }, "type": "object", "required": [ - "expiration", - "services" + "roles" ], "title": "Settings" }, diff --git a/repository_service_tuf_api/bootstrap.py b/repository_service_tuf_api/bootstrap.py index 681dd0e3..c91c0147 100644 --- a/repository_service_tuf_api/bootstrap.py +++ b/repository_service_tuf_api/bootstrap.py @@ -8,7 +8,7 @@ import time from datetime import datetime from threading import Thread -from typing import Dict, Literal +from typing import Dict, Literal, Optional from fastapi import HTTPException, status from pydantic import BaseModel, ConfigDict, Field @@ -26,20 +26,29 @@ TUFMetadata, ) -with open("tests/data_examples/bootstrap/payload.json") as f: +with open("tests/data_examples/bootstrap/payload_bins.json") as f: content = f.read() payload_example = json.loads(content) -class ServiceSettings(BaseModel): - targets_base_url: str +class Role(BaseModel): + expiration: int = Field(gt=0) + + +class BinsRole(Role): number_of_delegated_bins: int = Field(gt=1, lt=16385) - targets_online_key: bool + + +class RolesData(BaseModel): + root: Role + targets: Role + snapshot: Role + timestamp: Role + bins: Optional[BinsRole] = Field(default=None) class Settings(BaseModel): - expiration: Dict[Roles.values(), int] - services: ServiceSettings + roles: RolesData class BootstrapPayload(BaseModel): diff --git a/tests/data_examples/bootstrap/das-payload.json b/tests/data_examples/bootstrap/das-payload.json index 55fbc113..7b56d4dc 100644 --- a/tests/data_examples/bootstrap/das-payload.json +++ b/tests/data_examples/bootstrap/das-payload.json @@ -1,16 +1,22 @@ { "settings": { - "expiration": { - "root": 365, - "targets": 365, - "snapshot": 1, - "timestamp": 1, - "bins": 1 - }, - "services": { - "number_of_delegated_bins": 4, - "targets_base_url": "f/", - "targets_online_key": true + "roles": { + "root": { + "expiration": 365 + }, + "targets": { + "expiration": 365 + }, + "snapshot": { + "expiration": 1 + }, + "timestamp": { + "expiration": 1 + }, + "bins": { + "expiration": 30, + "number_of_delegated_bins": 4 + } } }, "metadata": { diff --git a/tests/data_examples/bootstrap/payload.json b/tests/data_examples/bootstrap/payload.json deleted file mode 100644 index e96e8770..00000000 --- a/tests/data_examples/bootstrap/payload.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "settings": { - "expiration": { - "root": 365, - "targets": 365, - "snapshot": 1, - "timestamp": 1, - "bins": 1 - }, - "services": { - "targets_base_url": "http://www.example.com/repository/", - "number_of_delegated_bins": 4, - "targets_online_key": true - } - }, - "metadata": { - "root": { - "signatures": [ - { - "keyid": "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7", - "sig": "b3c81b6579442b8672ff460ac36cdb51064109fcfa93f0e72dabbf338f7d0c24e1a91d3696d72d81f60e94b2782ab1bf41e6b8f3e535538216f4379bf30a4302" - }, - { - "keyid": "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5", - "sig": "fdfbb1877da404504e8b9c111d87680df5291094dafa01f66bfe6031e470d7c63cc477c1e79210a89e27734758e54fb54adc529918b1211d9dd9971c8bb26c0a" - } - ], - "signed": { - "_type": "root", - "version": 1, - "spec_version": "1.0.30", - "expires": "2024-02-17T10:55:28Z", - "consistent_snapshot": true, - "keys": { - "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8": { - "keytype": "ed25519", - "scheme": "ed25519", - "keyval": { - "public": "9fe7ddccb75b977a041424a1fdc142e01be4abab918dc4c611fbfe4a3360a9a8" - } - }, - "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7": { - "keytype": "ed25519", - "scheme": "ed25519", - "keyval": { - "public": "ad1709b3cb419b99c5cd7427d6411522e5a93aec6767453e91af921a73d22a3c" - } - }, - "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5": { - "keytype": "ed25519", - "scheme": "ed25519", - "keyval": { - "public": "7098f769f6ab8502b50f3b58686b8a042d5d3bb75d8b3a48a2fcbc15a0223501" - } - } - }, - "roles": { - "snapshot": { - "keyids": [ - "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" - ], - "threshold": 1 - }, - "timestamp": { - "keyids": [ - "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" - ], - "threshold": 1 - }, - "targets": { - "keyids": [ - "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" - ], - "threshold": 1 - }, - "root": { - "keyids": [ - "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7", - "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5" - ], - "threshold": 1 - } - } - } - } - } -} \ No newline at end of file diff --git a/tests/data_examples/bootstrap/payload_bins.json b/tests/data_examples/bootstrap/payload_bins.json new file mode 100644 index 00000000..f0bbabf3 --- /dev/null +++ b/tests/data_examples/bootstrap/payload_bins.json @@ -0,0 +1,93 @@ +{ + "settings": { + "roles": { + "root": { + "expiration": 365 + }, + "targets": { + "expiration": 365 + }, + "snapshot": { + "expiration": 1 + }, + "timestamp": { + "expiration": 1 + }, + "bins": { + "expiration": 30, + "number_of_delegated_bins": 4 + } + } + }, + "metadata": { + "root": { + "signatures": [ + { + "keyid": "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7", + "sig": "b3c81b6579442b8672ff460ac36cdb51064109fcfa93f0e72dabbf338f7d0c24e1a91d3696d72d81f60e94b2782ab1bf41e6b8f3e535538216f4379bf30a4302" + }, + { + "keyid": "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5", + "sig": "fdfbb1877da404504e8b9c111d87680df5291094dafa01f66bfe6031e470d7c63cc477c1e79210a89e27734758e54fb54adc529918b1211d9dd9971c8bb26c0a" + } + ], + "signed": { + "_type": "root", + "version": 1, + "spec_version": "1.0.30", + "expires": "2024-02-17T10:55:28Z", + "consistent_snapshot": true, + "keys": { + "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8": { + "keytype": "ed25519", + "scheme": "ed25519", + "keyval": { + "public": "9fe7ddccb75b977a041424a1fdc142e01be4abab918dc4c611fbfe4a3360a9a8" + } + }, + "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7": { + "keytype": "ed25519", + "scheme": "ed25519", + "keyval": { + "public": "ad1709b3cb419b99c5cd7427d6411522e5a93aec6767453e91af921a73d22a3c" + } + }, + "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5": { + "keytype": "ed25519", + "scheme": "ed25519", + "keyval": { + "public": "7098f769f6ab8502b50f3b58686b8a042d5d3bb75d8b3a48a2fcbc15a0223501" + } + } + }, + "roles": { + "snapshot": { + "keyids": [ + "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" + ], + "threshold": 1 + }, + "timestamp": { + "keyids": [ + "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" + ], + "threshold": 1 + }, + "targets": { + "keyids": [ + "f7a6872f297634219a80141caa2ec9ae8802098b07b67963272603e36cc19fd8" + ], + "threshold": 1 + }, + "root": { + "keyids": [ + "1cebe343e35f0213f6136758e6c3a8f8e1f9eeb7e47a07d5cb336462ed31dcb7", + "800dfb5a1982b82b7893e58035e19f414f553fc08cbb1130cfbae302a7b7fee5" + ], + "threshold": 1 + } + } + } + } + } + } \ No newline at end of file diff --git a/tests/data_examples/config/settings.json b/tests/data_examples/config/settings.json index a8c9ad20..35b8207e 100644 --- a/tests/data_examples/config/settings.json +++ b/tests/data_examples/config/settings.json @@ -16,6 +16,5 @@ "bins_threshold": 1, "bins_num_keys": 1, "number_of_delegated_bins": 4, - "targets_base_url": "http://www.example.com/repository/", "targets_online_key": true } \ No newline at end of file diff --git a/tests/unit/api/test_bootstrap.py b/tests/unit/api/test_bootstrap.py index b0f28daa..ee1d93ce 100644 --- a/tests/unit/api/test_bootstrap.py +++ b/tests/unit/api/test_bootstrap.py @@ -97,7 +97,7 @@ def test_get_bootstrap_already_bootstrap_in_signing( class TestPostBootstrap: - def test_post_bootstrap(self, test_client, monkeypatch): + def test_post_bootstrap_bins_delegation(self, test_client, monkeypatch): mocked_bootstrap_state = pretend.call_recorder( lambda *a: pretend.stub( bootstrap=False, state="finished", task_id="task_id" @@ -137,7 +137,7 @@ def test_post_bootstrap(self, test_client, monkeypatch): "repository_service_tuf_api.bootstrap.datetime", fake_datetime ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) @@ -195,7 +195,7 @@ def test_post_bootstrap_unrecognized_field(self, test_client, monkeypatch): "repository_service_tuf_api.bootstrap.datetime", fake_datetime ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) payload["metadata"]["root"]["signed"]["x-v-n-url"] = "http://url.com" @@ -242,7 +242,7 @@ def test_post_bootstrap_unrecognized_field_invalid( lambda *a: None, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) payload["metadata"]["root"]["signed"]["x-url"] = "http://example.com" @@ -285,7 +285,7 @@ def test_post_bootstrap_unrecognized_field_must_start_with_x( lambda *a: None, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) payload["metadata"]["root"]["signed"]["vendor-url"] = "http://url.com" @@ -339,7 +339,7 @@ def test_post_bootstrap_custom_timeout(self, test_client, monkeypatch): "repository_service_tuf_api.bootstrap.datetime", fake_datetime ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) payload["timeout"] = 600 @@ -368,7 +368,7 @@ def test_post_bootstrap_already_bootstrap(self, test_client, monkeypatch): "repository_service_tuf_api.bootstrap.bootstrap_state", mocked_bootstrap_state, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) @@ -395,7 +395,7 @@ def test_post_bootstrap_already_bootstrap_in_pre( "repository_service_tuf_api.bootstrap.bootstrap_state", mocked_bootstrap_state, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) @@ -420,7 +420,7 @@ def test_post_bootstrap_already_bootstrap_in_signing( "repository_service_tuf_api.bootstrap.bootstrap_state", mocked_bootstrap_state, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: f_data = f.read() payload = json.loads(f_data) @@ -458,48 +458,3 @@ def test_post_bootstrap_empty_payload(self, test_client): }, ] } - - def test_post_payload_incorrect_md_format(self, test_client): - payload = {"settings": {}, "metadata": {"timestamp": {}}} - response = test_client.post(BOOTSTRAP_URL, json=payload) - assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY - assert response.json() == { - "detail": [ - { - "type": "missing", - "loc": ["body", "settings", "expiration"], - "msg": "Field required", - "input": {}, - "url": "https://errors.pydantic.dev/2.6/v/missing", - }, - { - "type": "missing", - "loc": ["body", "settings", "services"], - "msg": "Field required", - "input": {}, - "url": "https://errors.pydantic.dev/2.6/v/missing", - }, - { - "type": "literal_error", - "loc": ["body", "metadata", "timestamp", "[key]"], - "msg": "Input should be 'root'", - "input": "timestamp", - "ctx": {"expected": "'root'"}, - "url": "https://errors.pydantic.dev/2.6/v/literal_error", - }, - { - "type": "missing", - "loc": ["body", "metadata", "timestamp", "signatures"], - "msg": "Field required", - "input": {}, - "url": "https://errors.pydantic.dev/2.6/v/missing", - }, - { - "type": "missing", - "loc": ["body", "metadata", "timestamp", "signed"], - "msg": "Field required", - "input": {}, - "url": "https://errors.pydantic.dev/2.6/v/missing", - }, - ] - } diff --git a/tests/unit/api/test_metadata.py b/tests/unit/api/test_metadata.py index 2315f6ba..2f5eb97d 100644 --- a/tests/unit/api/test_metadata.py +++ b/tests/unit/api/test_metadata.py @@ -172,7 +172,7 @@ def test_get_metadata_sign(self, test_client, monkeypatch): "repository_service_tuf_api.metadata.bootstrap_state", mocked_bootstrap_state, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: md_content = f.read() metadata_data = json.loads(md_content) fake_metadata = pretend.stub( @@ -220,7 +220,7 @@ def test_get_metadata_sign_with_trusted_root( "repository_service_tuf_api.metadata.bootstrap_state", mocked_bootstrap_state, ) - with open("tests/data_examples/bootstrap/payload.json") as f: + with open("tests/data_examples/bootstrap/payload_bins.json") as f: md_content = f.read() metadata_data = json.loads(md_content) From 87b76d06aa183144b923b81338f5f65ba53c45ed Mon Sep 17 00:00:00 2001 From: Kairo Araujo Date: Tue, 5 Mar 2024 12:28:02 +0100 Subject: [PATCH 2/3] Release v0.12.0b1 (#555) Signed-off-by: Kairo Araujo --- docs/swagger.json | 2 +- repository_service_tuf_api/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/swagger.json b/docs/swagger.json index 357a5ecc..866c0393 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -3,7 +3,7 @@ "info": { "title": "Repository Service for TUF API", "description": "Repository Service for TUF Rest API", - "version": "0.11.1b1" + "version": "0.12.0b1" }, "paths": { "/api/v1/bootstrap/": { diff --git a/repository_service_tuf_api/__version__.py b/repository_service_tuf_api/__version__.py index 5d6b2596..cdcb9bf5 100644 --- a/repository_service_tuf_api/__version__.py +++ b/repository_service_tuf_api/__version__.py @@ -5,6 +5,6 @@ # # SPDX-License-Identifier: MIT -version = "0.11.1b1" +version = "0.12.0b1" copyright = "Copyright (c) 2024 Repository Service for TUF Contributors" author = "Kairo de Araujo" From 835281e8d316838494334d7e405aea2c7e17920d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:31:06 +0200 Subject: [PATCH 3/3] build: Update Python dependencies (#552) Co-authored-by: rdimitrov <16540482+rdimitrov@users.noreply.github.com> --- Pipfile.lock | 36 ++++++++++++++++++------------------ requirements-dev.txt | 14 +++++++------- requirements.txt | 10 +++++----- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 51fc5bf6..a111c8cf 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -45,7 +45,7 @@ "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_full_version <= '3.11.2'", + "markers": "python_version >= '3.7'", "version": "==4.0.3" }, "billiard": { @@ -156,11 +156,11 @@ }, "pydantic": { "hashes": [ - "sha256:37a5432e54b12fecaa1049c5195f3d860a10e01bdfd24f1840ef14bd0d3aeab3", - "sha256:a09be1c3d28f3abe37f8a78af58284b236a92ce520105ddc91a6d29ea1176ba7" + "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a", + "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f" ], "markers": "python_version >= '3.8'", - "version": "==2.6.2" + "version": "==2.6.3" }, "pydantic-core": { "hashes": [ @@ -249,11 +249,11 @@ }, "python-dateutil": { "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" + "version": "==2.9.0.post0" }, "python-multipart": { "hashes": [ @@ -266,12 +266,12 @@ }, "redis": { "hashes": [ - "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f", - "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f" + "sha256:3f82cc80d350e93042c8e6e7a5d0596e4dd68715babffba79492733e1f367037", + "sha256:4caa8e1fcb6f3c0ef28dba99535101d80934b7d4cd541bbb47f4a3826ee472d1" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==5.0.1" + "version": "==5.0.2" }, "six": { "hashes": [ @@ -302,7 +302,7 @@ "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.8'", "version": "==4.10.0" }, "tzdata": { @@ -1185,11 +1185,11 @@ }, "rich": { "hashes": [ - "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", - "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" + "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.0" + "version": "==13.7.1" }, "rpds-py": { "hashes": [ @@ -1448,19 +1448,19 @@ }, "tox": { "hashes": [ - "sha256:1143c7e2489c68026a55d3d4ae84c02c449f073b28e62f80e3e440a3b72a4afa", - "sha256:dd789a554c16c4b532924ba393c92fc8991323c4b3d466712bfecc8c9b9f24f7" + "sha256:286807f8a581e55785dc30ff956a81583016625f6dd296948aa7a43001c1bb00", + "sha256:35976739e39e60e913bef4cf8226be64eb9eed6fdb9a44c6924265ebe11cbcae" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.13.0" + "version": "==4.14.0" }, "typing-extensions": { "hashes": [ "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.8'", "version": "==4.10.0" }, "urllib3": { diff --git a/requirements-dev.txt b/requirements-dev.txt index 1083459a..c981eab9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -60,7 +60,7 @@ pytest-xdist==3.5.0; python_version >= '3.7' pyyaml==6.0.1; python_version >= '3.6' referencing==0.33.0; python_version >= '3.8' requests==2.31.0; python_version >= '3.7' -rich==13.7.0; python_full_version >= '3.7.0' +rich==13.7.1; python_full_version >= '3.7.0' rpds-py==0.18.0; python_version >= '3.8' setuptools==69.1.1; python_version >= '3.8' six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' @@ -80,14 +80,14 @@ sphinxcontrib-qthelp==1.0.7; python_version >= '3.9' sphinxcontrib-serializinghtml==1.1.10; python_version >= '3.9' stevedore==5.2.0; python_version >= '3.8' tomli==2.0.1; python_version < '3.11' -tox==4.13.0; python_version >= '3.8' -typing-extensions==4.10.0; python_version < '3.11' +tox==4.14.0; python_version >= '3.8' +typing-extensions==4.10.0; python_version >= '3.8' urllib3==2.2.1; python_version >= '3.8' virtualenv==20.25.1; python_version >= '3.7' voluptuous==0.14.2; python_version >= '3.8' amqp==5.2.0; python_version >= '3.6' annotated-types==0.6.0; python_version >= '3.8' -async-timeout==4.0.3; python_full_version <= '3.11.2' +async-timeout==4.0.3; python_version >= '3.7' billiard==4.2.0; python_version >= '3.7' celery==5.3.6; python_version >= '3.8' click-didyoumean==0.3.0; python_full_version >= '3.6.2' and python_full_version < '4.0.0' @@ -97,11 +97,11 @@ dynaconf==3.2.4; python_version >= '3.8' fastapi==0.110.0; python_version >= '3.8' kombu==5.3.5; python_version >= '3.8' prompt-toolkit==3.0.43; python_full_version >= '3.7.0' -pydantic==2.6.2; python_version >= '3.8' +pydantic==2.6.3; python_version >= '3.8' pydantic-core==2.16.3; python_version >= '3.8' -python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' python-multipart==0.0.9; python_version >= '3.8' -redis==5.0.1; python_version >= '3.7' +redis==5.0.2; python_version >= '3.7' starlette==0.36.3; python_version >= '3.8' tzdata==2024.1; python_version >= '2' uvicorn==0.27.1; python_version >= '3.8' diff --git a/requirements.txt b/requirements.txt index 669fb6c0..c829db58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ amqp==5.2.0; python_version >= '3.6' annotated-types==0.6.0; python_version >= '3.8' anyio==4.3.0; python_version >= '3.8' -async-timeout==4.0.3; python_full_version <= '3.11.2' +async-timeout==4.0.3; python_version >= '3.7' billiard==4.2.0; python_version >= '3.7' celery==5.3.6; python_version >= '3.8' click==8.1.7; python_version >= '3.7' @@ -16,15 +16,15 @@ h11==0.14.0; python_version >= '3.7' idna==3.6; python_version >= '3.5' kombu==5.3.5; python_version >= '3.8' prompt-toolkit==3.0.43; python_full_version >= '3.7.0' -pydantic==2.6.2; python_version >= '3.8' +pydantic==2.6.3; python_version >= '3.8' pydantic-core==2.16.3; python_version >= '3.8' -python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' python-multipart==0.0.9; python_version >= '3.8' -redis==5.0.1; python_version >= '3.7' +redis==5.0.2; python_version >= '3.7' six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' sniffio==1.3.1; python_version >= '3.7' starlette==0.36.3; python_version >= '3.8' -typing-extensions==4.10.0; python_version < '3.11' +typing-extensions==4.10.0; python_version >= '3.8' tzdata==2024.1; python_version >= '2' uvicorn==0.27.1; python_version >= '3.8' vine==5.1.0; python_version >= '3.6'