From 0eb07feeef8c367dc05e9cf9821e986d72c058ac Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 09:14:58 +0200 Subject: [PATCH 01/82] Refactor access to group/version/kind --- src/servala/core/models/service.py | 54 +++++++++++++++++------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 82d00da..d421f8b 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -355,11 +355,27 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): def __str__(self): return f"{self.service_offering} on {self.control_plane} with {self.service_definition}" + @cached_property + def group(self): + return self.service_definition.api_definition["group"] + + @cached_property + def version(self): + return self.service_definition.api_definition["version"] + + @cached_property + def kind(self): + return self.service_definition.api_definition["kind"] + + @cached_property + def kind_plural(self): + plural = self.kind.lower() + if not plural.endswith("s"): + plural = f"{plural}s" + return plural + @cached_property def resource_definition(self): - kind = self.service_definition.api_definition["kind"] - group = self.service_definition.api_definition["group"] - version = self.service_definition.api_definition["version"] client = self.control_plane.get_kubernetes_client() extensions_api = kubernetes.client.ApiextensionsV1Api(client) @@ -368,10 +384,10 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): for crd in crds.items: if matching_crd: break - if crd.spec.group == group: + if crd.spec.group == self.group: for served_version in crd.spec.versions: - if served_version.name == version and served_version.served: - if crd.spec.names.kind == kind: + if served_version.name == self.version and served_version.served: + if crd.spec.names.kind == self.kind: matching_crd = crd break return matching_crd @@ -382,9 +398,8 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): if result := cache.get(cache_key): return result - version = self.service_definition.api_definition["version"] for v in self.resource_definition.spec.versions: - if v.name == version: + if v.name == self.version: result = v.schema.open_apiv3_schema.to_dict() timeout_seconds = 60 * 60 * 24 cache.set(cache_key, result, timeout=timeout_seconds) @@ -395,9 +410,9 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): from servala.core.crd import generate_django_model kwargs = { - key: value - for key, value in self.service_definition.api_definition.items() - if key in ("group", "version", "kind") + "group": self.group, + "version": self.version, + "kind": self.kind, } return generate_django_model(self.resource_schema, **kwargs) @@ -517,12 +532,9 @@ class ServiceInstance(ServalaModelMixin, models.Model): ) try: - group = context.service_definition.api_definition["group"] - version = context.service_definition.api_definition["version"] - kind = context.service_definition.api_definition["kind"] create_data = { - "apiVersion": f"{group}/{version}", - "kind": kind, + "apiVersion": f"{context.group}/{context.version}", + "kind": context.kind, "metadata": { "name": name, "namespace": organization.namespace, @@ -534,15 +546,11 @@ class ServiceInstance(ServalaModelMixin, models.Model): api_instance = client.CustomObjectsApi( context.control_plane.get_kubernetes_client() ) - plural = kind.lower() - if not plural.endswith("s"): - plural = f"{plural}s" - api_instance.create_namespaced_custom_object( - group=group, - version=version, + group=context.group, + version=context.version, namespace=organization.namespace, - plural=plural, + plural=context.kind_plural, body=create_data, ) except Exception as e: From c4522e31e873ea3f548a6fa5085876bfde054251 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 09:53:47 +0200 Subject: [PATCH 02/82] Implement k8s instance retrieval --- src/servala/core/models/service.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index d421f8b..7280eaa 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -564,3 +564,23 @@ class ServiceInstance(ServalaModelMixin, models.Model): raise ValidationError(_("Kubernetes API error: {}").format(str(e))) raise ValidationError(_("Error creating instance: {}").format(str(e))) return instance + + @cached_property + def kubernetes_object(self): + """Fetch the Kubernetes custom resource object""" + try: + api_instance = client.CustomObjectsApi( + self.context.control_plane.get_kubernetes_client() + ) + + return api_instance.get_namespaced_custom_object( + group=self.context.group, + version=self.context.version, + namespace=self.organization.namespace, + plural=self.context.kind_plural, + name=self.name, + ) + except ApiException as e: + if e.status == 404: + return None + raise From 912842bd8275a7018a59e73cb1ec0fbbc78887eb Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 10:10:41 +0200 Subject: [PATCH 03/82] Parse out spec data --- src/servala/core/models/service.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 7280eaa..3ba781e 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -584,3 +584,16 @@ class ServiceInstance(ServalaModelMixin, models.Model): if e.status == 404: return None raise + + @cached_property + def spec(self): + if not self.kubernetes_object: + return {} + if not (spec := self.kubernetes_object.get("spec")): + return {} + + # Remove fields that shouldn't be displayed + spec = spec.copy() + spec.pop("resourceRef", None) + spec.pop("writeConnectionSecretToRef", None) + return spec From 6d34e3abdc730697940f98bf06ea152c2df049b5 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 12:47:31 +0200 Subject: [PATCH 04/82] Parse status conditions --- src/servala/core/models/service.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 3ba781e..835689f 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -597,3 +597,11 @@ class ServiceInstance(ServalaModelMixin, models.Model): spec.pop("resourceRef", None) spec.pop("writeConnectionSecretToRef", None) return spec + + @cached_property + def status_conditions(self): + if not self.kubernetes_object: + return [] + if not (status := self.kubernetes_object.get("status")): + return [] + return status.get("conditions") or [] From 93916cdcbcca28b0c5f8fe5a50fc65cd05b54580 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 13:34:10 +0200 Subject: [PATCH 05/82] Show conditions in detail view --- .../service_instance_detail.html | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index 7a949f1..b85642f 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -7,10 +7,10 @@ {% endblock html_title %} {% block content %}
-
-
-
-
+
+
+
+
{% translate "Details" %}
{% translate "Service" %}
@@ -49,6 +49,51 @@
+ {% if instance.status_conditions %} +
+
+
+
+
+
{% translate "Status Conditions" %}
+
+ + + + + + + + + + + + {% for condition in instance.status_conditions %} + + + + + + + + {% endfor %} + +
{% translate "Type" %}{% translate "Status" %}{% translate "Last Transition Time" %}{% translate "Reason" %}{% translate "Message" %}
{{ condition.type }} + {% if condition.status == "True" %} + True + {% elif condition.status == "False" %} + False + {% else %} + {{ condition.status }} + {% endif %} + {{ condition.lastTransitionTime }}{{ condition.reason }}{{ condition.message }}
+
+
+
+
+
+
+ {% endif %}
{% endblock content %} From 7afc4400b7bc22c39f86b94799afa9b40b58e51e Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 14:00:38 +0200 Subject: [PATCH 06/82] Improve status condition display --- .../service_instance_detail.html | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index b85642f..7ae410f 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -10,8 +10,10 @@
+
+

{% translate "Details" %}

+
-
{% translate "Details" %}
{% translate "Service" %}
@@ -52,42 +54,42 @@ {% if instance.status_conditions %}
+
+

{% translate "Status" %}

+
-
-
-
{% translate "Status Conditions" %}
-
- - +
+
+
+ + + + + + + + + + + {% for condition in instance.status_conditions %} - - - - - + + + + + - - - {% for condition in instance.status_conditions %} - - - - - - - - {% endfor %} - -
{% translate "Type" %}{% translate "Status" %}{% translate "Last Transition Time" %}{% translate "Reason" %}{% translate "Message" %}
{% translate "Type" %}{% translate "Status" %}{% translate "Last Transition Time" %}{% translate "Reason" %}{% translate "Message" %}{{ condition.type }} + {% if condition.status == "True" %} + True + {% elif condition.status == "False" %} + False + {% else %} + {{ condition.status }} + {% endif %} + {{ condition.lastTransitionTime }}{{ condition.reason }}{{ condition.message }}
{{ condition.type }} - {% if condition.status == "True" %} - True - {% elif condition.status == "False" %} - False - {% else %} - {{ condition.status }} - {% endif %} - {{ condition.lastTransitionTime }}{{ condition.reason }}{{ condition.message }}
-
+ {% endfor %} + +
From 40811cbc082d3f35746c500d0246c28234737789 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 16:40:32 +0200 Subject: [PATCH 07/82] Very rough spec display in instance detail --- .../service_instance_detail.html | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index 7ae410f..3787e3c 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -96,6 +96,41 @@
{% endif %} + {% if instance.spec %} +
+
+
+

{% translate "Specification" %}

+
+
+
+ + + + + + + + + {% for key, value in instance.spec.items %} + + + + + {% endfor %} + +
{% translate "Property" %}{% translate "Value" %}
{{ key }} + {% if value|default:""|stringformat:"s"|slice:":1" == "{" or value|default:""|stringformat:"s"|slice:":1" == "[" %} +
{{ value|pprint }}
+ {% else %} + {{ value }} + {% endif %} +
+
+
+
+
+ {% endif %}
{% endblock content %} From 60b47ed6c858c271f8903d88d474028142e6beb9 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 16:55:33 +0200 Subject: [PATCH 08/82] WIP: connection credentials --- src/servala/core/models/service.py | 77 +++++++++++++++++++ .../service_instance_detail.html | 33 ++++++++ 2 files changed, 110 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 835689f..550a489 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -605,3 +605,80 @@ class ServiceInstance(ServalaModelMixin, models.Model): if not (status := self.kubernetes_object.get("status")): return [] return status.get("conditions") or [] + + @cached_property + def connection_credentials(self): + """ + Get connection credentials via spec.resourceRef. + The resource referenced there has the information which secret + we want in spec.writeConnectionSecretToRef.name and spec.writeConnectionSecretToRef.namespace. + """ + if not self.kubernetes_object: + return {} + if not ( + resource_ref := self.kubernetes_object.get("spec", {}).get("resourceRef") + ): + return {} + + try: + group = resource_ref.get("apiVersion", "").split("/")[0] + version = resource_ref.get("apiVersion", "").split("/")[1] + kind = resource_ref.get("kind") + name = resource_ref.get("name") + namespace = resource_ref.get("namespace", self.organization.namespace) + + if not all([group, version, kind, name]): + return {} + + plural = kind.lower() + if not plural.endswith("s"): + plural = f"{plural}s" + + api_instance = client.CustomObjectsApi( + self.context.control_plane.get_kubernetes_client() + ) + + referenced_obj = api_instance.get_namespaced_custom_object( + group=group, + version=version, + namespace=namespace, + plural=plural, + name=name, + ) + + secret_ref = referenced_obj.get("spec", {}).get( + "writeConnectionSecretToRef" + ) + if not secret_ref: + return {} + + secret_name = secret_ref.get("name") + secret_namespace = secret_ref.get("namespace", namespace) + + if not secret_name: + return {} + + # Get the secret data + v1 = kubernetes.client.CoreV1Api( + self.context.control_plane.get_kubernetes_client() + ) + secret = v1.read_namespaced_secret( + name=secret_name, namespace=secret_namespace + ) + + # Secret data is base64 encoded + credentials = {} + if hasattr(secret, "data") and secret.data: + import base64 + + for key, value in secret.data.items(): + try: + credentials[key] = base64.b64decode(value).decode("utf-8") + except Exception: + credentials[key] = f"" + + return credentials + except ApiException as e: + return {"error": str(e)} + except Exception as e: + return {"error": str(e)} diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index 3787e3c..b4049a8 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -131,6 +131,39 @@
{% endif %} + {% if instance.connection_credentials %} +
+
+

{% translate "Connection Credentials" %}

+
+
+
+ + + + + + + + + {% for key, value in instance.connection_credentials.items %} + + + + + {% endfor %} + +
{% translate "Name" %}{% translate "Value" %}
{{ key }} + {% if key == "error" %} + {{ value }} + {% else %} + {{ value }} + {% endif %} +
+
+
+
+ {% endif %}
{% endblock content %} From 2a359b50ef9ad8e31294b8814ea3991ce3e17071 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 11 Apr 2025 17:41:58 +0200 Subject: [PATCH 09/82] Add debugging template filter --- src/servala/frontend/templatetags/pprint_filters.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/servala/frontend/templatetags/pprint_filters.py diff --git a/src/servala/frontend/templatetags/pprint_filters.py b/src/servala/frontend/templatetags/pprint_filters.py new file mode 100644 index 0000000..e20772e --- /dev/null +++ b/src/servala/frontend/templatetags/pprint_filters.py @@ -0,0 +1,12 @@ +import json + +from django import template + +register = template.Library() + + +@register.filter +def pprint(value): + if isinstance(value, (dict, list)): + return json.dumps(value, indent=2) + return value From c8eaa99d381bdff2e5941d975b98ca7f1c1ca762 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Mon, 14 Apr 2025 10:50:16 +0200 Subject: [PATCH 10/82] Improve card display --- .../frontend/organizations/service_instance_detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index b4049a8..f83fb84 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -8,7 +8,7 @@ {% block content %}
-
+

{% translate "Details" %}

@@ -52,7 +52,7 @@
{% if instance.status_conditions %} -
+

{% translate "Status" %}

From fa3eb7c4fce755b27fef9235853dff6e872ccdcd Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 15 Apr 2025 09:22:24 +0200 Subject: [PATCH 11/82] add missing image to docs and fix url --- .../exoscale-marketplace-empty-service.png | Bin 0 -> 61331 bytes docs/modules/ROOT/pages/exoscale-osb.adoc | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/modules/ROOT/assets/images/exoscale-marketplace-empty-service.png diff --git a/docs/modules/ROOT/assets/images/exoscale-marketplace-empty-service.png b/docs/modules/ROOT/assets/images/exoscale-marketplace-empty-service.png new file mode 100644 index 0000000000000000000000000000000000000000..8137e21f512297c54b742dec48cadf383be82515 GIT binary patch literal 61331 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�q6NIzWV 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 IWBb>?0Y4nACIA2c literal 0 HcmV?d00001 diff --git a/docs/modules/ROOT/pages/exoscale-osb.adoc b/docs/modules/ROOT/pages/exoscale-osb.adoc index d42a126..540d5df 100644 --- a/docs/modules/ROOT/pages/exoscale-osb.adoc +++ b/docs/modules/ROOT/pages/exoscale-osb.adoc @@ -408,7 +408,7 @@ POST /orgs/:uuid/usage <1> * https://kb.vshn.ch/appuio-cloud/references/architecture/control-api.html[APPUiO Control API Architecture^] * https://kb.vshn.ch/appuio-cloud/references/architecture/invitations.html[APPUiO Invitations] -* https://github.com/vshn/crossplane-service-broker[Crossplane Service Broker (Code)^] - xref:how-tos/crossplane_service_broker/overview.adoc[Crossplane Service Broker (Docs)] +* https://github.com/vshn/crossplane-service-broker[Crossplane Service Broker (Code)^] - https://kb.vshn.ch/app-catalog/csp/spks/crossplane/overview.html[Crossplane Service Broker (Docs)^] * https://github.com/vshn/swisscom-service-broker[Swisscom Service Broker^] * https://community.exoscale.com/documentation/vendor/marketplace-managed-services/[Exoscale Vendor Documentation - Managed Services^] * https://community.exoscale.com/documentation/vendor/marketplace-managed-services-billing/[Exoscale Vendor Documentation - Managed Services Billing^] From c4f7c8df69a4bc95315e13f95d7367be08a49c82 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 15 Apr 2025 10:36:08 +0200 Subject: [PATCH 12/82] document models and admin --- .../portal-service-relations.drawio.svg | 469 ++++++++++++++++++ .../images/web-portal-arch-current.drawio.svg | 226 +++++++++ docs/modules/ROOT/nav.adoc | 5 +- docs/modules/ROOT/pages/web-portal-admin.adoc | 59 +++ .../ROOT/pages/web-portal-controlplanes.adoc | 30 ++ .../ROOT/pages/web-portal-planning.adoc | 64 +++ docs/modules/ROOT/pages/web-portal.adoc | 63 +-- 7 files changed, 860 insertions(+), 56 deletions(-) create mode 100644 docs/modules/ROOT/assets/images/portal-service-relations.drawio.svg create mode 100644 docs/modules/ROOT/assets/images/web-portal-arch-current.drawio.svg create mode 100644 docs/modules/ROOT/pages/web-portal-admin.adoc create mode 100644 docs/modules/ROOT/pages/web-portal-controlplanes.adoc create mode 100644 docs/modules/ROOT/pages/web-portal-planning.adoc diff --git a/docs/modules/ROOT/assets/images/portal-service-relations.drawio.svg b/docs/modules/ROOT/assets/images/portal-service-relations.drawio.svg new file mode 100644 index 0000000..ba23521 --- /dev/null +++ b/docs/modules/ROOT/assets/images/portal-service-relations.drawio.svg @@ -0,0 +1,469 @@ + + + + + + + + + + +
+
+
+ Cloud Provider "Exoscale" +
+
+
+
+ + Cloud Provider "Exoscale" + +
+
+
+ + + + + + + +
+
+
+ Cloud Provider "Cloudscale" +
+
+
+
+ + Cloud Provider "Cloudscale" + +
+
+
+ + + + + + + +
+
+
+ Control Plane 1 +
+
+
+
+ + Control Plane 1 + +
+
+
+ + + + + + + +
+
+
+ Control Plane 2 +
+
+
+
+ + Control Plane 2 + +
+
+
+ + + + + + + +
+
+
+ Control Plane N +
+
+
+
+ + Control Plane N + +
+
+
+ + + + + + + + +
+
+
+ Implemented by +
+
+
+
+ + Implemented by + +
+
+
+ + + + + + + +
+
+
+ Service +
+ (e.g. PostgreSQL) +
+
+
+
+
+ + Service... + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ Service Definition +
+ (e.g. PostgreSQL by VSHN) +
+
+
+
+
+ + Service Definition... + +
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+ Service Offering +
+ (e.g. PostgreSQL by VSHN at Cloudscale) +
+
+
+
+
+ + Service Offering... + +
+
+
+ + + + + + + + + + + +
+
+
+ Service Definition +
+ (e.g. DBaaS PostgreSQL) +
+
+
+
+
+ + Service Definition... + +
+
+
+ + + + + + + + +
+
+
+ Implemented by +
+
+
+
+ + Implemented by + +
+
+
+ + + + + + + +
+
+
+ Control Plane 1 +
+
+
+
+ + Control Plane 1 + +
+
+
+ + + + + + + +
+
+
+ Control Plane 2 +
+
+
+
+ + Control Plane 2 + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ Service Offering +
+ (e.g. PostgreSQL by VSHN at Exoscale) +
+
+
+
+
+ + Service Offering... + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ Service Offering +
+ (e.g. DBaaS PostgreSQL at Exoscale) +
+
+
+
+
+ + Service Offering... + +
+
+
+ + + + + + + +
+
+
+ ServiceOffering +
+ ControlPlane +
+
+ Configuration +
+
+
+
+
+ + ServiceOffering... + +
+
+
+ + + + + + + +
+
+
+ ServiceOffering +
+ ControlPlane +
+
+ Configuration +
+
+
+
+
+ + ServiceOffering... + +
+
+
+ + + + + + + +
+
+
+ ServiceOffering +
+ ControlPlane +
+
+ Configuration +
+
+
+
+
+ + ServiceOffering... + +
+
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/docs/modules/ROOT/assets/images/web-portal-arch-current.drawio.svg b/docs/modules/ROOT/assets/images/web-portal-arch-current.drawio.svg new file mode 100644 index 0000000..260f505 --- /dev/null +++ b/docs/modules/ROOT/assets/images/web-portal-arch-current.drawio.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + +
+
+
+ K8s API +
+
+
+
+ + K8s API + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ Web Portal +
+
+
+
+ + Web Portal + +
+
+
+ + + + + + + + +
+
+
+ HTTPS +
+
+
+
+ + HTTPS + +
+
+
+ + + + + + + + +
+
+
+ User +
+
+
+
+ + User + +
+
+
+ + + + + + + +
+
+
+ CSP 1 Zone A +
+ Control Plane +
+
+
+
+ + CSP 1 Zone A... + +
+
+
+ + + + + + + +
+
+
+ CSP 2 Zone A +
+ Control Plane +
+
+
+
+ + CSP 2 Zone A... + +
+
+
+ + + + + + + + +
+
+
+ K8s API +
+
+
+
+ + K8s API + +
+
+
+ + + + + + + + +
+
+
+ Portal DB +
+ PostgreSQL +
+
+
+
+
+ + Portal DB... + +
+
+
+ + + + + + + + +
+
+
+ VSHN Account +
+ Keycloak +
+
+
+
+
+ + VSHN Account... + +
+
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index ca7b4f5..447852e 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -2,6 +2,10 @@ * xref:terminology.adoc[] * xref:web-portal.adoc[] +** xref:web-portal-admin.adoc[Admin] +** xref:web-portal-controlplanes.adoc[Control-Planes] + +* xref:web-portal-planning.adoc[] ** xref:user-stories.adoc[] ** xref:organizations.adoc[] ** xref:authentication.adoc[] @@ -9,7 +13,6 @@ ** xref:service-catalog.adoc[] ** xref:service-instances.adoc[] ** xref:api.adoc[] -** xref:database-diagram.adoc[] * Cloud Providers ** xref:exoscale-osb.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/web-portal-admin.adoc b/docs/modules/ROOT/pages/web-portal-admin.adoc new file mode 100644 index 0000000..309933f --- /dev/null +++ b/docs/modules/ROOT/pages/web-portal-admin.adoc @@ -0,0 +1,59 @@ += Web Portal Admin + +The administration of the web portal happens with Django Admin. + +[TIP] +==== +* Production: https://portal.servala.com/admin[portal.servala.com^] +* Staging: https://staging.portal.servala.com/admin[staging.portal.servala.com^] +==== + +== Service Catalog and Control-Plane Models + +image::portal-service-relations.drawio.svg[] + +Service:: +The software service, top-level, categorized. + +_Examples_: PostgreSQL, Redis, GitLab. + +Admin: https://staging.portal.servala.com/admin/core/service/[staging^], https://portal.servala.com/admin/core/service/[prod^] + +Service Definition:: +A correlation between a specific managed service offering with the API definition on the control-planes. It tells the Portal which Kubernetes API implements a managed service. + +_Example_: "Forgejo by VSHN" is implemented by GVK `vshn.appcat.vshn.io/v1/VSHNForgejo` on the control-planes. + +Admin: https://staging.portal.servala.com/admin/core/servicedefinition/[staging^], https://portal.servala.com/admin/core/servicedefinition/[prod^] + +Service Offering:: +The service offering is the glue which connects a service with a service provider, the control-planes with the service definitions and plan information. It essentially tells the Portal which managed service is available on which control-plane with which specific configuration. It relates to "ControlPlane CRD" which is a correlation between "Service Offering", "Control Plane" and "Service Definition". +_Example_: "Forgejo at Hetzner Cloud" which makes the Service "Forgejo" available at Hetzner Cloud and through "ControlPlane CRDs" it defines which service definition is available in which control-plane at Hetzner Cloud. It also specifies plans with features, pricing and terms. + +Admin: https://staging.portal.servala.com/admin/core/serviceoffering/[staging^], https://portal.servala.com/admin/core/serviceoffering/[prod^] + +== Models + +In addition to the models described in <>, the following core models exist: + +Cloud Providers:: +Cloud providers where service instances can be provisioned at. + +Control Planes:: +Connections to Kubernetes API servers. Each control-plane represents a zone at a cloud provider. + +Organizations:: +The main multi-tenant object. + +Organization Memberships:: +Defines organization memberships including the roles in an organization. + +Organization Origins:: +The origin of an organization. Where the organization is coming from, influences e.g. access to control-planes or service offerings. + +Billing Entities:: +Billing contacts for Organizations - this is not further implemented yet. + +Plans:: +Plans for service offerings. + +Service Categories:: +Allows to categorize services. + +Service Instances:: +Service instances provisioned on control-planes. diff --git a/docs/modules/ROOT/pages/web-portal-controlplanes.adoc b/docs/modules/ROOT/pages/web-portal-controlplanes.adoc new file mode 100644 index 0000000..7b0328b --- /dev/null +++ b/docs/modules/ROOT/pages/web-portal-controlplanes.adoc @@ -0,0 +1,30 @@ += Web Portal Control-Planes + +Each control-plane represents a zone at a cloud provider. It's a dedicated Kubernetes API endpoint running the Servala control-plane. + +To register a control-plane, a service account with appropriate permissions is required on the Kubernetes API server. + +Example: + +[source,bash] +---- +# Create service account +kubectl -n kube-system create sa servala-portal + +# Create long-lived token for service account +kubectl -n kube-system apply -f - < Date: Thu, 17 Apr 2025 10:20:22 +0200 Subject: [PATCH 13/82] Possibly fix secret retrieval (untested) --- src/servala/core/models/service.py | 61 +++++++++--------------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 550a489..2f83d8d 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -609,61 +609,34 @@ class ServiceInstance(ServalaModelMixin, models.Model): @cached_property def connection_credentials(self): """ - Get connection credentials via spec.resourceRef. - The resource referenced there has the information which secret - we want in spec.writeConnectionSecretToRef.name and spec.writeConnectionSecretToRef.namespace. + Get connection credentials directly from the resource's writeConnectionSecretToRef + after checking that secret conditions are available. """ if not self.kubernetes_object: return {} - if not ( - resource_ref := self.kubernetes_object.get("spec", {}).get("resourceRef") - ): + + # Check if secrets are available based on conditions + secrets_available = any( + [ + condition.get("type") == "Status" and condition.get("status") == "True" + for condition in self.status_conditions + ] + ) + if not secrets_available: + return {} + + if not (secret_ref := self.spec.get("writeConnectionSecretToRef")): + return {} + if not (secret_name := secret_ref.get("name")): return {} try: - group = resource_ref.get("apiVersion", "").split("/")[0] - version = resource_ref.get("apiVersion", "").split("/")[1] - kind = resource_ref.get("kind") - name = resource_ref.get("name") - namespace = resource_ref.get("namespace", self.organization.namespace) - - if not all([group, version, kind, name]): - return {} - - plural = kind.lower() - if not plural.endswith("s"): - plural = f"{plural}s" - - api_instance = client.CustomObjectsApi( - self.context.control_plane.get_kubernetes_client() - ) - - referenced_obj = api_instance.get_namespaced_custom_object( - group=group, - version=version, - namespace=namespace, - plural=plural, - name=name, - ) - - secret_ref = referenced_obj.get("spec", {}).get( - "writeConnectionSecretToRef" - ) - if not secret_ref: - return {} - - secret_name = secret_ref.get("name") - secret_namespace = secret_ref.get("namespace", namespace) - - if not secret_name: - return {} - # Get the secret data v1 = kubernetes.client.CoreV1Api( self.context.control_plane.get_kubernetes_client() ) secret = v1.read_namespaced_secret( - name=secret_name, namespace=secret_namespace + name=secret_name, namespace=secret_ref.get("namespace") ) # Secret data is base64 encoded From b2d900435974d2de91c7d4c5440e2312d627a6e5 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 10:47:08 +0200 Subject: [PATCH 14/82] Display spec data tabbed like in form --- pyproject.toml | 2 +- .../service_instance_detail.html | 73 ++++++++---- src/servala/frontend/views/service.py | 111 ++++++++++++++++++ 3 files changed, 163 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 27d42c7..3cded0f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ known_first_party = "servala" [tool.flake8] max-line-length = 160 exclude = ".venv" -ignore = "E203" +ignore = "E203,W503" [tool.djlint] extend_exclude = "src/servala/static/mazer" diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index f83fb84..b9cf4dc 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -103,29 +103,58 @@

{% translate "Specification" %}

-
- - - - - - - - - {% for key, value in instance.spec.items %} - - - - +
+
+ +
-
{% translate "Property" %}{% translate "Value" %}
{{ key }} - {% if value|default:""|stringformat:"s"|slice:":1" == "{" or value|default:""|stringformat:"s"|slice:":1" == "[" %} -
{{ value|pprint }}
- {% else %} - {{ value }} - {% endif %} -
+ + +
+ {% for fieldset in spec_fieldsets %} +
+ +
+ {% for field in fieldset.fields %} +
{{ field.label }}
+
+ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %} +
{{ field.value|pprint }}
+ {% else %} + {{ field.value }} + {% endif %} +
+ {% endfor %} +
+ + {% for sub_key, sub_fieldset in fieldset.fieldsets.items %} +
{{ sub_fieldset.title }}
+
+ {% for field in sub_fieldset.fields %} +
{{ field.label }}
+
+ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %} +
{{ field.value|pprint }}
+ {% else %} + {{ field.value }} + {% endif %} +
+ {% endfor %} +
+ {% endfor %} +
+ {% endfor %} +
+
diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 6ee6b1e..b6ecc42 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -4,6 +4,7 @@ from django.shortcuts import redirect from django.utils.functional import cached_property from django.views.generic import DetailView, ListView +from servala.core.crd import deslugify from servala.core.models import ( ControlPlaneCRD, Service, @@ -168,6 +169,116 @@ class ServiceInstanceDetailView(OrganizationViewMixin, DetailView): "context__service_definition__service", ) + def get_nested_spec(self): + """ + Organize spec data into fieldsets similar to how the form does it. + """ + spec = self.object.spec or {} + + # Process spec fields + others = [] + nested_fieldsets = {} + + # First pass: organize fields into nested structures + for key, value in spec.items(): + if isinstance(value, dict): + # This is a nested structure + if key not in nested_fieldsets: + nested_fieldsets[key] = { + "title": deslugify(key), + "fields": [], + "fieldsets": {}, + } + + # Process fields in the nested structure + for sub_key, sub_value in value.items(): + if isinstance(sub_value, dict): + # Even deeper nesting + if sub_key not in nested_fieldsets[key]["fieldsets"]: + nested_fieldsets[key]["fieldsets"][sub_key] = { + "title": deslugify(sub_key), + "fields": [], + } + + # Add fields from the deeper level + for leaf_key, leaf_value in sub_value.items(): + nested_fieldsets[key]["fieldsets"][sub_key][ + "fields" + ].append( + { + "key": leaf_key, + "label": deslugify(leaf_key), + "value": leaf_value, + } + ) + else: + # Add field to parent level + nested_fieldsets[key]["fields"].append( + { + "key": sub_key, + "label": deslugify(sub_key), + "value": sub_value, + } + ) + else: + # This is a top-level field + others.append( + { + "key": key, + "label": deslugify(key), + "value": value, + } + ) + + # Second pass: Promote fields based on count + for group_key, group in list(nested_fieldsets.items()): + # Promote single sub-fieldsets to parent + for sub_key, sub_fieldset in list(group["fieldsets"].items()): + if len(sub_fieldset["fields"]) == 1: + field = sub_fieldset["fields"][0] + field["label"] = f"{sub_fieldset['title']}: {field['label']}" + group["fields"].append(field) + del group["fieldsets"][sub_key] + + # Move single-field groups to others + total_fields = len(group["fields"]) + for sub_fieldset in group["fieldsets"].values(): + total_fields += len(sub_fieldset["fields"]) + + if ( + total_fields == 1 + and len(group["fields"]) == 1 + and not group["fieldsets"] + ): + field = group["fields"][0] + field["label"] = f"{group['title']}: {field['label']}" + others.append(field) + del nested_fieldsets[group_key] + elif total_fields == 0: + del nested_fieldsets[group_key] + + fieldsets = [] + if others: + fieldsets.append( + { + "title": "General", + "fields": others, + "fieldsets": {}, + } + ) + # Create fieldsets from the organized data + for group in nested_fieldsets.values(): + fieldsets.append(group) + + return fieldsets + + def get_context_data(self, **kwargs): + """Return service instance for the current organization.""" + context = super().get_context_data(**kwargs) + if self.object.spec: + context["spec_fieldsets"] = self.get_nested_spec() + return context + class ServiceInstanceListView(OrganizationViewMixin, ListView): template_name = "frontend/organizations/service_instances.html" From d2ed55b6067f9c9336ad4218479d8bf35b21c098 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 15:41:01 +0200 Subject: [PATCH 15/82] Fix secret retrieval --- src/servala/core/models/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 2f83d8d..0a59989 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -636,7 +636,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): self.context.control_plane.get_kubernetes_client() ) secret = v1.read_namespaced_secret( - name=secret_name, namespace=secret_ref.get("namespace") + name=secret_name, namespace=self.organization.namespace ) # Secret data is base64 encoded From 9ddca7c0a4d5cdd886d2666cf66d7a7bbac3689d Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 15:42:10 +0200 Subject: [PATCH 16/82] Fix secret retrieval condition --- src/servala/core/models/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 0a59989..20a843c 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -618,7 +618,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): # Check if secrets are available based on conditions secrets_available = any( [ - condition.get("type") == "Status" and condition.get("status") == "True" + condition.get("type") == "Ready" and condition.get("status") == "True" for condition in self.status_conditions ] ) From aa73805cf602cab339fd448d9fbe9c04999364d1 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 15:50:28 +0200 Subject: [PATCH 17/82] Use full spec data to retrieve secret ref --- src/servala/core/models/service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 20a843c..baca840 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -625,7 +625,8 @@ class ServiceInstance(ServalaModelMixin, models.Model): if not secrets_available: return {} - if not (secret_ref := self.spec.get("writeConnectionSecretToRef")): + spec = self.kubernetes_object.get("spec") + if not (secret_ref := spec.get("writeConnectionSecretToRef")): return {} if not (secret_name := secret_ref.get("name")): return {} From a5875cf2b9e8c27cf367ee9e9710a05d406db536 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 16:58:37 +0200 Subject: [PATCH 18/82] Fix ControlPlaneAdmin ordering warning --- src/servala/core/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/servala/core/admin.py b/src/servala/core/admin.py index 746d5da..7ff602b 100644 --- a/src/servala/core/admin.py +++ b/src/servala/core/admin.py @@ -126,6 +126,7 @@ class ControlPlaneAdmin(admin.ModelAdmin): search_fields = ("name", "description") autocomplete_fields = ("cloud_provider",) actions = ["test_kubernetes_connection"] + ordering = ('name',) fieldsets = ( ( From ff5761ddc7d5e506fa4ec6a62c42ef2f89ceb355 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 17 Apr 2025 17:03:51 +0200 Subject: [PATCH 19/82] Code style --- src/servala/core/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servala/core/admin.py b/src/servala/core/admin.py index 7ff602b..740b7bf 100644 --- a/src/servala/core/admin.py +++ b/src/servala/core/admin.py @@ -126,7 +126,7 @@ class ControlPlaneAdmin(admin.ModelAdmin): search_fields = ("name", "description") autocomplete_fields = ("cloud_provider",) actions = ["test_kubernetes_connection"] - ordering = ('name',) + ordering = ("name",) fieldsets = ( ( From e63171f3b5b613bd52134aa785d85bd39baec0ac Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Mon, 19 May 2025 15:32:56 +0200 Subject: [PATCH 20/82] Update Django to 5.2 --- pyproject.toml | 2 +- uv.lock | 810 ++++++++++++++++++++++++------------------------- 2 files changed, 406 insertions(+), 406 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 51ae0c0..c8d634f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.12" dependencies = [ "argon2-cffi>=23.1.0", "cryptography>=44.0.2", - "django==5.2b1", + "django==5.2", "django-allauth>=65.5.0", "django-fernet-encrypted-fields>=0.3.0", "django-scopes>=2.0.0", diff --git a/uv.lock b/uv.lock index ff9dc60..461187f 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 2 requires-python = ">=3.12" [[package]] @@ -9,9 +9,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798, upload-time = "2023-08-15T14:13:12.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124, upload-time = "2023-08-15T14:13:10.752Z" }, ] [[package]] @@ -21,36 +21,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911, upload-time = "2021-12-01T08:52:55.68Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658 }, - { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583 }, - { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168 }, - { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709 }, - { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613 }, - { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583 }, - { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475 }, - { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698 }, - { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817 }, - { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104 }, + { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658, upload-time = "2021-12-01T09:09:17.016Z" }, + { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583, upload-time = "2021-12-01T09:09:19.546Z" }, + { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168, upload-time = "2021-12-01T09:09:21.445Z" }, + { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709, upload-time = "2021-12-01T09:09:18.182Z" }, + { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613, upload-time = "2021-12-01T09:09:22.741Z" }, + { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583, upload-time = "2021-12-01T09:09:24.177Z" }, + { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475, upload-time = "2021-12-01T09:09:26.673Z" }, + { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698, upload-time = "2021-12-01T09:09:27.87Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817, upload-time = "2021-12-01T09:09:30.267Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104, upload-time = "2021-12-01T09:09:31.335Z" }, ] [[package]] name = "asgiref" version = "3.8.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186 } +sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186, upload-time = "2024-03-22T14:39:36.863Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 }, + { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" }, ] [[package]] name = "attrs" version = "25.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562 } +sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562, upload-time = "2025-01-25T11:30:12.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152 }, + { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152, upload-time = "2025-01-25T11:30:10.164Z" }, ] [[package]] @@ -64,17 +64,17 @@ dependencies = [ { name = "pathspec" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449 } +sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988 }, - { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985 }, - { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816 }, - { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860 }, - { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673 }, - { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190 }, - { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926 }, - { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613 }, - { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646 }, + { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, + { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, + { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" }, + { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, ] [[package]] @@ -87,27 +87,27 @@ dependencies = [ { name = "lexid" }, { name = "toml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/a9/becf78cc86211bd2287114c4f990a3bed450816696f14810cc59d7815bb5/bumpver-2024.1130.tar.gz", hash = "sha256:74f7ebc294b2240f346e99748cc6f238e57b050999d7428db75d76baf2bf1437", size = 115102 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/a9/becf78cc86211bd2287114c4f990a3bed450816696f14810cc59d7815bb5/bumpver-2024.1130.tar.gz", hash = "sha256:74f7ebc294b2240f346e99748cc6f238e57b050999d7428db75d76baf2bf1437", size = 115102, upload-time = "2024-11-10T20:51:53.072Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/34/57d038ae30374976ce4ec57db9dea95bf55d1b5543b35e77aa9ce3543198/bumpver-2024.1130-py2.py3-none-any.whl", hash = "sha256:8e54220aefe7db25148622f45959f7beb6b8513af0b0429b38b9072566665a49", size = 65273 }, + { url = "https://files.pythonhosted.org/packages/09/34/57d038ae30374976ce4ec57db9dea95bf55d1b5543b35e77aa9ce3543198/bumpver-2024.1130-py2.py3-none-any.whl", hash = "sha256:8e54220aefe7db25148622f45959f7beb6b8513af0b0429b38b9072566665a49", size = 65273, upload-time = "2024-11-10T20:51:50.383Z" }, ] [[package]] name = "cachetools" version = "5.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080 }, + { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, ] [[package]] name = "certifi" version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload-time = "2025-01-31T02:16:47.166Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload-time = "2025-01-31T02:16:45.015Z" }, ] [[package]] @@ -117,65 +117,65 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, - { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, - { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, - { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, - { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, - { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, - { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, - { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, - { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, - { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, - { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, - { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, - { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, - { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, - { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, - { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, - { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, - { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, - { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, - { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, - { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, - { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, - { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, - { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, - { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, - { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, - { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, ] [[package]] @@ -185,57 +185,57 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "coverage" version = "7.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/02/36/465f5492443265e1278f9a82ffe6aeed3f1db779da0d6e7d4611a5cfb6af/coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166", size = 809969 } +sdist = { url = "https://files.pythonhosted.org/packages/02/36/465f5492443265e1278f9a82ffe6aeed3f1db779da0d6e7d4611a5cfb6af/coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166", size = 809969, upload-time = "2025-03-16T18:00:21.805Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/47/f7b870caa26082ff8033be074ac61dc175a6b0c965adf7b910f92a6d7cfe/coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94", size = 210907 }, - { url = "https://files.pythonhosted.org/packages/ea/eb/40b39bdc6c1da403257f0fcb2c1b2fd81ff9f66c13abbe3862f42780e1c1/coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db", size = 211162 }, - { url = "https://files.pythonhosted.org/packages/53/08/42a2db41b4646d6261122773e222dd7105e2306526f2d7846de6fee808ec/coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe", size = 245223 }, - { url = "https://files.pythonhosted.org/packages/78/2a/0ceb328a7e67e8639d5c7800b8161d4b5f489073ac8d5ac33b11eadee218/coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8", size = 242114 }, - { url = "https://files.pythonhosted.org/packages/ba/68/42b13b849d40af1581830ff06c60f4ec84649764f4a58d5c6e20ae11cbd4/coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135", size = 244371 }, - { url = "https://files.pythonhosted.org/packages/68/66/ab7c3b9fdbeb8bdd322f5b67b1886463834dba2014a534caba60fb0075ea/coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705", size = 244134 }, - { url = "https://files.pythonhosted.org/packages/01/74/b833d299a479681957d6b238e16a0725586e1d56ec1e43658f3184550bb0/coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0", size = 242353 }, - { url = "https://files.pythonhosted.org/packages/f9/c5/0ed656d65da39bbab8e8fc367dc3d465a7501fea0f2b1caccfb4f6361c9f/coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd", size = 243543 }, - { url = "https://files.pythonhosted.org/packages/87/b5/142bcff3828e4cce5d4c9ddc9222de1664464263acca09638e4eb0dbda7c/coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d", size = 213543 }, - { url = "https://files.pythonhosted.org/packages/29/74/99d226985def03284bad6a9aff27a1079a8881ec7523b5980b00a5260527/coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92", size = 214344 }, - { url = "https://files.pythonhosted.org/packages/45/2f/df6235ec963b9eb6b6b2f3c24f70448f1ffa13b9a481c155a6caff176395/coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072", size = 210934 }, - { url = "https://files.pythonhosted.org/packages/f3/85/ff19510bf642e334845318ddb73a550d2b17082831fa9ae053ce72288be7/coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82", size = 211212 }, - { url = "https://files.pythonhosted.org/packages/2d/6a/af6582a419550d35eacc3e1bf9f4a936dda0ae559632a0bc4e3aef694ac8/coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa", size = 244727 }, - { url = "https://files.pythonhosted.org/packages/55/62/7c49526111c91f3d7d27e111c22c8d08722f5b661c3f031b625b4d7bc4d9/coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f", size = 241768 }, - { url = "https://files.pythonhosted.org/packages/62/4b/2dc27700782be9795cbbbe98394dd19ef74815d78d5027ed894972cd1b4a/coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265", size = 243790 }, - { url = "https://files.pythonhosted.org/packages/d3/11/9cc1ae56d3015edca69437f3121c2b44de309f6828980b29e4cc9b13246d/coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2", size = 243861 }, - { url = "https://files.pythonhosted.org/packages/db/e4/2398ed93edcf42ff43002d91c37be11514d825cec382606654fd44f4b8fa/coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d", size = 241942 }, - { url = "https://files.pythonhosted.org/packages/ec/fe/b6bd35b17a2b8d26bdb21d5ea4351a837ec01edf552655e833629af05b90/coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39", size = 243228 }, - { url = "https://files.pythonhosted.org/packages/6d/06/d8701bae1e5d865edeb00a6c2a71bd7659ca6af349789271c6fd16a57909/coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68", size = 213572 }, - { url = "https://files.pythonhosted.org/packages/d7/c1/7e67780bfcaed6bed20100c9e1b2645e3414577b4bdad169578325249045/coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573", size = 214372 }, - { url = "https://files.pythonhosted.org/packages/ed/25/50b0447442a415ad3da33093c589d9ef945dd6933225f1ce0ac97476397e/coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322", size = 211774 }, - { url = "https://files.pythonhosted.org/packages/13/cc/3daddc707e934d3c0aafaa4a9b217f53fcf4133d4e40cc6ae63aa51243b8/coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce", size = 211995 }, - { url = "https://files.pythonhosted.org/packages/98/99/c92f43355d3d67f6bf8c946a350f2174e18f9ea7c8a1e36c9eb84ab7d20b/coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816", size = 256226 }, - { url = "https://files.pythonhosted.org/packages/25/62/65f0f33c08e0a1632f1e487b9c2d252e8bad6a77a942836043972b0ba6d2/coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf", size = 251937 }, - { url = "https://files.pythonhosted.org/packages/b2/10/99a9565aaeb159aade178c6509c8324a9c9e825b01f02242a37c2a8869f8/coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57", size = 254276 }, - { url = "https://files.pythonhosted.org/packages/a7/12/206196edbf0b82250b11bf5c252fe25ebaa2b7c8d66edb0c194e7b3403fe/coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4", size = 255366 }, - { url = "https://files.pythonhosted.org/packages/a5/82/a2abb8d4cdd99c6a443ab6682c0eee5797490a2113a45ffaa8b6b31c5dcc/coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c", size = 253536 }, - { url = "https://files.pythonhosted.org/packages/4d/7d/3747e000e60ad5dd8157bd978f99979967d56cb35c55235980c85305db86/coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463", size = 254344 }, - { url = "https://files.pythonhosted.org/packages/45/56/7c33f8a6de1b3b079374d2ae490ccf76fb7c094a23f72d10f071989fc3ef/coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90", size = 214284 }, - { url = "https://files.pythonhosted.org/packages/95/ab/657bfa6171800a67bd1c005402f06d6b78610820ef1364ea4f85b04bbb5b/coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07", size = 215445 }, - { url = "https://files.pythonhosted.org/packages/2a/ac/60f409a448e5b0e9b8539716f683568aa5848c1be903cdbbc805a552cdf8/coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a", size = 202803 }, + { url = "https://files.pythonhosted.org/packages/b7/47/f7b870caa26082ff8033be074ac61dc175a6b0c965adf7b910f92a6d7cfe/coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94", size = 210907, upload-time = "2025-03-16T17:59:15.706Z" }, + { url = "https://files.pythonhosted.org/packages/ea/eb/40b39bdc6c1da403257f0fcb2c1b2fd81ff9f66c13abbe3862f42780e1c1/coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db", size = 211162, upload-time = "2025-03-16T17:59:16.993Z" }, + { url = "https://files.pythonhosted.org/packages/53/08/42a2db41b4646d6261122773e222dd7105e2306526f2d7846de6fee808ec/coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe", size = 245223, upload-time = "2025-03-16T17:59:19.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/2a/0ceb328a7e67e8639d5c7800b8161d4b5f489073ac8d5ac33b11eadee218/coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8", size = 242114, upload-time = "2025-03-16T17:59:20.83Z" }, + { url = "https://files.pythonhosted.org/packages/ba/68/42b13b849d40af1581830ff06c60f4ec84649764f4a58d5c6e20ae11cbd4/coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135", size = 244371, upload-time = "2025-03-16T17:59:22.222Z" }, + { url = "https://files.pythonhosted.org/packages/68/66/ab7c3b9fdbeb8bdd322f5b67b1886463834dba2014a534caba60fb0075ea/coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705", size = 244134, upload-time = "2025-03-16T17:59:23.536Z" }, + { url = "https://files.pythonhosted.org/packages/01/74/b833d299a479681957d6b238e16a0725586e1d56ec1e43658f3184550bb0/coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0", size = 242353, upload-time = "2025-03-16T17:59:25.127Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c5/0ed656d65da39bbab8e8fc367dc3d465a7501fea0f2b1caccfb4f6361c9f/coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd", size = 243543, upload-time = "2025-03-16T17:59:26.462Z" }, + { url = "https://files.pythonhosted.org/packages/87/b5/142bcff3828e4cce5d4c9ddc9222de1664464263acca09638e4eb0dbda7c/coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d", size = 213543, upload-time = "2025-03-16T17:59:27.745Z" }, + { url = "https://files.pythonhosted.org/packages/29/74/99d226985def03284bad6a9aff27a1079a8881ec7523b5980b00a5260527/coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92", size = 214344, upload-time = "2025-03-16T17:59:30.377Z" }, + { url = "https://files.pythonhosted.org/packages/45/2f/df6235ec963b9eb6b6b2f3c24f70448f1ffa13b9a481c155a6caff176395/coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072", size = 210934, upload-time = "2025-03-16T17:59:31.651Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/ff19510bf642e334845318ddb73a550d2b17082831fa9ae053ce72288be7/coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82", size = 211212, upload-time = "2025-03-16T17:59:32.966Z" }, + { url = "https://files.pythonhosted.org/packages/2d/6a/af6582a419550d35eacc3e1bf9f4a936dda0ae559632a0bc4e3aef694ac8/coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa", size = 244727, upload-time = "2025-03-16T17:59:34.276Z" }, + { url = "https://files.pythonhosted.org/packages/55/62/7c49526111c91f3d7d27e111c22c8d08722f5b661c3f031b625b4d7bc4d9/coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f", size = 241768, upload-time = "2025-03-16T17:59:36.026Z" }, + { url = "https://files.pythonhosted.org/packages/62/4b/2dc27700782be9795cbbbe98394dd19ef74815d78d5027ed894972cd1b4a/coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265", size = 243790, upload-time = "2025-03-16T17:59:37.967Z" }, + { url = "https://files.pythonhosted.org/packages/d3/11/9cc1ae56d3015edca69437f3121c2b44de309f6828980b29e4cc9b13246d/coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2", size = 243861, upload-time = "2025-03-16T17:59:39.311Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/2398ed93edcf42ff43002d91c37be11514d825cec382606654fd44f4b8fa/coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d", size = 241942, upload-time = "2025-03-16T17:59:41.063Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fe/b6bd35b17a2b8d26bdb21d5ea4351a837ec01edf552655e833629af05b90/coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39", size = 243228, upload-time = "2025-03-16T17:59:42.39Z" }, + { url = "https://files.pythonhosted.org/packages/6d/06/d8701bae1e5d865edeb00a6c2a71bd7659ca6af349789271c6fd16a57909/coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68", size = 213572, upload-time = "2025-03-16T17:59:44.114Z" }, + { url = "https://files.pythonhosted.org/packages/d7/c1/7e67780bfcaed6bed20100c9e1b2645e3414577b4bdad169578325249045/coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573", size = 214372, upload-time = "2025-03-16T17:59:45.61Z" }, + { url = "https://files.pythonhosted.org/packages/ed/25/50b0447442a415ad3da33093c589d9ef945dd6933225f1ce0ac97476397e/coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322", size = 211774, upload-time = "2025-03-16T17:59:47.068Z" }, + { url = "https://files.pythonhosted.org/packages/13/cc/3daddc707e934d3c0aafaa4a9b217f53fcf4133d4e40cc6ae63aa51243b8/coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce", size = 211995, upload-time = "2025-03-16T17:59:48.414Z" }, + { url = "https://files.pythonhosted.org/packages/98/99/c92f43355d3d67f6bf8c946a350f2174e18f9ea7c8a1e36c9eb84ab7d20b/coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816", size = 256226, upload-time = "2025-03-16T17:59:49.824Z" }, + { url = "https://files.pythonhosted.org/packages/25/62/65f0f33c08e0a1632f1e487b9c2d252e8bad6a77a942836043972b0ba6d2/coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf", size = 251937, upload-time = "2025-03-16T17:59:51.498Z" }, + { url = "https://files.pythonhosted.org/packages/b2/10/99a9565aaeb159aade178c6509c8324a9c9e825b01f02242a37c2a8869f8/coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57", size = 254276, upload-time = "2025-03-16T17:59:53.258Z" }, + { url = "https://files.pythonhosted.org/packages/a7/12/206196edbf0b82250b11bf5c252fe25ebaa2b7c8d66edb0c194e7b3403fe/coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4", size = 255366, upload-time = "2025-03-16T17:59:54.639Z" }, + { url = "https://files.pythonhosted.org/packages/a5/82/a2abb8d4cdd99c6a443ab6682c0eee5797490a2113a45ffaa8b6b31c5dcc/coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c", size = 253536, upload-time = "2025-03-16T17:59:56.184Z" }, + { url = "https://files.pythonhosted.org/packages/4d/7d/3747e000e60ad5dd8157bd978f99979967d56cb35c55235980c85305db86/coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463", size = 254344, upload-time = "2025-03-16T17:59:57.738Z" }, + { url = "https://files.pythonhosted.org/packages/45/56/7c33f8a6de1b3b079374d2ae490ccf76fb7c094a23f72d10f071989fc3ef/coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90", size = 214284, upload-time = "2025-03-16T17:59:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/95/ab/657bfa6171800a67bd1c005402f06d6b78610820ef1364ea4f85b04bbb5b/coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07", size = 215445, upload-time = "2025-03-16T18:00:00.501Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ac/60f409a448e5b0e9b8539716f683568aa5848c1be903cdbbc805a552cdf8/coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a", size = 202803, upload-time = "2025-03-16T18:00:20.282Z" }, ] [[package]] @@ -245,32 +245,32 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807, upload-time = "2025-03-02T00:01:37.692Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361 }, - { url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350 }, - { url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572 }, - { url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124 }, - { url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122 }, - { url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831 }, - { url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583 }, - { url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753 }, - { url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550 }, - { url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367 }, - { url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843 }, - { url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057 }, - { url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789 }, - { url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919 }, - { url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812 }, - { url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571 }, - { url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832 }, - { url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719 }, - { url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852 }, - { url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906 }, - { url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572 }, - { url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631 }, - { url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792 }, - { url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957 }, + { url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361, upload-time = "2025-03-02T00:00:06.528Z" }, + { url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350, upload-time = "2025-03-02T00:00:09.537Z" }, + { url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572, upload-time = "2025-03-02T00:00:12.03Z" }, + { url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124, upload-time = "2025-03-02T00:00:14.518Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122, upload-time = "2025-03-02T00:00:17.212Z" }, + { url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831, upload-time = "2025-03-02T00:00:19.696Z" }, + { url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583, upload-time = "2025-03-02T00:00:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753, upload-time = "2025-03-02T00:00:25.038Z" }, + { url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550, upload-time = "2025-03-02T00:00:26.929Z" }, + { url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367, upload-time = "2025-03-02T00:00:28.735Z" }, + { url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843, upload-time = "2025-03-02T00:00:30.592Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057, upload-time = "2025-03-02T00:00:33.393Z" }, + { url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789, upload-time = "2025-03-02T00:00:36.009Z" }, + { url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919, upload-time = "2025-03-02T00:00:38.581Z" }, + { url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812, upload-time = "2025-03-02T00:00:42.934Z" }, + { url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571, upload-time = "2025-03-02T00:00:46.026Z" }, + { url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832, upload-time = "2025-03-02T00:00:48.647Z" }, + { url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719, upload-time = "2025-03-02T00:00:51.397Z" }, + { url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852, upload-time = "2025-03-02T00:00:53.317Z" }, + { url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906, upload-time = "2025-03-02T00:00:56.49Z" }, + { url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572, upload-time = "2025-03-02T00:00:59.995Z" }, + { url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631, upload-time = "2025-03-02T00:01:01.623Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792, upload-time = "2025-03-02T00:01:04.133Z" }, + { url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957, upload-time = "2025-03-02T00:01:06.987Z" }, ] [[package]] @@ -282,23 +282,23 @@ dependencies = [ { name = "jsbeautifier" }, { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f7/01/fdf41c1e5f93d359681976ba10410a04b299d248e28ecce1d4e88588dde4/cssbeautifier-1.15.4.tar.gz", hash = "sha256:9bb08dc3f64c101a01677f128acf01905914cf406baf87434dcde05b74c0acf5", size = 25376 } +sdist = { url = "https://files.pythonhosted.org/packages/f7/01/fdf41c1e5f93d359681976ba10410a04b299d248e28ecce1d4e88588dde4/cssbeautifier-1.15.4.tar.gz", hash = "sha256:9bb08dc3f64c101a01677f128acf01905914cf406baf87434dcde05b74c0acf5", size = 25376, upload-time = "2025-02-27T17:53:51.341Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/51/ef6c5628e46092f0a54c7cee69acc827adc6b6aab57b55d344fefbdf28f1/cssbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:78c84d5e5378df7d08622bbd0477a1abdbd209680e95480bf22f12d5701efc98", size = 123667 }, + { url = "https://files.pythonhosted.org/packages/63/51/ef6c5628e46092f0a54c7cee69acc827adc6b6aab57b55d344fefbdf28f1/cssbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:78c84d5e5378df7d08622bbd0477a1abdbd209680e95480bf22f12d5701efc98", size = 123667, upload-time = "2025-02-27T17:53:43.594Z" }, ] [[package]] name = "django" -version = "5.2b1" +version = "5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, { name = "sqlparse" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/22/ae506393d2fb47d8ea8256cb600072b02d971134e26bd1d4b8fbfb8fca9e/Django-5.2b1.tar.gz", hash = "sha256:55c764c5990759ee97ba60ac1ce17092e91e445be1d0a83e88b754835c4bb564", size = 10816962 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/1b/c6da718c65228eb3a7ff7ba6a32d8e80fa840ca9057490504e099e4dd1ef/Django-5.2.tar.gz", hash = "sha256:1a47f7a7a3d43ce64570d350e008d2949abe8c7e21737b351b6a1611277c6d89", size = 10824891, upload-time = "2025-04-02T13:08:06.874Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/6a/4e53c567ef24e81e17a30c788209396e08b8aaf8011d9cf01b8aa4910fa1/Django-5.2b1-py3-none-any.whl", hash = "sha256:ec33b0b3846d145a95d84a1ffea29f64ce4fc73ba755d9a6ab35128f354b750a", size = 8295550 }, + { url = "https://files.pythonhosted.org/packages/63/e0/6a5b5ea350c5bd63fe94b05e4c146c18facb51229d9dee42aa39f9fc2214/Django-5.2-py3-none-any.whl", hash = "sha256:91ceed4e3a6db5aedced65e3c8f963118ea9ba753fc620831c77074e620e7d83", size = 8301361, upload-time = "2025-04-02T13:08:01.465Z" }, ] [[package]] @@ -309,7 +309,7 @@ dependencies = [ { name = "asgiref" }, { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/f8/b58f84c29bcbca3798939279a98e2423e6e53a38c29e3fed7700ff3d6984/django_allauth-65.5.0.tar.gz", hash = "sha256:1a564fd2f5413054559078c2b7146796b517c1e7a38c6312e9de7c9bb708325d", size = 1624216 } +sdist = { url = "https://files.pythonhosted.org/packages/66/f8/b58f84c29bcbca3798939279a98e2423e6e53a38c29e3fed7700ff3d6984/django_allauth-65.5.0.tar.gz", hash = "sha256:1a564fd2f5413054559078c2b7146796b517c1e7a38c6312e9de7c9bb708325d", size = 1624216, upload-time = "2025-03-14T12:37:49.299Z" } [[package]] name = "django-fernet-encrypted-fields" @@ -319,9 +319,9 @@ dependencies = [ { name = "cryptography" }, { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/b8/b6725f1207693ba9e76223abf87eb9e8de5114cccad8ddd1bce29a195273/django-fernet-encrypted-fields-0.3.0.tar.gz", hash = "sha256:38031bdaf1724a6e885ee137cc66a2bd7dc3726c438e189ea7e44799ec0ba9b3", size = 4021 } +sdist = { url = "https://files.pythonhosted.org/packages/70/b8/b6725f1207693ba9e76223abf87eb9e8de5114cccad8ddd1bce29a195273/django-fernet-encrypted-fields-0.3.0.tar.gz", hash = "sha256:38031bdaf1724a6e885ee137cc66a2bd7dc3726c438e189ea7e44799ec0ba9b3", size = 4021, upload-time = "2025-02-21T02:58:42.049Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/8a/2c5d88cd540d83ceaa1cb3191ed35dfed0caacc6fe2ff5fe74c9ecc7776f/django_fernet_encrypted_fields-0.3.0-py3-none-any.whl", hash = "sha256:a17cca5bf3638ee44674e64f30792d5960b1d4d4b291ec478c27515fc4860612", size = 5400 }, + { url = "https://files.pythonhosted.org/packages/75/8a/2c5d88cd540d83ceaa1cb3191ed35dfed0caacc6fe2ff5fe74c9ecc7776f/django_fernet_encrypted_fields-0.3.0-py3-none-any.whl", hash = "sha256:a17cca5bf3638ee44674e64f30792d5960b1d4d4b291ec478c27515fc4860612", size = 5400, upload-time = "2025-02-21T02:58:40.832Z" }, ] [[package]] @@ -331,9 +331,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a5/d7/a26ccb685b64e8e0b21f107b01ea16636a899a380175fe29d7c01d3d8395/django-scopes-2.0.0.tar.gz", hash = "sha256:d190d9a2462bce812bc6fdd254e47ba031f6fba3279c8ac7397c671df0a4e54f", size = 15118 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/d7/a26ccb685b64e8e0b21f107b01ea16636a899a380175fe29d7c01d3d8395/django-scopes-2.0.0.tar.gz", hash = "sha256:d190d9a2462bce812bc6fdd254e47ba031f6fba3279c8ac7397c671df0a4e54f", size = 15118, upload-time = "2023-04-22T17:07:52.352Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/3d/94d82839c111a36145b5ec1fb407a85f9a460af5974a07f4c6d3cc414358/django_scopes-2.0.0-py3-none-any.whl", hash = "sha256:9cf521b4d543ffa2ff6369fb5a1dda03567e862ba89626c01405f3d93ca04724", size = 16660 }, + { url = "https://files.pythonhosted.org/packages/15/3d/94d82839c111a36145b5ec1fb407a85f9a460af5974a07f4c6d3cc414358/django_scopes-2.0.0-py3-none-any.whl", hash = "sha256:9cf521b4d543ffa2ff6369fb5a1dda03567e862ba89626c01405f3d93ca04724", size = 16660, upload-time = "2023-04-22T17:08:45.058Z" }, ] [[package]] @@ -343,9 +343,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ff/2a7ddae12ca8e5fea1a41af05924c04f1bb4aec7157b04a88b829dd93d4a/django_template_partials-24.4.tar.gz", hash = "sha256:25b67301470fc274ecc419e5e5fd4686a5020b1c038fd241a70eb087809034b6", size = 14538 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ff/2a7ddae12ca8e5fea1a41af05924c04f1bb4aec7157b04a88b829dd93d4a/django_template_partials-24.4.tar.gz", hash = "sha256:25b67301470fc274ecc419e5e5fd4686a5020b1c038fd241a70eb087809034b6", size = 14538, upload-time = "2024-08-16T10:51:30.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/72/d8eea70683b25230e0d2647b5cf6f2db4a7e7d35cb6170506d9618196374/django_template_partials-24.4-py2.py3-none-any.whl", hash = "sha256:ee59d3839385d7f648907c3fa8d5923fcd66cd8090f141fe2a1c338b917984e2", size = 8439 }, + { url = "https://files.pythonhosted.org/packages/31/72/d8eea70683b25230e0d2647b5cf6f2db4a7e7d35cb6170506d9618196374/django_template_partials-24.4-py2.py3-none-any.whl", hash = "sha256:ee59d3839385d7f648907c3fa8d5923fcd66cd8090f141fe2a1c338b917984e2", size = 8439, upload-time = "2024-08-16T10:51:28.437Z" }, ] [[package]] @@ -363,35 +363,35 @@ dependencies = [ { name = "regex" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/89/ecf5be9f5c59a0c53bcaa29671742c5e269cc7d0e2622e3f65f41df251bf/djlint-1.36.4.tar.gz", hash = "sha256:17254f218b46fe5a714b224c85074c099bcb74e3b2e1f15c2ddc2cf415a408a1", size = 47849 } +sdist = { url = "https://files.pythonhosted.org/packages/74/89/ecf5be9f5c59a0c53bcaa29671742c5e269cc7d0e2622e3f65f41df251bf/djlint-1.36.4.tar.gz", hash = "sha256:17254f218b46fe5a714b224c85074c099bcb74e3b2e1f15c2ddc2cf415a408a1", size = 47849, upload-time = "2024-12-24T13:06:36.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/f5/9ae02b875604755d4d00cebf96b218b0faa3198edc630f56a139581aed87/djlint-1.36.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff9faffd7d43ac20467493fa71d5355b5b330a00ade1c4d1e859022f4195223b", size = 354886 }, - { url = "https://files.pythonhosted.org/packages/97/51/284443ff2f2a278f61d4ae6ae55eaf820ad9f0fd386d781cdfe91f4de495/djlint-1.36.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:79489e262b5ac23a8dfb7ca37f1eea979674cfc2d2644f7061d95bea12c38f7e", size = 323237 }, - { url = "https://files.pythonhosted.org/packages/6d/5e/791f4c5571f3f168ad26fa3757af8f7a05c623fde1134a9c4de814ee33b7/djlint-1.36.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e58c5fa8c6477144a0be0a87273706a059e6dd0d6efae01146ae8c29cdfca675", size = 411719 }, - { url = "https://files.pythonhosted.org/packages/1f/11/894425add6f84deffcc6e373f2ce250f2f7b01aa58c7f230016ebe7a0085/djlint-1.36.4-cp312-cp312-win_amd64.whl", hash = "sha256:bb6903777bf3124f5efedcddf1f4716aef097a7ec4223fc0fa54b865829a6e08", size = 362076 }, - { url = "https://files.pythonhosted.org/packages/da/83/88b4c885812921739f5529a29085c3762705154d41caf7eb9a8886a3380c/djlint-1.36.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ead475013bcac46095b1bbc8cf97ed2f06e83422335734363f8a76b4ba7e47c2", size = 354384 }, - { url = "https://files.pythonhosted.org/packages/32/38/67695f7a150b3d9d62fadb65242213d96024151570c3cf5d966effa68b0e/djlint-1.36.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c601dfa68ea253311deb4a29a7362b7a64933bdfcfb5a06618f3e70ad1fa835", size = 322971 }, - { url = "https://files.pythonhosted.org/packages/ac/7a/cd851393291b12e7fe17cf5d4d8874b8ea133aebbe9235f5314aabc96a52/djlint-1.36.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bda5014f295002363381969864addeb2db13955f1b26e772657c3b273ed7809f", size = 410972 }, - { url = "https://files.pythonhosted.org/packages/6c/31/56469120394b970d4f079a552fde21ed27702ca729595ab0ed459eb6d240/djlint-1.36.4-cp313-cp313-win_amd64.whl", hash = "sha256:16ce37e085afe5a30953b2bd87cbe34c37843d94c701fc68a2dda06c1e428ff4", size = 362053 }, - { url = "https://files.pythonhosted.org/packages/4b/67/f7aeea9be6fb3bd984487af8d0d80225a0b1e5f6f7126e3332d349fb13fe/djlint-1.36.4-py3-none-any.whl", hash = "sha256:e9699b8ac3057a6ed04fb90835b89bee954ed1959c01541ce4f8f729c938afdd", size = 52290 }, + { url = "https://files.pythonhosted.org/packages/53/f5/9ae02b875604755d4d00cebf96b218b0faa3198edc630f56a139581aed87/djlint-1.36.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff9faffd7d43ac20467493fa71d5355b5b330a00ade1c4d1e859022f4195223b", size = 354886, upload-time = "2024-12-24T13:06:11.571Z" }, + { url = "https://files.pythonhosted.org/packages/97/51/284443ff2f2a278f61d4ae6ae55eaf820ad9f0fd386d781cdfe91f4de495/djlint-1.36.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:79489e262b5ac23a8dfb7ca37f1eea979674cfc2d2644f7061d95bea12c38f7e", size = 323237, upload-time = "2024-12-24T13:06:13.057Z" }, + { url = "https://files.pythonhosted.org/packages/6d/5e/791f4c5571f3f168ad26fa3757af8f7a05c623fde1134a9c4de814ee33b7/djlint-1.36.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e58c5fa8c6477144a0be0a87273706a059e6dd0d6efae01146ae8c29cdfca675", size = 411719, upload-time = "2024-12-24T13:06:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/1f/11/894425add6f84deffcc6e373f2ce250f2f7b01aa58c7f230016ebe7a0085/djlint-1.36.4-cp312-cp312-win_amd64.whl", hash = "sha256:bb6903777bf3124f5efedcddf1f4716aef097a7ec4223fc0fa54b865829a6e08", size = 362076, upload-time = "2024-12-24T13:06:17.517Z" }, + { url = "https://files.pythonhosted.org/packages/da/83/88b4c885812921739f5529a29085c3762705154d41caf7eb9a8886a3380c/djlint-1.36.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ead475013bcac46095b1bbc8cf97ed2f06e83422335734363f8a76b4ba7e47c2", size = 354384, upload-time = "2024-12-24T13:06:20.809Z" }, + { url = "https://files.pythonhosted.org/packages/32/38/67695f7a150b3d9d62fadb65242213d96024151570c3cf5d966effa68b0e/djlint-1.36.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c601dfa68ea253311deb4a29a7362b7a64933bdfcfb5a06618f3e70ad1fa835", size = 322971, upload-time = "2024-12-24T13:06:22.185Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7a/cd851393291b12e7fe17cf5d4d8874b8ea133aebbe9235f5314aabc96a52/djlint-1.36.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bda5014f295002363381969864addeb2db13955f1b26e772657c3b273ed7809f", size = 410972, upload-time = "2024-12-24T13:06:24.077Z" }, + { url = "https://files.pythonhosted.org/packages/6c/31/56469120394b970d4f079a552fde21ed27702ca729595ab0ed459eb6d240/djlint-1.36.4-cp313-cp313-win_amd64.whl", hash = "sha256:16ce37e085afe5a30953b2bd87cbe34c37843d94c701fc68a2dda06c1e428ff4", size = 362053, upload-time = "2024-12-24T13:06:25.432Z" }, + { url = "https://files.pythonhosted.org/packages/4b/67/f7aeea9be6fb3bd984487af8d0d80225a0b1e5f6f7126e3332d349fb13fe/djlint-1.36.4-py3-none-any.whl", hash = "sha256:e9699b8ac3057a6ed04fb90835b89bee954ed1959c01541ce4f8f729c938afdd", size = 52290, upload-time = "2024-12-24T13:06:33.76Z" }, ] [[package]] name = "durationpy" version = "0.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/31/e9/f49c4e7fccb77fa5c43c2480e09a857a78b41e7331a75e128ed5df45c56b/durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a", size = 3186 } +sdist = { url = "https://files.pythonhosted.org/packages/31/e9/f49c4e7fccb77fa5c43c2480e09a857a78b41e7331a75e128ed5df45c56b/durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a", size = 3186, upload-time = "2024-10-02T17:59:00.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/a3/ac312faeceffd2d8f86bc6dcb5c401188ba5a01bc88e69bed97578a0dfcd/durationpy-0.9-py3-none-any.whl", hash = "sha256:e65359a7af5cedad07fb77a2dd3f390f8eb0b74cb845589fa6c057086834dd38", size = 3461 }, + { url = "https://files.pythonhosted.org/packages/4c/a3/ac312faeceffd2d8f86bc6dcb5c401188ba5a01bc88e69bed97578a0dfcd/durationpy-0.9-py3-none-any.whl", hash = "sha256:e65359a7af5cedad07fb77a2dd3f390f8eb0b74cb845589fa6c057086834dd38", size = 3461, upload-time = "2024-10-02T17:58:59.349Z" }, ] [[package]] name = "editorconfig" version = "0.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/29/785595a0d8b30ab8d2486559cfba1d46487b8dcbd99f74960b6b4cca92a4/editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2", size = 13369 } +sdist = { url = "https://files.pythonhosted.org/packages/b4/29/785595a0d8b30ab8d2486559cfba1d46487b8dcbd99f74960b6b4cca92a4/editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2", size = 13369, upload-time = "2024-12-12T21:04:21.278Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/e5/8dba39ea24ca3de0e954e668107692f4dfc13a85300a531fa9a39e83fde4/EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc", size = 16276 }, + { url = "https://files.pythonhosted.org/packages/af/e5/8dba39ea24ca3de0e954e668107692f4dfc13a85300a531fa9a39e83fde4/EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc", size = 16276, upload-time = "2024-12-12T21:04:01.098Z" }, ] [[package]] @@ -403,9 +403,9 @@ dependencies = [ { name = "pycodestyle" }, { name = "pyflakes" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/16/3f2a0bb700ad65ac9663262905a025917c020a3f92f014d2ba8964b4602c/flake8-7.1.2.tar.gz", hash = "sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd", size = 48119 } +sdist = { url = "https://files.pythonhosted.org/packages/58/16/3f2a0bb700ad65ac9663262905a025917c020a3f92f014d2ba8964b4602c/flake8-7.1.2.tar.gz", hash = "sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd", size = 48119, upload-time = "2025-02-16T18:45:44.296Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/f8/08d37b2cd89da306e3520bd27f8a85692122b42b56c0c2c3784ff09c022f/flake8-7.1.2-py2.py3-none-any.whl", hash = "sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a", size = 57745 }, + { url = "https://files.pythonhosted.org/packages/35/f8/08d37b2cd89da306e3520bd27f8a85692122b42b56c0c2c3784ff09c022f/flake8-7.1.2-py2.py3-none-any.whl", hash = "sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a", size = 57745, upload-time = "2025-02-16T18:45:42.351Z" }, ] [[package]] @@ -416,9 +416,9 @@ dependencies = [ { name = "attrs" }, { name = "flake8" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c7/25/48ba712ff589b0149f21135234f9bb45c14d6689acc6151b5e2ff8ac2ae9/flake8_bugbear-24.12.12.tar.gz", hash = "sha256:46273cef0a6b6ff48ca2d69e472f41420a42a46e24b2a8972e4f0d6733d12a64", size = 82907 } +sdist = { url = "https://files.pythonhosted.org/packages/c7/25/48ba712ff589b0149f21135234f9bb45c14d6689acc6151b5e2ff8ac2ae9/flake8_bugbear-24.12.12.tar.gz", hash = "sha256:46273cef0a6b6ff48ca2d69e472f41420a42a46e24b2a8972e4f0d6733d12a64", size = 82907, upload-time = "2024-12-12T16:49:26.307Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/21/0a875f75fbe4008bd171e2fefa413536258fe6b4cfaaa087986de74588f4/flake8_bugbear-24.12.12-py3-none-any.whl", hash = "sha256:1b6967436f65ca22a42e5373aaa6f2d87966ade9aa38d4baf2a1be550767545e", size = 36664 }, + { url = "https://files.pythonhosted.org/packages/b9/21/0a875f75fbe4008bd171e2fefa413536258fe6b4cfaaa087986de74588f4/flake8_bugbear-24.12.12-py3-none-any.whl", hash = "sha256:1b6967436f65ca22a42e5373aaa6f2d87966ade9aa38d4baf2a1be550767545e", size = 36664, upload-time = "2024-12-12T16:49:23.584Z" }, ] [[package]] @@ -429,7 +429,7 @@ dependencies = [ { name = "flake8" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/1d/635e86f9f3a96b7ea9e9f19b5efe17a987e765c39ca496e4a893bb999112/flake8_pyproject-1.2.3-py3-none-any.whl", hash = "sha256:6249fe53545205af5e76837644dc80b4c10037e73a0e5db87ff562d75fb5bd4a", size = 4756 }, + { url = "https://files.pythonhosted.org/packages/5f/1d/635e86f9f3a96b7ea9e9f19b5efe17a987e765c39ca496e4a893bb999112/flake8_pyproject-1.2.3-py3-none-any.whl", hash = "sha256:6249fe53545205af5e76837644dc80b4c10037e73a0e5db87ff562d75fb5bd4a", size = 4756, upload-time = "2023-03-21T20:51:38.911Z" }, ] [[package]] @@ -441,36 +441,36 @@ dependencies = [ { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/eb/d504ba1daf190af6b204a9d4714d457462b486043744901a6eeea711f913/google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4", size = 270866 } +sdist = { url = "https://files.pythonhosted.org/packages/c6/eb/d504ba1daf190af6b204a9d4714d457462b486043744901a6eeea711f913/google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4", size = 270866, upload-time = "2025-01-23T01:05:29.119Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/47/603554949a37bca5b7f894d51896a9c534b9eab808e2520a748e081669d0/google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a", size = 210770 }, + { url = "https://files.pythonhosted.org/packages/9d/47/603554949a37bca5b7f894d51896a9c534b9eab808e2520a748e081669d0/google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a", size = 210770, upload-time = "2025-01-23T01:05:26.572Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, ] [[package]] name = "isort" version = "6.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955 } +sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955, upload-time = "2025-02-26T21:13:16.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186 }, + { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186, upload-time = "2025-02-26T21:13:14.911Z" }, ] [[package]] @@ -481,18 +481,18 @@ dependencies = [ { name = "editorconfig" }, { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ea/98/d6cadf4d5a1c03b2136837a435682418c29fdeb66be137128544cecc5b7a/jsbeautifier-1.15.4.tar.gz", hash = "sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592", size = 75257 } +sdist = { url = "https://files.pythonhosted.org/packages/ea/98/d6cadf4d5a1c03b2136837a435682418c29fdeb66be137128544cecc5b7a/jsbeautifier-1.15.4.tar.gz", hash = "sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592", size = 75257, upload-time = "2025-02-27T17:53:53.252Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528", size = 94707 }, + { url = "https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528", size = 94707, upload-time = "2025-02-27T17:53:46.152Z" }, ] [[package]] name = "json5" version = "0.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/3d/bbe62f3d0c05a689c711cff57b2e3ac3d3e526380adb7c781989f075115c/json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559", size = 48202 } +sdist = { url = "https://files.pythonhosted.org/packages/85/3d/bbe62f3d0c05a689c711cff57b2e3ac3d3e526380adb7c781989f075115c/json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559", size = 48202, upload-time = "2024-11-26T19:56:37.823Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/42/797895b952b682c3dafe23b1834507ee7f02f4d6299b65aaa61425763278/json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa", size = 34049 }, + { url = "https://files.pythonhosted.org/packages/aa/42/797895b952b682c3dafe23b1834507ee7f02f4d6299b65aaa61425763278/json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa", size = 34049, upload-time = "2024-11-26T19:56:36.649Z" }, ] [[package]] @@ -505,9 +505,9 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 } +sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778, upload-time = "2024-07-08T18:40:05.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, + { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462, upload-time = "2024-07-08T18:40:00.165Z" }, ] [[package]] @@ -517,9 +517,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 } +sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561, upload-time = "2024-10-08T12:29:32.068Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, + { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459, upload-time = "2024-10-08T12:29:30.439Z" }, ] [[package]] @@ -539,159 +539,159 @@ dependencies = [ { name = "urllib3" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/e8/0598f0e8b4af37cd9b10d8b87386cf3173cb8045d834ab5f6ec347a758b3/kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28", size = 946691 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/e8/0598f0e8b4af37cd9b10d8b87386cf3173cb8045d834ab5f6ec347a758b3/kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28", size = 946691, upload-time = "2025-02-18T21:06:34.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/10/9f8af3e6f569685ce3af7faab51c8dd9d93b9c38eba339ca31c746119447/kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998", size = 1988070 }, + { url = "https://files.pythonhosted.org/packages/08/10/9f8af3e6f569685ce3af7faab51c8dd9d93b9c38eba339ca31c746119447/kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998", size = 1988070, upload-time = "2025-02-18T21:06:31.391Z" }, ] [[package]] name = "lexid" version = "2021.1006" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/60/0b/28a3f9abc75abbf1fa996eb2dd77e1e33a5d1aac62566e3f60a8ec8b8a22/lexid-2021.1006.tar.gz", hash = "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5", size = 11525 } +sdist = { url = "https://files.pythonhosted.org/packages/60/0b/28a3f9abc75abbf1fa996eb2dd77e1e33a5d1aac62566e3f60a8ec8b8a22/lexid-2021.1006.tar.gz", hash = "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5", size = 11525, upload-time = "2021-04-02T20:18:34.668Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/e3/35764404a4b7e2021be1f88f42264c2e92e0c4720273559a62461ce64a47/lexid-2021.1006-py2.py3-none-any.whl", hash = "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed", size = 7587 }, + { url = "https://files.pythonhosted.org/packages/cf/e3/35764404a4b7e2021be1f88f42264c2e92e0c4720273559a62461ce64a47/lexid-2021.1006-py2.py3-none-any.whl", hash = "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed", size = 7587, upload-time = "2021-04-02T20:18:33.129Z" }, ] [[package]] name = "mccabe" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350 }, + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] [[package]] name = "mypy-extensions" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, ] [[package]] name = "oauthlib" version = "3.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352, upload-time = "2022-10-17T20:04:27.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688 }, + { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688, upload-time = "2022-10-17T20:04:24.037Z" }, ] [[package]] name = "packaging" version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "pillow" version = "11.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715, upload-time = "2025-01-02T08:13:58.407Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818 }, - { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662 }, - { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317 }, - { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999 }, - { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819 }, - { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081 }, - { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513 }, - { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298 }, - { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630 }, - { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369 }, - { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240 }, - { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 }, - { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 }, - { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 }, - { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 }, - { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 }, - { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 }, - { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 }, - { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 }, - { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 }, - { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 }, - { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 }, - { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 }, - { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 }, - { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 }, - { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 }, - { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 }, - { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 }, - { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 }, - { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 }, + { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818, upload-time = "2025-01-02T08:11:22.518Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662, upload-time = "2025-01-02T08:11:25.19Z" }, + { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317, upload-time = "2025-01-02T08:11:30.371Z" }, + { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999, upload-time = "2025-01-02T08:11:33.499Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819, upload-time = "2025-01-02T08:11:37.304Z" }, + { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081, upload-time = "2025-01-02T08:11:39.598Z" }, + { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513, upload-time = "2025-01-02T08:11:43.083Z" }, + { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298, upload-time = "2025-01-02T08:11:46.626Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630, upload-time = "2025-01-02T08:11:49.401Z" }, + { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369, upload-time = "2025-01-02T08:11:52.02Z" }, + { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240, upload-time = "2025-01-02T08:11:56.193Z" }, + { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640, upload-time = "2025-01-02T08:11:58.329Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437, upload-time = "2025-01-02T08:12:01.797Z" }, + { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605, upload-time = "2025-01-02T08:12:05.224Z" }, + { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173, upload-time = "2025-01-02T08:12:08.281Z" }, + { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145, upload-time = "2025-01-02T08:12:11.411Z" }, + { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340, upload-time = "2025-01-02T08:12:15.29Z" }, + { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906, upload-time = "2025-01-02T08:12:17.485Z" }, + { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759, upload-time = "2025-01-02T08:12:20.382Z" }, + { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657, upload-time = "2025-01-02T08:12:23.922Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304, upload-time = "2025-01-02T08:12:28.069Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117, upload-time = "2025-01-02T08:12:30.064Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060, upload-time = "2025-01-02T08:12:32.362Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192, upload-time = "2025-01-02T08:12:34.361Z" }, + { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805, upload-time = "2025-01-02T08:12:36.99Z" }, + { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623, upload-time = "2025-01-02T08:12:41.912Z" }, + { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191, upload-time = "2025-01-02T08:12:45.186Z" }, + { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494, upload-time = "2025-01-02T08:12:47.098Z" }, + { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595, upload-time = "2025-01-02T08:12:50.47Z" }, + { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651, upload-time = "2025-01-02T08:12:53.356Z" }, ] [[package]] name = "platformdirs" version = "4.3.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302, upload-time = "2024-09-17T19:06:50.688Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439, upload-time = "2024-09-17T19:06:49.212Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] name = "psycopg2-binary" version = "2.9.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764 } +sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764, upload-time = "2024-10-16T11:24:58.126Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771 }, - { url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336 }, - { url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637 }, - { url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097 }, - { url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776 }, - { url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968 }, - { url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334 }, - { url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722 }, - { url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132 }, - { url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312 }, - { url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191 }, - { url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031 }, - { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699 }, - { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245 }, - { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631 }, - { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140 }, - { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762 }, - { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967 }, - { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326 }, - { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, - { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, - { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, - { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, + { url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771, upload-time = "2024-10-16T11:20:35.234Z" }, + { url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336, upload-time = "2024-10-16T11:20:38.742Z" }, + { url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637, upload-time = "2024-10-16T11:20:42.145Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097, upload-time = "2024-10-16T11:20:46.185Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776, upload-time = "2024-10-16T11:20:50.879Z" }, + { url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968, upload-time = "2024-10-16T11:20:56.819Z" }, + { url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334, upload-time = "2024-10-16T11:21:02.411Z" }, + { url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722, upload-time = "2024-10-16T11:21:09.01Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132, upload-time = "2024-10-16T11:21:16.339Z" }, + { url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312, upload-time = "2024-10-16T11:21:25.584Z" }, + { url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191, upload-time = "2024-10-16T11:21:29.912Z" }, + { url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031, upload-time = "2024-10-16T11:21:34.211Z" }, + { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699, upload-time = "2024-10-16T11:21:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245, upload-time = "2024-10-16T11:21:51.989Z" }, + { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631, upload-time = "2024-10-16T11:21:57.584Z" }, + { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140, upload-time = "2024-10-16T11:22:02.005Z" }, + { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762, upload-time = "2024-10-16T11:22:06.412Z" }, + { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967, upload-time = "2024-10-16T11:22:11.583Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326, upload-time = "2024-10-16T11:22:16.406Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712, upload-time = "2024-10-16T11:22:21.366Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155, upload-time = "2024-10-16T11:22:25.684Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356, upload-time = "2024-10-16T11:22:30.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224, upload-time = "2025-01-04T20:09:19.234Z" }, ] [[package]] name = "pyasn1" version = "0.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, ] [[package]] @@ -701,45 +701,45 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1d/67/6afbf0d507f73c32d21084a79946bfcfca5fbc62a72057e9c23797a737c9/pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c", size = 310028 } +sdist = { url = "https://files.pythonhosted.org/packages/1d/67/6afbf0d507f73c32d21084a79946bfcfca5fbc62a72057e9c23797a737c9/pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c", size = 310028, upload-time = "2024-09-10T22:42:08.349Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", size = 181537 }, + { url = "https://files.pythonhosted.org/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", size = 181537, upload-time = "2024-09-11T16:02:10.336Z" }, ] [[package]] name = "pycodestyle" version = "2.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232 } +sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232, upload-time = "2024-08-04T20:26:54.576Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284 }, + { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284, upload-time = "2024-08-04T20:26:53.173Z" }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pyflakes" version = "3.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/f9/669d8c9c86613c9d568757c7f5824bd3197d7b1c6c27553bc5618a27cce2/pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", size = 63788 } +sdist = { url = "https://files.pythonhosted.org/packages/57/f9/669d8c9c86613c9d568757c7f5824bd3197d7b1c6c27553bc5618a27cce2/pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", size = 63788, upload-time = "2024-01-05T00:28:47.703Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/d7/f1b7db88d8e4417c5d47adad627a93547f44bdc9028372dbd2313f34a855/pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a", size = 62725 }, + { url = "https://files.pythonhosted.org/packages/d4/d7/f1b7db88d8e4417c5d47adad627a93547f44bdc9028372dbd2313f34a855/pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a", size = 62725, upload-time = "2024-01-05T00:28:45.903Z" }, ] [[package]] name = "pyjwt" version = "2.10.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, ] [[package]] @@ -752,9 +752,9 @@ dependencies = [ { name = "packaging" }, { name = "pluggy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] [[package]] @@ -765,9 +765,9 @@ dependencies = [ { name = "coverage" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945, upload-time = "2024-10-29T20:13:35.363Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949, upload-time = "2024-10-29T20:13:33.215Z" }, ] [[package]] @@ -777,9 +777,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a5/10/a096573b4b896f18a8390d9dafaffc054c1f613c60bf838300732e538890/pytest_django-4.10.0.tar.gz", hash = "sha256:1091b20ea1491fd04a310fc9aaff4c01b4e8450e3b157687625e16a6b5f3a366", size = 84710 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/10/a096573b4b896f18a8390d9dafaffc054c1f613c60bf838300732e538890/pytest_django-4.10.0.tar.gz", hash = "sha256:1091b20ea1491fd04a310fc9aaff4c01b4e8450e3b157687625e16a6b5f3a366", size = 84710, upload-time = "2025-02-10T14:52:57.337Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/4c/a4fe18205926216e1aebe1f125cba5bce444f91b6e4de4f49fa87e322775/pytest_django-4.10.0-py3-none-any.whl", hash = "sha256:57c74ef3aa9d89cae5a5d73fbb69a720a62673ade7ff13b9491872409a3f5918", size = 23975 }, + { url = "https://files.pythonhosted.org/packages/58/4c/a4fe18205926216e1aebe1f125cba5bce444f91b6e4de4f49fa87e322775/pytest_django-4.10.0-py3-none-any.whl", hash = "sha256:57c74ef3aa9d89cae5a5d73fbb69a720a62673ade7ff13b9491872409a3f5918", size = 23975, upload-time = "2025-02-10T14:52:55.325Z" }, ] [[package]] @@ -789,35 +789,35 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] @@ -829,47 +829,47 @@ dependencies = [ { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775 }, + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, ] [[package]] name = "regex" version = "2024.11.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload-time = "2024-11-06T20:12:31.635Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, - { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, - { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, - { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, - { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, - { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, - { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, - { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, - { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, - { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, - { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, - { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, - { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, - { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, - { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, - { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, - { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, - { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, - { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, - { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, - { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, - { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, - { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, - { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, - { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, - { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, - { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, - { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, - { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, - { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781, upload-time = "2024-11-06T20:10:07.07Z" }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455, upload-time = "2024-11-06T20:10:09.117Z" }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759, upload-time = "2024-11-06T20:10:11.155Z" }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976, upload-time = "2024-11-06T20:10:13.24Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077, upload-time = "2024-11-06T20:10:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160, upload-time = "2024-11-06T20:10:19.027Z" }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896, upload-time = "2024-11-06T20:10:21.85Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997, upload-time = "2024-11-06T20:10:24.329Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725, upload-time = "2024-11-06T20:10:28.067Z" }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481, upload-time = "2024-11-06T20:10:31.612Z" }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896, upload-time = "2024-11-06T20:10:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138, upload-time = "2024-11-06T20:10:36.142Z" }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692, upload-time = "2024-11-06T20:10:38.394Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135, upload-time = "2024-11-06T20:10:40.367Z" }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567, upload-time = "2024-11-06T20:10:43.467Z" }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525, upload-time = "2024-11-06T20:10:45.19Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324, upload-time = "2024-11-06T20:10:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617, upload-time = "2024-11-06T20:10:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023, upload-time = "2024-11-06T20:10:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072, upload-time = "2024-11-06T20:10:52.926Z" }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130, upload-time = "2024-11-06T20:10:54.828Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857, upload-time = "2024-11-06T20:10:56.634Z" }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006, upload-time = "2024-11-06T20:10:59.369Z" }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650, upload-time = "2024-11-06T20:11:02.042Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545, upload-time = "2024-11-06T20:11:03.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045, upload-time = "2024-11-06T20:11:06.497Z" }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182, upload-time = "2024-11-06T20:11:09.06Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733, upload-time = "2024-11-06T20:11:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122, upload-time = "2024-11-06T20:11:13.161Z" }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545, upload-time = "2024-11-06T20:11:15Z" }, ] [[package]] @@ -882,9 +882,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, ] [[package]] @@ -895,56 +895,56 @@ dependencies = [ { name = "oauthlib" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650 } +sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650, upload-time = "2024-03-22T20:32:29.939Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179 }, + { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179, upload-time = "2024-03-22T20:32:28.055Z" }, ] [[package]] name = "rpds-py" version = "0.24.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/b3/52b213298a0ba7097c7ea96bee95e1947aa84cc816d48cebb539770cdf41/rpds_py-0.24.0.tar.gz", hash = "sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e", size = 26863 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/b3/52b213298a0ba7097c7ea96bee95e1947aa84cc816d48cebb539770cdf41/rpds_py-0.24.0.tar.gz", hash = "sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e", size = 26863, upload-time = "2025-03-26T14:56:01.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/e0/1c55f4a3be5f1ca1a4fd1f3ff1504a1478c1ed48d84de24574c4fa87e921/rpds_py-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d8551e733626afec514b5d15befabea0dd70a343a9f23322860c4f16a9430205", size = 366945 }, - { url = "https://files.pythonhosted.org/packages/39/1b/a3501574fbf29118164314dbc800d568b8c1c7b3258b505360e8abb3902c/rpds_py-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e374c0ce0ca82e5b67cd61fb964077d40ec177dd2c4eda67dba130de09085c7", size = 351935 }, - { url = "https://files.pythonhosted.org/packages/dc/47/77d3d71c55f6a374edde29f1aca0b2e547325ed00a9da820cabbc9497d2b/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d69d003296df4840bd445a5d15fa5b6ff6ac40496f956a221c4d1f6f7b4bc4d9", size = 390817 }, - { url = "https://files.pythonhosted.org/packages/4e/ec/1e336ee27484379e19c7f9cc170f4217c608aee406d3ae3a2e45336bff36/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8212ff58ac6dfde49946bea57474a386cca3f7706fc72c25b772b9ca4af6b79e", size = 401983 }, - { url = "https://files.pythonhosted.org/packages/07/f8/39b65cbc272c635eaea6d393c2ad1ccc81c39eca2db6723a0ca4b2108fce/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:528927e63a70b4d5f3f5ccc1fa988a35456eb5d15f804d276709c33fc2f19bda", size = 451719 }, - { url = "https://files.pythonhosted.org/packages/32/05/05c2b27dd9c30432f31738afed0300659cb9415db0ff7429b05dfb09bbde/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a824d2c7a703ba6daaca848f9c3d5cb93af0505be505de70e7e66829affd676e", size = 442546 }, - { url = "https://files.pythonhosted.org/packages/7d/e0/19383c8b5d509bd741532a47821c3e96acf4543d0832beba41b4434bcc49/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d51febb7a114293ffd56c6cf4736cb31cd68c0fddd6aa303ed09ea5a48e029", size = 393695 }, - { url = "https://files.pythonhosted.org/packages/9d/15/39f14e96d94981d0275715ae8ea564772237f3fa89bc3c21e24de934f2c7/rpds_py-0.24.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3fab5f4a2c64a8fb64fc13b3d139848817a64d467dd6ed60dcdd6b479e7febc9", size = 427218 }, - { url = "https://files.pythonhosted.org/packages/22/b9/12da7124905a680f690da7a9de6f11de770b5e359f5649972f7181c8bf51/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9be4f99bee42ac107870c61dfdb294d912bf81c3c6d45538aad7aecab468b6b7", size = 568062 }, - { url = "https://files.pythonhosted.org/packages/88/17/75229017a2143d915f6f803721a6d721eca24f2659c5718a538afa276b4f/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:564c96b6076a98215af52f55efa90d8419cc2ef45d99e314fddefe816bc24f91", size = 596262 }, - { url = "https://files.pythonhosted.org/packages/aa/64/8e8a1d8bd1b6b638d6acb6d41ab2cec7f2067a5b8b4c9175703875159a7c/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:75a810b7664c17f24bf2ffd7f92416c00ec84b49bb68e6a0d93e542406336b56", size = 564306 }, - { url = "https://files.pythonhosted.org/packages/68/1c/a7eac8d8ed8cb234a9b1064647824c387753343c3fab6ed7c83481ed0be7/rpds_py-0.24.0-cp312-cp312-win32.whl", hash = "sha256:f6016bd950be4dcd047b7475fdf55fb1e1f59fc7403f387be0e8123e4a576d30", size = 224281 }, - { url = "https://files.pythonhosted.org/packages/bb/46/b8b5424d1d21f2f2f3f2d468660085318d4f74a8df8289e3dd6ad224d488/rpds_py-0.24.0-cp312-cp312-win_amd64.whl", hash = "sha256:998c01b8e71cf051c28f5d6f1187abbdf5cf45fc0efce5da6c06447cba997034", size = 239719 }, - { url = "https://files.pythonhosted.org/packages/9d/c3/3607abc770395bc6d5a00cb66385a5479fb8cd7416ddef90393b17ef4340/rpds_py-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2d8e4508e15fc05b31285c4b00ddf2e0eb94259c2dc896771966a163122a0c", size = 367072 }, - { url = "https://files.pythonhosted.org/packages/d8/35/8c7ee0fe465793e3af3298dc5a9f3013bd63e7a69df04ccfded8293a4982/rpds_py-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f00c16e089282ad68a3820fd0c831c35d3194b7cdc31d6e469511d9bffc535c", size = 351919 }, - { url = "https://files.pythonhosted.org/packages/91/d3/7e1b972501eb5466b9aca46a9c31bcbbdc3ea5a076e9ab33f4438c1d069d/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951cc481c0c395c4a08639a469d53b7d4afa252529a085418b82a6b43c45c240", size = 390360 }, - { url = "https://files.pythonhosted.org/packages/a2/a8/ccabb50d3c91c26ad01f9b09a6a3b03e4502ce51a33867c38446df9f896b/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9ca89938dff18828a328af41ffdf3902405a19f4131c88e22e776a8e228c5a8", size = 400704 }, - { url = "https://files.pythonhosted.org/packages/53/ae/5fa5bf0f3bc6ce21b5ea88fc0ecd3a439e7cb09dd5f9ffb3dbe1b6894fc5/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0ef550042a8dbcd657dfb284a8ee00f0ba269d3f2286b0493b15a5694f9fe8", size = 450839 }, - { url = "https://files.pythonhosted.org/packages/e3/ac/c4e18b36d9938247e2b54f6a03746f3183ca20e1edd7d3654796867f5100/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b2356688e5d958c4d5cb964af865bea84db29971d3e563fb78e46e20fe1848b", size = 441494 }, - { url = "https://files.pythonhosted.org/packages/bf/08/b543969c12a8f44db6c0f08ced009abf8f519191ca6985509e7c44102e3c/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78884d155fd15d9f64f5d6124b486f3d3f7fd7cd71a78e9670a0f6f6ca06fb2d", size = 393185 }, - { url = "https://files.pythonhosted.org/packages/da/7e/f6eb6a7042ce708f9dfc781832a86063cea8a125bbe451d663697b51944f/rpds_py-0.24.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a4a535013aeeef13c5532f802708cecae8d66c282babb5cd916379b72110cf7", size = 426168 }, - { url = "https://files.pythonhosted.org/packages/38/b0/6cd2bb0509ac0b51af4bb138e145b7c4c902bb4b724d6fd143689d6e0383/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:84e0566f15cf4d769dade9b366b7b87c959be472c92dffb70462dd0844d7cbad", size = 567622 }, - { url = "https://files.pythonhosted.org/packages/64/b0/c401f4f077547d98e8b4c2ec6526a80e7cb04f519d416430ec1421ee9e0b/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:823e74ab6fbaa028ec89615ff6acb409e90ff45580c45920d4dfdddb069f2120", size = 595435 }, - { url = "https://files.pythonhosted.org/packages/9f/ec/7993b6e803294c87b61c85bd63e11142ccfb2373cf88a61ec602abcbf9d6/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c61a2cb0085c8783906b2f8b1f16a7e65777823c7f4d0a6aaffe26dc0d358dd9", size = 563762 }, - { url = "https://files.pythonhosted.org/packages/1f/29/4508003204cb2f461dc2b83dd85f8aa2b915bc98fe6046b9d50d4aa05401/rpds_py-0.24.0-cp313-cp313-win32.whl", hash = "sha256:60d9b630c8025b9458a9d114e3af579a2c54bd32df601c4581bd054e85258143", size = 223510 }, - { url = "https://files.pythonhosted.org/packages/f9/12/09e048d1814195e01f354155fb772fb0854bd3450b5f5a82224b3a319f0e/rpds_py-0.24.0-cp313-cp313-win_amd64.whl", hash = "sha256:6eea559077d29486c68218178ea946263b87f1c41ae7f996b1f30a983c476a5a", size = 239075 }, - { url = "https://files.pythonhosted.org/packages/d2/03/5027cde39bb2408d61e4dd0cf81f815949bb629932a6c8df1701d0257fc4/rpds_py-0.24.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:d09dc82af2d3c17e7dd17120b202a79b578d79f2b5424bda209d9966efeed114", size = 362974 }, - { url = "https://files.pythonhosted.org/packages/bf/10/24d374a2131b1ffafb783e436e770e42dfdb74b69a2cd25eba8c8b29d861/rpds_py-0.24.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5fc13b44de6419d1e7a7e592a4885b323fbc2f46e1f22151e3a8ed3b8b920405", size = 348730 }, - { url = "https://files.pythonhosted.org/packages/7a/d1/1ef88d0516d46cd8df12e5916966dbf716d5ec79b265eda56ba1b173398c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c347a20d79cedc0a7bd51c4d4b7dbc613ca4e65a756b5c3e57ec84bd43505b47", size = 387627 }, - { url = "https://files.pythonhosted.org/packages/4e/35/07339051b8b901ecefd449ebf8e5522e92bcb95e1078818cbfd9db8e573c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20f2712bd1cc26a3cc16c5a1bfee9ed1abc33d4cdf1aabd297fe0eb724df4272", size = 394094 }, - { url = "https://files.pythonhosted.org/packages/dc/62/ee89ece19e0ba322b08734e95441952062391065c157bbd4f8802316b4f1/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad911555286884be1e427ef0dc0ba3929e6821cbeca2194b13dc415a462c7fd", size = 449639 }, - { url = "https://files.pythonhosted.org/packages/15/24/b30e9f9e71baa0b9dada3a4ab43d567c6b04a36d1cb531045f7a8a0a7439/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0aeb3329c1721c43c58cae274d7d2ca85c1690d89485d9c63a006cb79a85771a", size = 438584 }, - { url = "https://files.pythonhosted.org/packages/28/d9/49f7b8f3b4147db13961e19d5e30077cd0854ccc08487026d2cb2142aa4a/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a0f156e9509cee987283abd2296ec816225145a13ed0391df8f71bf1d789e2d", size = 391047 }, - { url = "https://files.pythonhosted.org/packages/49/b0/e66918d0972c33a259ba3cd7b7ff10ed8bd91dbcfcbec6367b21f026db75/rpds_py-0.24.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa6800adc8204ce898c8a424303969b7aa6a5e4ad2789c13f8648739830323b7", size = 418085 }, - { url = "https://files.pythonhosted.org/packages/e1/6b/99ed7ea0a94c7ae5520a21be77a82306aac9e4e715d4435076ead07d05c6/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a18fc371e900a21d7392517c6f60fe859e802547309e94313cd8181ad9db004d", size = 564498 }, - { url = "https://files.pythonhosted.org/packages/28/26/1cacfee6b800e6fb5f91acecc2e52f17dbf8b0796a7c984b4568b6d70e38/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9168764133fd919f8dcca2ead66de0105f4ef5659cbb4fa044f7014bed9a1797", size = 590202 }, - { url = "https://files.pythonhosted.org/packages/a9/9e/57bd2f9fba04a37cef673f9a66b11ca8c43ccdd50d386c455cd4380fe461/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f6e3cec44ba05ee5cbdebe92d052f69b63ae792e7d05f1020ac5e964394080c", size = 561771 }, - { url = "https://files.pythonhosted.org/packages/9f/cf/b719120f375ab970d1c297dbf8de1e3c9edd26fe92c0ed7178dd94b45992/rpds_py-0.24.0-cp313-cp313t-win32.whl", hash = "sha256:8ebc7e65ca4b111d928b669713865f021b7773350eeac4a31d3e70144297baba", size = 221195 }, - { url = "https://files.pythonhosted.org/packages/2d/e5/22865285789f3412ad0c3d7ec4dc0a3e86483b794be8a5d9ed5a19390900/rpds_py-0.24.0-cp313-cp313t-win_amd64.whl", hash = "sha256:675269d407a257b8c00a6b58205b72eec8231656506c56fd429d924ca00bb350", size = 237354 }, + { url = "https://files.pythonhosted.org/packages/1a/e0/1c55f4a3be5f1ca1a4fd1f3ff1504a1478c1ed48d84de24574c4fa87e921/rpds_py-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d8551e733626afec514b5d15befabea0dd70a343a9f23322860c4f16a9430205", size = 366945, upload-time = "2025-03-26T14:53:28.149Z" }, + { url = "https://files.pythonhosted.org/packages/39/1b/a3501574fbf29118164314dbc800d568b8c1c7b3258b505360e8abb3902c/rpds_py-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e374c0ce0ca82e5b67cd61fb964077d40ec177dd2c4eda67dba130de09085c7", size = 351935, upload-time = "2025-03-26T14:53:29.684Z" }, + { url = "https://files.pythonhosted.org/packages/dc/47/77d3d71c55f6a374edde29f1aca0b2e547325ed00a9da820cabbc9497d2b/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d69d003296df4840bd445a5d15fa5b6ff6ac40496f956a221c4d1f6f7b4bc4d9", size = 390817, upload-time = "2025-03-26T14:53:31.177Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ec/1e336ee27484379e19c7f9cc170f4217c608aee406d3ae3a2e45336bff36/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8212ff58ac6dfde49946bea57474a386cca3f7706fc72c25b772b9ca4af6b79e", size = 401983, upload-time = "2025-03-26T14:53:33.163Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/39b65cbc272c635eaea6d393c2ad1ccc81c39eca2db6723a0ca4b2108fce/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:528927e63a70b4d5f3f5ccc1fa988a35456eb5d15f804d276709c33fc2f19bda", size = 451719, upload-time = "2025-03-26T14:53:34.721Z" }, + { url = "https://files.pythonhosted.org/packages/32/05/05c2b27dd9c30432f31738afed0300659cb9415db0ff7429b05dfb09bbde/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a824d2c7a703ba6daaca848f9c3d5cb93af0505be505de70e7e66829affd676e", size = 442546, upload-time = "2025-03-26T14:53:36.26Z" }, + { url = "https://files.pythonhosted.org/packages/7d/e0/19383c8b5d509bd741532a47821c3e96acf4543d0832beba41b4434bcc49/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d51febb7a114293ffd56c6cf4736cb31cd68c0fddd6aa303ed09ea5a48e029", size = 393695, upload-time = "2025-03-26T14:53:37.728Z" }, + { url = "https://files.pythonhosted.org/packages/9d/15/39f14e96d94981d0275715ae8ea564772237f3fa89bc3c21e24de934f2c7/rpds_py-0.24.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3fab5f4a2c64a8fb64fc13b3d139848817a64d467dd6ed60dcdd6b479e7febc9", size = 427218, upload-time = "2025-03-26T14:53:39.326Z" }, + { url = "https://files.pythonhosted.org/packages/22/b9/12da7124905a680f690da7a9de6f11de770b5e359f5649972f7181c8bf51/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9be4f99bee42ac107870c61dfdb294d912bf81c3c6d45538aad7aecab468b6b7", size = 568062, upload-time = "2025-03-26T14:53:40.885Z" }, + { url = "https://files.pythonhosted.org/packages/88/17/75229017a2143d915f6f803721a6d721eca24f2659c5718a538afa276b4f/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:564c96b6076a98215af52f55efa90d8419cc2ef45d99e314fddefe816bc24f91", size = 596262, upload-time = "2025-03-26T14:53:42.544Z" }, + { url = "https://files.pythonhosted.org/packages/aa/64/8e8a1d8bd1b6b638d6acb6d41ab2cec7f2067a5b8b4c9175703875159a7c/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:75a810b7664c17f24bf2ffd7f92416c00ec84b49bb68e6a0d93e542406336b56", size = 564306, upload-time = "2025-03-26T14:53:44.2Z" }, + { url = "https://files.pythonhosted.org/packages/68/1c/a7eac8d8ed8cb234a9b1064647824c387753343c3fab6ed7c83481ed0be7/rpds_py-0.24.0-cp312-cp312-win32.whl", hash = "sha256:f6016bd950be4dcd047b7475fdf55fb1e1f59fc7403f387be0e8123e4a576d30", size = 224281, upload-time = "2025-03-26T14:53:45.769Z" }, + { url = "https://files.pythonhosted.org/packages/bb/46/b8b5424d1d21f2f2f3f2d468660085318d4f74a8df8289e3dd6ad224d488/rpds_py-0.24.0-cp312-cp312-win_amd64.whl", hash = "sha256:998c01b8e71cf051c28f5d6f1187abbdf5cf45fc0efce5da6c06447cba997034", size = 239719, upload-time = "2025-03-26T14:53:47.187Z" }, + { url = "https://files.pythonhosted.org/packages/9d/c3/3607abc770395bc6d5a00cb66385a5479fb8cd7416ddef90393b17ef4340/rpds_py-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2d8e4508e15fc05b31285c4b00ddf2e0eb94259c2dc896771966a163122a0c", size = 367072, upload-time = "2025-03-26T14:53:48.686Z" }, + { url = "https://files.pythonhosted.org/packages/d8/35/8c7ee0fe465793e3af3298dc5a9f3013bd63e7a69df04ccfded8293a4982/rpds_py-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f00c16e089282ad68a3820fd0c831c35d3194b7cdc31d6e469511d9bffc535c", size = 351919, upload-time = "2025-03-26T14:53:50.229Z" }, + { url = "https://files.pythonhosted.org/packages/91/d3/7e1b972501eb5466b9aca46a9c31bcbbdc3ea5a076e9ab33f4438c1d069d/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951cc481c0c395c4a08639a469d53b7d4afa252529a085418b82a6b43c45c240", size = 390360, upload-time = "2025-03-26T14:53:51.909Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a8/ccabb50d3c91c26ad01f9b09a6a3b03e4502ce51a33867c38446df9f896b/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9ca89938dff18828a328af41ffdf3902405a19f4131c88e22e776a8e228c5a8", size = 400704, upload-time = "2025-03-26T14:53:53.47Z" }, + { url = "https://files.pythonhosted.org/packages/53/ae/5fa5bf0f3bc6ce21b5ea88fc0ecd3a439e7cb09dd5f9ffb3dbe1b6894fc5/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0ef550042a8dbcd657dfb284a8ee00f0ba269d3f2286b0493b15a5694f9fe8", size = 450839, upload-time = "2025-03-26T14:53:55.005Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ac/c4e18b36d9938247e2b54f6a03746f3183ca20e1edd7d3654796867f5100/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b2356688e5d958c4d5cb964af865bea84db29971d3e563fb78e46e20fe1848b", size = 441494, upload-time = "2025-03-26T14:53:57.047Z" }, + { url = "https://files.pythonhosted.org/packages/bf/08/b543969c12a8f44db6c0f08ced009abf8f519191ca6985509e7c44102e3c/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78884d155fd15d9f64f5d6124b486f3d3f7fd7cd71a78e9670a0f6f6ca06fb2d", size = 393185, upload-time = "2025-03-26T14:53:59.032Z" }, + { url = "https://files.pythonhosted.org/packages/da/7e/f6eb6a7042ce708f9dfc781832a86063cea8a125bbe451d663697b51944f/rpds_py-0.24.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a4a535013aeeef13c5532f802708cecae8d66c282babb5cd916379b72110cf7", size = 426168, upload-time = "2025-03-26T14:54:00.661Z" }, + { url = "https://files.pythonhosted.org/packages/38/b0/6cd2bb0509ac0b51af4bb138e145b7c4c902bb4b724d6fd143689d6e0383/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:84e0566f15cf4d769dade9b366b7b87c959be472c92dffb70462dd0844d7cbad", size = 567622, upload-time = "2025-03-26T14:54:02.312Z" }, + { url = "https://files.pythonhosted.org/packages/64/b0/c401f4f077547d98e8b4c2ec6526a80e7cb04f519d416430ec1421ee9e0b/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:823e74ab6fbaa028ec89615ff6acb409e90ff45580c45920d4dfdddb069f2120", size = 595435, upload-time = "2025-03-26T14:54:04.388Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ec/7993b6e803294c87b61c85bd63e11142ccfb2373cf88a61ec602abcbf9d6/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c61a2cb0085c8783906b2f8b1f16a7e65777823c7f4d0a6aaffe26dc0d358dd9", size = 563762, upload-time = "2025-03-26T14:54:06.422Z" }, + { url = "https://files.pythonhosted.org/packages/1f/29/4508003204cb2f461dc2b83dd85f8aa2b915bc98fe6046b9d50d4aa05401/rpds_py-0.24.0-cp313-cp313-win32.whl", hash = "sha256:60d9b630c8025b9458a9d114e3af579a2c54bd32df601c4581bd054e85258143", size = 223510, upload-time = "2025-03-26T14:54:08.344Z" }, + { url = "https://files.pythonhosted.org/packages/f9/12/09e048d1814195e01f354155fb772fb0854bd3450b5f5a82224b3a319f0e/rpds_py-0.24.0-cp313-cp313-win_amd64.whl", hash = "sha256:6eea559077d29486c68218178ea946263b87f1c41ae7f996b1f30a983c476a5a", size = 239075, upload-time = "2025-03-26T14:54:09.992Z" }, + { url = "https://files.pythonhosted.org/packages/d2/03/5027cde39bb2408d61e4dd0cf81f815949bb629932a6c8df1701d0257fc4/rpds_py-0.24.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:d09dc82af2d3c17e7dd17120b202a79b578d79f2b5424bda209d9966efeed114", size = 362974, upload-time = "2025-03-26T14:54:11.484Z" }, + { url = "https://files.pythonhosted.org/packages/bf/10/24d374a2131b1ffafb783e436e770e42dfdb74b69a2cd25eba8c8b29d861/rpds_py-0.24.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5fc13b44de6419d1e7a7e592a4885b323fbc2f46e1f22151e3a8ed3b8b920405", size = 348730, upload-time = "2025-03-26T14:54:13.145Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d1/1ef88d0516d46cd8df12e5916966dbf716d5ec79b265eda56ba1b173398c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c347a20d79cedc0a7bd51c4d4b7dbc613ca4e65a756b5c3e57ec84bd43505b47", size = 387627, upload-time = "2025-03-26T14:54:14.711Z" }, + { url = "https://files.pythonhosted.org/packages/4e/35/07339051b8b901ecefd449ebf8e5522e92bcb95e1078818cbfd9db8e573c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20f2712bd1cc26a3cc16c5a1bfee9ed1abc33d4cdf1aabd297fe0eb724df4272", size = 394094, upload-time = "2025-03-26T14:54:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/ee89ece19e0ba322b08734e95441952062391065c157bbd4f8802316b4f1/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad911555286884be1e427ef0dc0ba3929e6821cbeca2194b13dc415a462c7fd", size = 449639, upload-time = "2025-03-26T14:54:19.047Z" }, + { url = "https://files.pythonhosted.org/packages/15/24/b30e9f9e71baa0b9dada3a4ab43d567c6b04a36d1cb531045f7a8a0a7439/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0aeb3329c1721c43c58cae274d7d2ca85c1690d89485d9c63a006cb79a85771a", size = 438584, upload-time = "2025-03-26T14:54:20.722Z" }, + { url = "https://files.pythonhosted.org/packages/28/d9/49f7b8f3b4147db13961e19d5e30077cd0854ccc08487026d2cb2142aa4a/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a0f156e9509cee987283abd2296ec816225145a13ed0391df8f71bf1d789e2d", size = 391047, upload-time = "2025-03-26T14:54:22.426Z" }, + { url = "https://files.pythonhosted.org/packages/49/b0/e66918d0972c33a259ba3cd7b7ff10ed8bd91dbcfcbec6367b21f026db75/rpds_py-0.24.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa6800adc8204ce898c8a424303969b7aa6a5e4ad2789c13f8648739830323b7", size = 418085, upload-time = "2025-03-26T14:54:23.949Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6b/99ed7ea0a94c7ae5520a21be77a82306aac9e4e715d4435076ead07d05c6/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a18fc371e900a21d7392517c6f60fe859e802547309e94313cd8181ad9db004d", size = 564498, upload-time = "2025-03-26T14:54:25.573Z" }, + { url = "https://files.pythonhosted.org/packages/28/26/1cacfee6b800e6fb5f91acecc2e52f17dbf8b0796a7c984b4568b6d70e38/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9168764133fd919f8dcca2ead66de0105f4ef5659cbb4fa044f7014bed9a1797", size = 590202, upload-time = "2025-03-26T14:54:27.569Z" }, + { url = "https://files.pythonhosted.org/packages/a9/9e/57bd2f9fba04a37cef673f9a66b11ca8c43ccdd50d386c455cd4380fe461/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f6e3cec44ba05ee5cbdebe92d052f69b63ae792e7d05f1020ac5e964394080c", size = 561771, upload-time = "2025-03-26T14:54:29.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cf/b719120f375ab970d1c297dbf8de1e3c9edd26fe92c0ed7178dd94b45992/rpds_py-0.24.0-cp313-cp313t-win32.whl", hash = "sha256:8ebc7e65ca4b111d928b669713865f021b7773350eeac4a31d3e70144297baba", size = 221195, upload-time = "2025-03-26T14:54:31.581Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e5/22865285789f3412ad0c3d7ec4dc0a3e86483b794be8a5d9ed5a19390900/rpds_py-0.24.0-cp313-cp313t-win_amd64.whl", hash = "sha256:675269d407a257b8c00a6b58205b72eec8231656506c56fd429d924ca00bb350", size = 237354, upload-time = "2025-03-26T14:54:33.199Z" }, ] [[package]] @@ -954,18 +954,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/aa/65/7d973b89c4d2351d7fb232c2e452547ddfa243e93131e7cfa766da627b52/rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21", size = 29711 } +sdist = { url = "https://files.pythonhosted.org/packages/aa/65/7d973b89c4d2351d7fb232c2e452547ddfa243e93131e7cfa766da627b52/rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21", size = 29711, upload-time = "2022-07-20T10:28:36.115Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/49/97/fa78e3d2f65c02c8e1268b9aba606569fe97f6c8f7c2d74394553347c145/rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", size = 34315 }, + { url = "https://files.pythonhosted.org/packages/49/97/fa78e3d2f65c02c8e1268b9aba606569fe97f6c8f7c2d74394553347c145/rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", size = 34315, upload-time = "2022-07-20T10:28:34.978Z" }, ] [[package]] name = "rules" version = "3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/36/918cf4cc9fd0e38bb9310b2d1a13ae6ebb2b5732d56e7de6feb4a992a6ed/rules-3.5.tar.gz", hash = "sha256:f01336218f4561bab95f53672d22418b4168baea271423d50d9e8490d64cb27a", size = 55504 } +sdist = { url = "https://files.pythonhosted.org/packages/f7/36/918cf4cc9fd0e38bb9310b2d1a13ae6ebb2b5732d56e7de6feb4a992a6ed/rules-3.5.tar.gz", hash = "sha256:f01336218f4561bab95f53672d22418b4168baea271423d50d9e8490d64cb27a", size = 55504, upload-time = "2024-09-02T16:01:46.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/33/16213dd62ca8ce8749985318a966ac1300ab55c977b2d66632a45b405c99/rules-3.5-py2.py3-none-any.whl", hash = "sha256:0f00fc9ee448b3f82e9aff9334ab0c56c76dce4dfa14f1598f57969f1022acc0", size = 25658 }, + { url = "https://files.pythonhosted.org/packages/ea/33/16213dd62ca8ce8749985318a966ac1300ab55c977b2d66632a45b405c99/rules-3.5-py2.py3-none-any.whl", hash = "sha256:0f00fc9ee448b3f82e9aff9334ab0c56c76dce4dfa14f1598f57969f1022acc0", size = 25658, upload-time = "2024-09-02T16:01:44.844Z" }, ] [[package]] @@ -1009,7 +1009,7 @@ dev = [ requires-dist = [ { name = "argon2-cffi", specifier = ">=23.1.0" }, { name = "cryptography", specifier = ">=44.0.2" }, - { name = "django", specifier = "==5.2b1" }, + { name = "django", specifier = "==5.2" }, { name = "django-allauth", specifier = ">=65.5.0" }, { name = "django-fernet-encrypted-fields", specifier = ">=0.3.0" }, { name = "django-scopes", specifier = ">=2.0.0" }, @@ -1043,27 +1043,27 @@ dev = [ name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sqlparse" version = "0.5.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999 } +sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999, upload-time = "2024-12-10T12:05:30.728Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415 }, + { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" }, ] [[package]] name = "toml" version = "0.10.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253 } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 }, + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, ] [[package]] @@ -1073,52 +1073,52 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 } +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, ] [[package]] name = "typing-extensions" version = "4.13.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0e/3e/b00a62db91a83fff600de219b6ea9908e6918664899a2d85db222f4fbf19/typing_extensions-4.13.0.tar.gz", hash = "sha256:0a4ac55a5820789d87e297727d229866c9650f6521b64206413c4fbada24d95b", size = 106520 } +sdist = { url = "https://files.pythonhosted.org/packages/0e/3e/b00a62db91a83fff600de219b6ea9908e6918664899a2d85db222f4fbf19/typing_extensions-4.13.0.tar.gz", hash = "sha256:0a4ac55a5820789d87e297727d229866c9650f6521b64206413c4fbada24d95b", size = 106520, upload-time = "2025-03-26T03:49:41.628Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/86/39b65d676ec5732de17b7e3c476e45bb80ec64eb50737a8dce1a4178aba1/typing_extensions-4.13.0-py3-none-any.whl", hash = "sha256:c8dd92cc0d6425a97c18fbb9d1954e5ff92c1ca881a309c45f06ebc0b79058e5", size = 45683 }, + { url = "https://files.pythonhosted.org/packages/e0/86/39b65d676ec5732de17b7e3c476e45bb80ec64eb50737a8dce1a4178aba1/typing_extensions-4.13.0-py3-none-any.whl", hash = "sha256:c8dd92cc0d6425a97c18fbb9d1954e5ff92c1ca881a309c45f06ebc0b79058e5", size = 45683, upload-time = "2025-03-26T03:49:40.35Z" }, ] [[package]] name = "tzdata" version = "2025.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 } +sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950, upload-time = "2025-01-21T19:49:38.686Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 }, + { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762, upload-time = "2025-01-21T19:49:37.187Z" }, ] [[package]] name = "urllib3" version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268, upload-time = "2024-12-22T07:47:30.032Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369, upload-time = "2024-12-22T07:47:28.074Z" }, ] [[package]] name = "urlman" version = "2.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/c3/cc163cadf40a03d23d522d050ffa147c0589ccd7992a2cc4dd2b02aa9886/urlman-2.0.2.tar.gz", hash = "sha256:231afe89d0d0db358fe7a2626eb39310e5bf5911f3796318955cbe77e1b39601", size = 7684 } +sdist = { url = "https://files.pythonhosted.org/packages/65/c3/cc163cadf40a03d23d522d050ffa147c0589ccd7992a2cc4dd2b02aa9886/urlman-2.0.2.tar.gz", hash = "sha256:231afe89d0d0db358fe7a2626eb39310e5bf5911f3796318955cbe77e1b39601", size = 7684, upload-time = "2024-05-21T15:03:55.951Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/0c/e8a418c9bc9349e7869e88a5b439cf39c4f6f8942da858000944c94a8f01/urlman-2.0.2-py2.py3-none-any.whl", hash = "sha256:2505bf310be424ffa6f4965a6f643ce32dc6194f61a3c5989f2f56453c614814", size = 8028 }, + { url = "https://files.pythonhosted.org/packages/f4/0c/e8a418c9bc9349e7869e88a5b439cf39c4f6f8942da858000944c94a8f01/urlman-2.0.2-py2.py3-none-any.whl", hash = "sha256:2505bf310be424ffa6f4965a6f643ce32dc6194f61a3c5989f2f56453c614814", size = 8028, upload-time = "2024-05-21T15:03:54.858Z" }, ] [[package]] name = "websocket-client" version = "1.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, ] From 4d1215f976109f5ad31b73aa294a61aedc14bbd4 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Mon, 19 May 2025 16:04:43 +0200 Subject: [PATCH 21/82] Fix the creation of Forgejo service instances closes #43 --- src/servala/core/models/service.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index baca840..c38cac0 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -369,10 +369,7 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): @cached_property def kind_plural(self): - plural = self.kind.lower() - if not plural.endswith("s"): - plural = f"{plural}s" - return plural + return self.resource_definition.status.accepted_names.plural @cached_property def resource_definition(self): From 9830eebcdae7d208c5ddece7c4ace275a1cd56a9 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:22:17 +0200 Subject: [PATCH 22/82] Build custom object instantiation --- src/servala/core/crd.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/servala/core/crd.py b/src/servala/core/crd.py index 2c2b9fb..173b26c 100644 --- a/src/servala/core/crd.py +++ b/src/servala/core/crd.py @@ -9,6 +9,18 @@ from django.utils.translation import gettext_lazy as _ from servala.core.models import ServiceInstance +class CRDModel(models.Model): + """Base class for all virtual CRD models""" + + def __init__(self, **kwargs): + if spec := kwargs.pop("spec", None): + kwargs.update(unnest_data({"spec": spec})) + super().__init__(**kwargs) + + class Meta: + abstract = True + + def duplicate_field(field_name, model): # Get the field from the model field = model._meta.get_field(field_name) @@ -47,7 +59,7 @@ def generate_django_model(schema, group, version, kind): # create the model class model_name = kind - model_class = type(model_name, (models.Model,), model_fields) + model_class = type(model_name, (CRDModel,), model_fields) return model_class @@ -138,6 +150,21 @@ def get_django_field( return models.CharField(max_length=255, **kwargs) +def unnest_data(data): + result = {} + + def _flatten_dict(d, parent_key=""): + for key, value in d.items(): + new_key = f"{parent_key}.{key}" if parent_key else key + if isinstance(value, dict): + _flatten_dict(value, new_key) + else: + result[new_key] = value + + _flatten_dict(data) + return result + + class CrdModelFormMixin: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) From f65e6e0de0c10615c282c7bab2f14d4fc937bff2 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:24:18 +0200 Subject: [PATCH 23/82] Implement model updates --- src/servala/core/models/service.py | 48 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index c38cac0..dab18db 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -188,6 +188,10 @@ class ControlPlane(ServalaModelMixin, models.Model): def get_kubernetes_client(self): return kubernetes.client.ApiClient(self.kubernetes_config) + @cached_property + def custom_objects_api(self): + return client.CustomObjectsApi(self.get_kubernetes_client()) + def test_connection(self): if not self.api_credentials: return False, _("No API credentials provided") @@ -540,9 +544,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): } if label := context.control_plane.required_label: create_data["metadata"]["labels"] = {settings.DEFAULT_LABEL_KEY: label} - api_instance = client.CustomObjectsApi( - context.control_plane.get_kubernetes_client() - ) + api_instance = context.control_plane.custom_objects_api api_instance.create_namespaced_custom_object( group=context.group, version=context.version, @@ -562,6 +564,46 @@ class ServiceInstance(ServalaModelMixin, models.Model): raise ValidationError(_("Error creating instance: {}").format(str(e))) return instance + def update_spec(self, spec_data, updated_by): + try: + api_instance = self.context.control_plane.custom_objects_api + patch_body = {"spec": spec_data} + + api_instance.patch_namespaced_custom_object( + group=self.context.group, + version=self.context.version, + namespace=self.organization.namespace, + plural=self.context.kind_plural, + name=self.name, + body=patch_body, + ) + self._clear_kubernetes_caches() + except ApiException as e: + if e.status == 404: + raise ValidationError( + _( + "Service instance not found in Kubernetes. It may have been deleted externally." + ) + ) + try: + error_body = json.loads(e.body) + reason = error_body.get("message", str(e)) + raise ValidationError( + _("Kubernetes API error updating instance: {error}").format( + error=reason + ) + ) + except (ValueError, TypeError): + raise ValidationError( + _("Kubernetes API error updating instance: {error}").format( + error=str(e) + ) + ) + except Exception as e: + raise ValidationError( + _("Error updating instance: {error}").format(error=str(e)) + ) + @cached_property def kubernetes_object(self): """Fetch the Kubernetes custom resource object""" From 857105b01f39e32c084bee390d91eefabf8faa5a Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:24:25 +0200 Subject: [PATCH 24/82] Implement cache invalidation --- src/servala/core/models/service.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index dab18db..f32d5ca 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -513,6 +513,19 @@ class ServiceInstance(ServalaModelMixin, models.Model): class urls(urlman.Urls): base = "{self.organization.urls.instances}{self.name}/" + update = "{base}update/" + + def _clear_kubernetes_caches(self): + """Clears cached properties that depend on Kubernetes state.""" + attrs = self.__dict__.keys() + if "kubernetes_object" in attrs: + del self.kubernetes_object + if "spec" in attrs: + del self.spec + if "status_conditions" in attrs: + del self.status_conditions + if "connection_credentials" in attrs: + del self.connection_credentials @classmethod def create_instance(cls, name, organization, context, created_by, spec_data): From 51bcd620e18a2bdcdb8531b7161879b0c6179822 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:25:09 +0200 Subject: [PATCH 25/82] Improve error on viewing remotely-deleted instance --- src/servala/frontend/urls.py | 5 +++++ src/servala/frontend/views/__init__.py | 2 ++ src/servala/frontend/views/service.py | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/servala/frontend/urls.py b/src/servala/frontend/urls.py index 2838dae..64c84bf 100644 --- a/src/servala/frontend/urls.py +++ b/src/servala/frontend/urls.py @@ -50,6 +50,11 @@ urlpatterns = [ views.ServiceInstanceDetailView.as_view(), name="organization.instance", ), + path( + "instances//update/", + views.ServiceInstanceUpdateView.as_view(), + name="organization.instance.update", + ), ] ), ), diff --git a/src/servala/frontend/views/__init__.py b/src/servala/frontend/views/__init__.py index 5de38ee..d13d4d5 100644 --- a/src/servala/frontend/views/__init__.py +++ b/src/servala/frontend/views/__init__.py @@ -9,6 +9,7 @@ from .service import ( ServiceDetailView, ServiceInstanceDetailView, ServiceInstanceListView, + ServiceInstanceUpdateView, ServiceListView, ServiceOfferingDetailView, ) @@ -22,6 +23,7 @@ __all__ = [ "ServiceDetailView", "ServiceInstanceDetailView", "ServiceInstanceListView", + "ServiceInstanceUpdateView", "ServiceListView", "ServiceOfferingDetailView", "ProfileView", diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index b6ecc42..ab4fa0e 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -2,6 +2,7 @@ from django.contrib import messages from django.core.exceptions import ValidationError from django.shortcuts import redirect from django.utils.functional import cached_property +from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from servala.core.crd import deslugify @@ -105,6 +106,8 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView ).first() def get_instance_form(self): + if not self.context_object: + return None return self.context_object.model_form_class( data=self.request.POST if self.request.method == "POST" else None, initial={ @@ -130,6 +133,10 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView return self.render_to_response(context) form = self.get_instance_form() + if not form: # Should not happen if context_object is valid, but as a safeguard + messages.error(self.request, _("Could not initialize service form.")) + return self.render_to_response(context) + if form.is_valid(): try: service_instance = ServiceInstance.create_instance( @@ -143,7 +150,9 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView except ValidationError as e: messages.error(self.request, e.message or str(e)) except Exception as e: - messages.error(self.request, str(e)) + messages.error( + self.request, _("Error creating instance: {}").format(str(e)) + ) # If the form is not valid or if the service creation failed, we render it again context["service_form"] = form From f464483c7a1177c3a6c992f93b42b74a0b086fb6 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:37:57 +0200 Subject: [PATCH 26/82] Make sure update timestamp is set --- src/servala/core/models/service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index f32d5ca..6637b85 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -591,6 +591,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): body=patch_body, ) self._clear_kubernetes_caches() + self.save() # Updates updated_at timestamp except ApiException as e: if e.status == 404: raise ValidationError( From 032596c0e4abf41b7cad4233089b59cad9fd7850 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:39:32 +0200 Subject: [PATCH 27/82] Refactor common view functionality into mixin --- src/servala/frontend/views/service.py | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index ab4fa0e..1ee46b4 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -159,15 +159,15 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView return self.render_to_response(context) -class ServiceInstanceDetailView(OrganizationViewMixin, DetailView): - """View to display details of a specific service instance.""" - - template_name = "frontend/organizations/service_instance_detail.html" - context_object_name = "instance" +class ServiceInstanceMixin: model = ServiceInstance - permission_type = "view" + context_object_name = "instance" slug_field = "name" + def dispatch(self, *args, **kwargs): + self._has_warned = False + return super().dispatch(*args, **kwargs) + def get_queryset(self): """Return service instance for the current organization.""" return ServiceInstance.objects.filter( @@ -178,6 +178,35 @@ class ServiceInstanceDetailView(OrganizationViewMixin, DetailView): "context__service_definition__service", ) + def get_object(self, **kwargs): + instance = super().get_object(**kwargs) + if ( + not instance.kubernetes_object + and not instance.is_deleted + and not self._has_warned + ): + messages.warning( + self.request, + _( + "Could not retrieve instance details from Kubernetes. It might have been deleted externally." + ), + ) + self._has_warned = True + return instance + + +class ServiceInstanceDetailView( + ServiceInstanceMixin, OrganizationViewMixin, DetailView +): + template_name = "frontend/organizations/service_instance_detail.html" + permission_type = "view" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + if self.object.kubernetes_object and self.object.spec: + context["spec_fieldsets"] = self.get_nested_spec() + return context + def get_nested_spec(self): """ Organize spec data into fieldsets similar to how the form does it. From 8a67e16a0b3ffb75b992ffa1c24f524266a088d4 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:15:19 +0200 Subject: [PATCH 28/82] =?UTF-8?q?Do=20not=20allow=20the=20instance?= =?UTF-8?q?=E2=80=99s=20name=20to=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/servala/core/crd.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/servala/core/crd.py b/src/servala/core/crd.py index 173b26c..f356c7b 100644 --- a/src/servala/core/crd.py +++ b/src/servala/core/crd.py @@ -173,6 +173,11 @@ class CrdModelFormMixin: for field in ("organization", "context"): self.fields[field].widget = forms.HiddenInput() + if self.instance and self.instance.pk: + self.fields["name"].disabled = True + self.fields["name"].help_text = _("Name cannot be changed after creation.") + self.fields["name"].widget = forms.HiddenInput() + def strip_title(self, field_name, label): field = self.fields[field_name] if field and field.label.startswith(label): @@ -183,7 +188,10 @@ class CrdModelFormMixin: # General fieldset for non-spec fields general_fields = [ - field for field in self.fields if not field.startswith("spec.") + field_name + for field_name, field in self.fields.items() + if not field_name.startswith("spec.") + and not isinstance(field.widget, forms.HiddenInput) ] if general_fields: fieldsets.append( From ba30fb0402d9994aa66fce0d5ae8069d159b68db Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:16:43 +0200 Subject: [PATCH 29/82] Improve cached data deletion --- src/servala/core/models/service.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 6637b85..fd082ce 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -518,14 +518,14 @@ class ServiceInstance(ServalaModelMixin, models.Model): def _clear_kubernetes_caches(self): """Clears cached properties that depend on Kubernetes state.""" attrs = self.__dict__.keys() - if "kubernetes_object" in attrs: - del self.kubernetes_object - if "spec" in attrs: - del self.spec - if "status_conditions" in attrs: - del self.status_conditions - if "connection_credentials" in attrs: - del self.connection_credentials + for key in ( + "kubernetes_object", + "spec", + "status_conditions", + "connection_credentials", + ): + if key in attrs: + delattr(self, key) @classmethod def create_instance(cls, name, organization, context, created_by, spec_data): From fd3cb6a1d4ec4b7ab8965fcd128755da26288f62 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:17:09 +0200 Subject: [PATCH 30/82] Instantiate dynamic model from instance --- src/servala/core/models/service.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index fd082ce..901a822 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -651,6 +651,20 @@ class ServiceInstance(ServalaModelMixin, models.Model): spec.pop("writeConnectionSecretToRef", None) return spec + @cached_property + def spec_object(self): + """Dynamically generated CRD object.""" + return self.context.django_model( + name=self.name, + organization=self.organization, + context=self.context, + spec=self.spec, + # We pass -1 as ID in order to make it clear that a) this object exists (remotely), + # and b) it’s not a normal database object. This allows us to treat e.g. update + # forms differently from create forms. + pk=-1, + ) + @cached_property def status_conditions(self): if not self.kubernetes_object: From eb4d3f95563ab1d26db154693ee51d66ce54c32b Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:19:31 +0200 Subject: [PATCH 31/82] Implement service instance update --- .../service_instance_update.html | 39 +++++++++++++ src/servala/frontend/views/service.py | 56 ++++++++++++++++--- 2 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 src/servala/frontend/templates/frontend/organizations/service_instance_update.html diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html new file mode 100644 index 0000000..cbfbd6f --- /dev/null +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html @@ -0,0 +1,39 @@ +{% extends "frontend/base.html" %} +{% load i18n %} +{% load static %} +{% load partials %} +{% block html_title %} + {% block page_title %} + {% block title %} + {% blocktranslate with instance_name=instance.name organization_name=request.organization.name %}Update {{ instance_name }} in {{ organization_name }}{% endblocktranslate %} + {% endblock %} + {% endblock page_title %} +{% endblock html_title %} +{% partialdef service-form %} +{% if form %} +
+
+
+ {% if form_error %} +
+ {% translate "Oops! Something went wrong with the service form generation. Please try again later." %} +
+ {% else %} + {% include "includes/tabbed_fieldset_form.html" with form=form %} + {% endif %} +
+
+{% endif %} +{% endpartialdef %} +{% block content %} +
+
+ {% if not form %} + + {% else %} +
{% partial service-form %}
+ {% endif %} +
+ {% endblock %} diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 1ee46b4..0a0fe10 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -17,7 +17,11 @@ from servala.frontend.forms.service import ( ServiceFilterForm, ServiceInstanceFilterForm, ) -from servala.frontend.views.mixins import HtmxViewMixin, OrganizationViewMixin +from servala.frontend.views.mixins import ( + HtmxUpdateView, + HtmxViewMixin, + OrganizationViewMixin, +) class ServiceListView(OrganizationViewMixin, ListView): @@ -310,12 +314,43 @@ class ServiceInstanceDetailView( return fieldsets - def get_context_data(self, **kwargs): - """Return service instance for the current organization.""" - context = super().get_context_data(**kwargs) - if self.object.spec: - context["spec_fieldsets"] = self.get_nested_spec() - return context + +class ServiceInstanceUpdateView( + ServiceInstanceMixin, OrganizationViewMixin, HtmxUpdateView +): + template_name = "frontend/organizations/service_instance_update.html" + permission_type = "change" + + def get_form_class(self): + return self.object.context.model_form_class + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs["instance"] = self.object.spec_object + return kwargs + + def form_valid(self, form): + try: + spec_data = form.get_nested_data().get("spec") + self.object.update_spec(spec_data=spec_data, updated_by=self.request.user) + messages.success( + self.request, + _("Service instance '{name}' updated successfully.").format( + name=self.object.name + ), + ) + return redirect(self.object.urls.base) + except ValidationError as e: + messages.error(self.request, e.message or str(e)) + return self.form_invalid(form) + except Exception as e: + messages.error( + self.request, _("Error updating instance: {error}").format(error=str(e)) + ) + return self.form_invalid(form) + + def get_success_url(self): + return self.object.urls.base class ServiceInstanceListView(OrganizationViewMixin, ListView): @@ -331,7 +366,12 @@ class ServiceInstanceListView(OrganizationViewMixin, ListView): def get_queryset(self): """Return all service instances for the current organization with filtering.""" queryset = ServiceInstance.objects.filter( - organization=self.request.organization + organization=self.request.organization, + is_deleted=False, # Exclude soft-deleted + ).select_related( + "context__service_offering__provider", + "context__control_plane", + "context__service_definition__service", ) if self.filter_form.is_valid(): queryset = self.filter_form.filter_queryset(queryset) From 4bb52cda4fc99a49125a4a609dbce8362ded8037 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:29:28 +0200 Subject: [PATCH 32/82] Add links between detail and update page --- src/servala/frontend/templates/frontend/base.html | 10 +++++++--- .../organizations/service_instance_detail.html | 5 +++++ .../organizations/service_instance_update.html | 3 +++ src/servala/frontend/views/service.py | 4 ++++ src/servala/static/css/servala.css | 5 +++++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/servala/frontend/templates/frontend/base.html b/src/servala/frontend/templates/frontend/base.html index f5ce6dd..89d363f 100644 --- a/src/servala/frontend/templates/frontend/base.html +++ b/src/servala/frontend/templates/frontend/base.html @@ -25,9 +25,13 @@

- {% block page_title %} - Dashboard - {% endblock page_title %} + + {% block page_title %} + Dashboard + {% endblock page_title %} + + {% block page_title_extra %} + {% endblock page_title_extra %}

diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index b9cf4dc..973d2f1 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -5,6 +5,11 @@ {{ instance.name }} {% endblock page_title %} {% endblock html_title %} +{% block page_title_extra %} + {% if has_change_permission %} + {% translate "Edit" %} + {% endif %} +{% endblock page_title_extra %} {% block content %}
diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html index cbfbd6f..fa7f502 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html @@ -9,6 +9,9 @@ {% endblock %} {% endblock page_title %} {% endblock html_title %} +{% block page_title_extra %} + {% translate "Back" %} +{% endblock page_title_extra %} {% partialdef service-form %} {% if form %}
diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 0a0fe10..298d5bc 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -209,6 +209,10 @@ class ServiceInstanceDetailView( context = super().get_context_data(**kwargs) if self.object.kubernetes_object and self.object.spec: context["spec_fieldsets"] = self.get_nested_spec() + permission_required = ServiceInstance.get_perm("change") + context["has_change_permission"] = self.request.user.has_perm( + permission_required, self.object + ) return context def get_nested_spec(self): diff --git a/src/servala/static/css/servala.css b/src/servala/static/css/servala.css index e2eb044..e607205 100644 --- a/src/servala/static/css/servala.css +++ b/src/servala/static/css/servala.css @@ -85,3 +85,8 @@ html[data-bs-theme="dark"] .btn-outline-primary, .btn-outline-primary { a.btn-keycloak { display: inline-flex; } +.page-heading h3 { + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} From 83b44fd262c31bfb39f6f31bb7a07ebd5878bb12 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:31:25 +0200 Subject: [PATCH 33/82] Fix missing closing tag --- .../frontend/organizations/service_instance_update.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html index fa7f502..51a9213 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html @@ -38,5 +38,6 @@ {% else %}
{% partial service-form %}
{% endif %} -
- {% endblock %} +
+
+{% endblock content %} From c5702753872c361fd480fb2703dafb3edd5b37c5 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 16:39:31 +0200 Subject: [PATCH 34/82] Add and configure django-storages --- .env.example | 11 +++++++++++ pyproject.toml | 1 + src/servala/settings.py | 33 +++++++++++++++++++++++++++++++++ uv.lock | 14 ++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/.env.example b/.env.example index 829b56e..13c1e64 100644 --- a/.env.example +++ b/.env.example @@ -47,3 +47,14 @@ SERVALA_DEFAULT_ORIGIN='1' SERVALA_KEYCLOAK_CLIENT_ID='portal.servala.com' SERVALA_KEYCLOAK_CLIENT_SECRET='' SERVALA_KEYCLOAK_SERVER_URL='' + +# S3 Storage settings (optional, for using S3 compatible storage for media files) +# If these are set, Django will use S3 for default file storage. +# Defaults are indicated if any. +# SERVALA_STORAGE_BUCKET_NAME='' +# SERVALA_S3_ENDPOINT_URL='' +# SERVALA_ACCESS_KEY_ID='' +# SERVALA_SECRET_ACCESS_KEY='' +# SERVALA_S3_REGION_NAME='eu-central-1' +# SERVALA_S3_ADDRESSING_STYLE='virtual' +# SERVALA_S3_SIGNATURE_VERSION='s3v4' diff --git a/pyproject.toml b/pyproject.toml index c8d634f..740bb70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ dependencies = [ "django-allauth>=65.5.0", "django-fernet-encrypted-fields>=0.3.0", "django-scopes>=2.0.0", + "django-storages>=1.14.6", "django-template-partials>=24.4", "jsonschema>=4.23.0", "kubernetes>=32.0.1", diff --git a/src/servala/settings.py b/src/servala/settings.py index 50b0c5e..c5905c2 100644 --- a/src/servala/settings.py +++ b/src/servala/settings.py @@ -87,6 +87,39 @@ SOCIALACCOUNT_PROVIDERS = { } } + +SERVALA_STORAGE_BUCKET_NAME = os.environ.get("SERVALA_STORAGE_BUCKET_NAME") +SERVALA_S3_ENDPOINT_URL = os.environ.get("SERVALA_S3_ENDPOINT_URL") +SERVALA_ACCESS_KEY_ID = os.environ.get("SERVALA_ACCESS_KEY_ID") +SERVALA_SECRET_ACCESS_KEY = os.environ.get("SERVALA_SECRET_ACCESS_KEY") +SERVALA_S3_REGION_NAME = os.environ.get("SERVALA_S3_REGION_NAME", "eu-central-1") +SERVALA_S3_ADDRESSING_STYLE = os.environ.get("SERVALA_S3_ADDRESSING_STYLE", "virtual") +SERVALA_S3_SIGNATURE_VERSION = os.environ.get("SERVALA_S3_SIGNATURE_VERSION", "s3v4") + +# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html +if all( + [ + SERVALA_STORAGE_BUCKET_NAME, + SERVALA_S3_ENDPOINT_URL, + SERVALA_ACCESS_KEY_ID, + SERVALA_SECRET_ACCESS_KEY, + ] +): + STORAGES = { + "default": { + "BACKEND": "storages.backends.s3.S3Storage", + "OPTIONS": { + "bucket_name": SERVALA_STORAGE_BUCKET_NAME, + "endpoint_url": SERVALA_S3_ENDPOINT_URL, + "access_key": SERVALA_ACCESS_KEY_ID, + "secret_key": SERVALA_SECRET_ACCESS_KEY, + "region_name": SERVALA_S3_REGION_NAME, + "addressing_style": SERVALA_S3_ADDRESSING_STYLE, + "signature_version": SERVALA_S3_SIGNATURE_VERSION, + }, + } + } + ####################################### # Non-configurable settings below # ####################################### diff --git a/uv.lock b/uv.lock index 461187f..f2e6662 100644 --- a/uv.lock +++ b/uv.lock @@ -336,6 +336,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/3d/94d82839c111a36145b5ec1fb407a85f9a460af5974a07f4c6d3cc414358/django_scopes-2.0.0-py3-none-any.whl", hash = "sha256:9cf521b4d543ffa2ff6369fb5a1dda03567e862ba89626c01405f3d93ca04724", size = 16660, upload-time = "2023-04-22T17:08:45.058Z" }, ] +[[package]] +name = "django-storages" +version = "1.14.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/d6/2e50e378fff0408d558f36c4acffc090f9a641fd6e084af9e54d45307efa/django_storages-1.14.6.tar.gz", hash = "sha256:7a25ce8f4214f69ac9c7ce87e2603887f7ae99326c316bc8d2d75375e09341c9", size = 87587, upload-time = "2025-04-02T02:34:55.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/21/3cedee63417bc5553eed0c204be478071c9ab208e5e259e97287590194f1/django_storages-1.14.6-py3-none-any.whl", hash = "sha256:11b7b6200e1cb5ffcd9962bd3673a39c7d6a6109e8096f0e03d46fab3d3aabd9", size = 33095, upload-time = "2025-04-02T02:34:53.291Z" }, +] + [[package]] name = "django-template-partials" version = "24.4" @@ -979,6 +991,7 @@ dependencies = [ { name = "django-allauth" }, { name = "django-fernet-encrypted-fields" }, { name = "django-scopes" }, + { name = "django-storages" }, { name = "django-template-partials" }, { name = "jsonschema" }, { name = "kubernetes" }, @@ -1013,6 +1026,7 @@ requires-dist = [ { name = "django-allauth", specifier = ">=65.5.0" }, { name = "django-fernet-encrypted-fields", specifier = ">=0.3.0" }, { name = "django-scopes", specifier = ">=2.0.0" }, + { name = "django-storages", specifier = ">=1.14.6" }, { name = "django-template-partials", specifier = ">=24.4" }, { name = "jsonschema", specifier = ">=4.23.0" }, { name = "kubernetes", specifier = ">=32.0.1" }, From 09ce5406eecdd9326fa7be7d6d1efdfdd25c941b Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 25 May 2025 22:40:01 +0200 Subject: [PATCH 35/82] Implement service instance delete basics --- src/servala/core/models/service.py | 54 ++++++++++++++++- src/servala/frontend/forms/service.py | 32 ++++++++++ .../service_instance_delete_form.html | 0 src/servala/frontend/urls.py | 5 ++ src/servala/frontend/views/__init__.py | 2 + src/servala/frontend/views/service.py | 59 ++++++++++++++++--- 6 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 901a822..20611b2 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -7,6 +7,7 @@ from django.conf import settings from django.core.cache import cache from django.core.exceptions import ValidationError from django.db import IntegrityError, models +from django.utils import timezone from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from encrypted_fields.fields import EncryptedJSONField @@ -373,7 +374,13 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): @cached_property def kind_plural(self): - return self.resource_definition.status.accepted_names.plural + if hasattr(self.resource_definition, 'status') and \ + hasattr(self.resource_definition.status, 'accepted_names') and \ + self.resource_definition.status.accepted_names: + return self.resource_definition.status.accepted_names.plural + if self.kind.endswith("s"): + return self.kind.lower() + return f"{self.kind.lower()}s" @cached_property def resource_definition(self): @@ -399,8 +406,13 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): if result := cache.get(cache_key): return result + if not self.resource_definition: + return + for v in self.resource_definition.spec.versions: if v.name == self.version: + if not v.schema or not v.schema.open_apiv3_schema: + return result = v.schema.open_apiv3_schema.to_dict() timeout_seconds = 60 * 60 * 24 cache.set(cache_key, result, timeout=timeout_seconds) @@ -410,6 +422,9 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): def django_model(self): from servala.core.crd import generate_django_model + if not self.resource_schema: + return + kwargs = { "group": self.group, "version": self.version, @@ -421,6 +436,8 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): def model_form_class(self): from servala.core.crd import generate_model_form_class + if not self.django_model: + return return generate_model_form_class(self.django_model) @@ -514,6 +531,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): class urls(urlman.Urls): base = "{self.organization.urls.instances}{self.name}/" update = "{base}update/" + delete = "{base}delete/" def _clear_kubernetes_caches(self): """Clears cached properties that depend on Kubernetes state.""" @@ -618,9 +636,41 @@ class ServiceInstance(ServalaModelMixin, models.Model): _("Error updating instance: {error}").format(error=str(e)) ) + def delete_instance(self, user): + """ + Soft deletes the instance in Django and initiates deletion of the + corresponding Kubernetes custom resource. + """ + if self.is_deleted: + return + + self.is_deleted = True + self.deleted_at = timezone.now() + self.deleted_by = user + self.save(update_fields=["is_deleted", "deleted_at", "deleted_by", "updated_at"]) + + self._clear_kubernetes_caches() + + try: + api_instance = self.context.control_plane.custom_objects_api + api_instance.delete_namespaced_custom_object( + group=self.context.group, + version=self.context.version, + namespace=self.organization.namespace, + plural=self.context.kind_plural, + name=self.name, + body=client.V1DeleteOptions(), + ) + except ApiException as e: + if e.status != 404: + # 404 is fine, the object was deleted already. + raise + @cached_property def kubernetes_object(self): """Fetch the Kubernetes custom resource object""" + if self.is_deleted: + return try: api_instance = client.CustomObjectsApi( self.context.control_plane.get_kubernetes_client() @@ -654,6 +704,8 @@ class ServiceInstance(ServalaModelMixin, models.Model): @cached_property def spec_object(self): """Dynamically generated CRD object.""" + if not self.context.django_model: + return return self.context.django_model( name=self.name, organization=self.organization, diff --git a/src/servala/frontend/forms/service.py b/src/servala/frontend/forms/service.py index 1b134a2..decb1a0 100644 --- a/src/servala/frontend/forms/service.py +++ b/src/servala/frontend/forms/service.py @@ -86,3 +86,35 @@ class ServiceInstanceFilterForm(forms.Form): else: queryset = queryset.filter(is_deleted=True) return queryset + + +class ServiceInstanceDeleteForm(forms.Form): + name_confirm = forms.CharField( + label=_("Instance Name"), + max_length=63, + widget=forms.TextInput(attrs={"class": "form-control"}), + ) + + def __init__(self, *args, **kwargs): + self.instance_name = kwargs.pop("instance_name", None) + super().__init__(*args, **kwargs) + if self.instance_name: + self.fields["name_confirm"].help_text = _( + "To confirm deletion, please type the instance name: {instance_name}" + ).format(instance_name=self.instance_name) + else: + self.fields["name_confirm"].help_text = _( + "Please type the instance name to confirm deletion." + ) + + def clean_name_confirm(self): + entered_name = self.cleaned_data.get("name_confirm") + if not self.instance_name: + raise ValidationError( + _("Cannot confirm deletion: instance name not provided to form.") + ) + if entered_name != self.instance_name: + raise ValidationError( + _("The entered name does not match the instance name. Deletion not confirmed.") + ) + return entered_name diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html b/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html new file mode 100644 index 0000000..e69de29 diff --git a/src/servala/frontend/urls.py b/src/servala/frontend/urls.py index 64c84bf..6ab6949 100644 --- a/src/servala/frontend/urls.py +++ b/src/servala/frontend/urls.py @@ -55,6 +55,11 @@ urlpatterns = [ views.ServiceInstanceUpdateView.as_view(), name="organization.instance.update", ), + path( + "instances//delete/", + views.ServiceInstanceDeleteView.as_view(), + name="organization.instance.delete", + ), ] ), ), diff --git a/src/servala/frontend/views/__init__.py b/src/servala/frontend/views/__init__.py index d13d4d5..cc43552 100644 --- a/src/servala/frontend/views/__init__.py +++ b/src/servala/frontend/views/__init__.py @@ -7,6 +7,7 @@ from .organization import ( ) from .service import ( ServiceDetailView, + ServiceInstanceDeleteView, ServiceInstanceDetailView, ServiceInstanceListView, ServiceInstanceUpdateView, @@ -21,6 +22,7 @@ __all__ = [ "OrganizationDashboardView", "OrganizationUpdateView", "ServiceDetailView", + "ServiceInstanceDeleteView", "ServiceInstanceDetailView", "ServiceInstanceListView", "ServiceInstanceUpdateView", diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 298d5bc..2d0612b 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -3,7 +3,7 @@ from django.core.exceptions import ValidationError from django.shortcuts import redirect from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ -from django.views.generic import DetailView, ListView +from django.views.generic import DetailView, UpdateView, ListView from servala.core.crd import deslugify from servala.core.models import ( @@ -15,6 +15,7 @@ from servala.core.models import ( from servala.frontend.forms.service import ( ControlPlaneSelectForm, ServiceFilterForm, + ServiceInstanceDeleteForm, ServiceInstanceFilterForm, ) from servala.frontend.views.mixins import ( @@ -144,7 +145,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView if form.is_valid(): try: service_instance = ServiceInstance.create_instance( - organization=self.organization, + organization=self.request.organization, name=form.cleaned_data["name"], context=self.context_object, created_by=request.user, @@ -185,8 +186,8 @@ class ServiceInstanceMixin: def get_object(self, **kwargs): instance = super().get_object(**kwargs) if ( - not instance.kubernetes_object - and not instance.is_deleted + not instance.is_deleted + and not instance.kubernetes_object and not self._has_warned ): messages.warning( @@ -207,11 +208,13 @@ class ServiceInstanceDetailView( def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - if self.object.kubernetes_object and self.object.spec: + if not self.object.is_deleted and self.object.kubernetes_object and self.object.spec: context["spec_fieldsets"] = self.get_nested_spec() - permission_required = ServiceInstance.get_perm("change") context["has_change_permission"] = self.request.user.has_perm( - permission_required, self.object + ServiceInstance.get_perm("change"), self.object + ) + context["has_delete_permission"] = self.request.user.has_perm( + ServiceInstance.get_perm("delete"), self.object ) return context @@ -220,8 +223,9 @@ class ServiceInstanceDetailView( Organize spec data into fieldsets similar to how the form does it. """ spec = self.object.spec or {} + if not spec: + return [] - # Process spec fields others = [] nested_fieldsets = {} @@ -379,10 +383,47 @@ class ServiceInstanceListView(OrganizationViewMixin, ListView): ) if self.filter_form.is_valid(): queryset = self.filter_form.filter_queryset(queryset) - return queryset + status_filter = self.filter_form.cleaned_data.get("status") if self.filter_form.is_valid() else "active" + if status_filter == "active": + queryset = queryset.filter(is_deleted=False) + elif status_filter == "deleted": + queryset = queryset.filter(is_deleted=True) + return queryset.order_by("-created_at") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["organization"] = self.request.organization context["filter_form"] = self.filter_form return context + + +class ServiceInstanceDeleteView( + ServiceInstanceMixin, OrganizationViewMixin, HtmxViewMixin, UpdateView +): + template_name = "frontend/organizations/service_instance_delete_form.html" + form_class = ServiceInstanceDeleteForm + permission_type = "delete" + + def form_valid(self, form): + try: + self.object.delete_instance(user=self.request.user) + messages.success( + self.request, + _("Service instance '{name}' has been scheduled for deletion.").format( + name=self.object.name + ), + ) + response = HttpResponse() + response["HX-Redirect"] = self.get_success_url() + return response + except Exception as e: + messages.error( + self.request, + _("An error occurred while trying to delete instance '{name}': {error}").format( + name=self.object.name, error=str(e) + ), + ) + return self.form_invalid(form) + + def get_success_url(self): + return self.request.organization.urls.instances From 3a8b9987b2d4919236b666324aeed915a43537a0 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 25 May 2025 22:53:22 +0200 Subject: [PATCH 36/82] Improve instance delete --- src/servala/core/models/service.py | 3 +- src/servala/frontend/forms/service.py | 31 ++++++++----------- .../templates/frontend/forms/form.html | 2 +- .../service_instance_detail.html | 30 ++++++++++++++---- src/servala/frontend/views/service.py | 4 ++- src/servala/static/css/servala.css | 3 ++ 6 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 20611b2..4824c47 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -6,7 +6,7 @@ import urlman from django.conf import settings from django.core.cache import cache from django.core.exceptions import ValidationError -from django.db import IntegrityError, models +from django.db import IntegrityError, models, transaction from django.utils import timezone from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ @@ -636,6 +636,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): _("Error updating instance: {error}").format(error=str(e)) ) + @transaction.atomic def delete_instance(self, user): """ Soft deletes the instance in Django and initiates deletion of the diff --git a/src/servala/frontend/forms/service.py b/src/servala/frontend/forms/service.py index decb1a0..09833d9 100644 --- a/src/servala/frontend/forms/service.py +++ b/src/servala/frontend/forms/service.py @@ -88,33 +88,28 @@ class ServiceInstanceFilterForm(forms.Form): return queryset -class ServiceInstanceDeleteForm(forms.Form): - name_confirm = forms.CharField( +class ServiceInstanceDeleteForm(forms.ModelForm): + name = forms.CharField( label=_("Instance Name"), max_length=63, widget=forms.TextInput(attrs={"class": "form-control"}), ) def __init__(self, *args, **kwargs): - self.instance_name = kwargs.pop("instance_name", None) + kwargs["initial"] = {"name": ""} super().__init__(*args, **kwargs) - if self.instance_name: - self.fields["name_confirm"].help_text = _( - "To confirm deletion, please type the instance name: {instance_name}" - ).format(instance_name=self.instance_name) - else: - self.fields["name_confirm"].help_text = _( - "Please type the instance name to confirm deletion." - ) + self.fields["name"].help_text = _( + "To confirm deletion, please type the instance name: {instance_name}" + ).format(instance_name=self.instance.name) - def clean_name_confirm(self): - entered_name = self.cleaned_data.get("name_confirm") - if not self.instance_name: - raise ValidationError( - _("Cannot confirm deletion: instance name not provided to form.") - ) - if entered_name != self.instance_name: + def clean_name(self): + entered_name = self.cleaned_data.get("name") + if entered_name != self.instance.name: raise ValidationError( _("The entered name does not match the instance name. Deletion not confirmed.") ) return entered_name + + class Meta: + model = ServiceInstance + fields = ("name", ) diff --git a/src/servala/frontend/templates/frontend/forms/form.html b/src/servala/frontend/templates/frontend/forms/form.html index b45c41f..8ab90d1 100644 --- a/src/servala/frontend/templates/frontend/forms/form.html +++ b/src/servala/frontend/templates/frontend/forms/form.html @@ -1,6 +1,6 @@ {% load i18n %} {% if form.non_field_errors or form.errors %} - - {% if instance.status_conditions %} + {% if not instance.is_deleted and instance.status_conditions %}
@@ -101,7 +119,7 @@
{% endif %} - {% if instance.spec %} + {% if not instance.is_deleted and instance.spec and spec_fieldsets %}
diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 2d0612b..89b3f3c 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -423,7 +423,9 @@ class ServiceInstanceDeleteView( name=self.object.name, error=str(e) ), ) - return self.form_invalid(form) + response = HttpResponse() + response["HX-Redirect"] = str(self.object.urls.base) + return response def get_success_url(self): return self.request.organization.urls.instances diff --git a/src/servala/static/css/servala.css b/src/servala/static/css/servala.css index e607205..1e418fb 100644 --- a/src/servala/static/css/servala.css +++ b/src/servala/static/css/servala.css @@ -90,3 +90,6 @@ a.btn-keycloak { flex-wrap: wrap; justify-content: space-between; } +.hide-form-errors .alert.form-errors { + display: none; +} From 52aa6acfb63aa706b476201e19cc3fa2a4298f9b Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 25 May 2025 22:54:36 +0200 Subject: [PATCH 37/82] Show instance delete modal --- .../service_instance_delete_form.html | 18 +++++++++++++++ .../service_instance_detail.html | 23 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html b/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html index e69de29..08d4167 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html @@ -0,0 +1,18 @@ +{% load i18n %} +
+ {% csrf_token %} + + + +
diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index f0867c5..5d6779c 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -218,4 +218,27 @@ {% endif %}
+ + + {% endblock content %} From 3e466fb011a94d4348fa7cfd4921b5768c67afed Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 25 May 2025 22:55:37 +0200 Subject: [PATCH 38/82] Instance form and template improvements --- src/servala/core/models/service.py | 12 ++++-- src/servala/frontend/forms/service.py | 29 +++++++++------ .../service_instance_delete_form.html | 11 +++++- .../service_instance_detail.html | 37 ++++++++++++------- src/servala/frontend/views/service.py | 37 +++++++++++++------ 5 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 4824c47..5540d22 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -374,9 +374,11 @@ class ControlPlaneCRD(ServalaModelMixin, models.Model): @cached_property def kind_plural(self): - if hasattr(self.resource_definition, 'status') and \ - hasattr(self.resource_definition.status, 'accepted_names') and \ - self.resource_definition.status.accepted_names: + if ( + hasattr(self.resource_definition, "status") + and hasattr(self.resource_definition.status, "accepted_names") + and self.resource_definition.status.accepted_names + ): return self.resource_definition.status.accepted_names.plural if self.kind.endswith("s"): return self.kind.lower() @@ -648,7 +650,9 @@ class ServiceInstance(ServalaModelMixin, models.Model): self.is_deleted = True self.deleted_at = timezone.now() self.deleted_by = user - self.save(update_fields=["is_deleted", "deleted_at", "deleted_by", "updated_at"]) + self.save( + update_fields=["is_deleted", "deleted_at", "deleted_by", "updated_at"] + ) self._clear_kubernetes_caches() diff --git a/src/servala/frontend/forms/service.py b/src/servala/frontend/forms/service.py index 09833d9..04fe2df 100644 --- a/src/servala/frontend/forms/service.py +++ b/src/servala/frontend/forms/service.py @@ -6,6 +6,7 @@ from servala.core.models import ( ControlPlane, Service, ServiceCategory, + ServiceInstance, ServiceOffering, ) @@ -37,6 +38,8 @@ class ControlPlaneSelectForm(forms.Form): def __init__(self, *args, planes=None, **kwargs): super().__init__(*args, **kwargs) self.fields["control_plane"].queryset = planes + if planes and planes.count() == 1: + self.fields["control_plane"].initial = planes.first() class ServiceInstanceFilterForm(forms.Form): @@ -68,23 +71,23 @@ class ServiceInstanceFilterForm(forms.Form): def filter_queryset(self, queryset): if self.is_valid(): data = self.cleaned_data - if data["name"]: + if data.get("name"): queryset = queryset.filter(name__icontains=data["name"]) - if data["service"]: + if data.get("service"): queryset = queryset.filter( context__service_definition__service=data["service"] ) - if data["provider"]: + if data.get("provider"): queryset = queryset.filter( context__service_offering__provider=data["provider"] ) - if data["control_plane"]: + if data.get("control_plane"): queryset = queryset.filter(context__control_plane=data["control_plane"]) - if data["status"]: - if data["status"] == "active": - queryset = queryset.filter(is_deleted=False) - else: - queryset = queryset.filter(is_deleted=True) + status = data.get("status") + if status == "active": + queryset = queryset.filter(is_deleted=False) + elif status == "deleted": + queryset = queryset.filter(is_deleted=True) return queryset @@ -105,11 +108,13 @@ class ServiceInstanceDeleteForm(forms.ModelForm): def clean_name(self): entered_name = self.cleaned_data.get("name") if entered_name != self.instance.name: - raise ValidationError( - _("The entered name does not match the instance name. Deletion not confirmed.") + raise forms.ValidationError( + _( + "The entered name does not match the instance name. Deletion not confirmed." + ) ) return entered_name class Meta: model = ServiceInstance - fields = ("name", ) + fields = ("name",) diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html b/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html index 08d4167..5296c56 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_delete_form.html @@ -1,11 +1,18 @@ {% load i18n %} -
+ {% csrf_token %} {% endblock page_title_extra %} @@ -45,7 +44,7 @@
{% translate "Created By" %}
- {{ instance.created_by }} + {{ instance.created_by|default:"-" }}
{% translate "Created At" %}
@@ -106,9 +105,9 @@ {{ condition.status }} {% endif %} - {{ condition.lastTransitionTime }} - {{ condition.reason }} - {{ condition.message }} + {{ condition.lastTransitionTime|date:"SHORT_DATETIME_FORMAT" }} + {{ condition.reason|default:"-" }} + {{ condition.message|truncatewords:20|default:"-" }} {% endfor %} @@ -137,6 +136,8 @@ data-bs-toggle="tab" role="tab">{{ fieldset.title }} + {% empty %} + {% endfor %} @@ -153,7 +154,7 @@ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %}
{{ field.value|pprint }}
{% else %} - {{ field.value }} + {{ field.value|default:"-" }} {% endif %}
{% endfor %} @@ -168,13 +169,15 @@ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %}
{{ field.value|pprint }}
{% else %} - {{ field.value }} + {{ field.value|default:"-" }} {% endif %} {% endfor %} {% endfor %}
+ {% empty %} +

{% translate "No specification details to display." %}

{% endfor %}
@@ -218,15 +221,21 @@ {% endif %} - -