From b445069e72653a3c3ffbaaa7602e9f9f54d43422 Mon Sep 17 00:00:00 2001 From: "Szabo, Zoltan" Date: Tue, 26 Mar 2024 14:45:56 +0100 Subject: [PATCH] Catch SVG uploads --- api/models.py | 30 ++- api/serializers.py | 99 ++++--- country_plan/serializers.py | 9 + databank/serializers.py | 6 + dref/serializers.py | 17 ++ flash_update/serializers.py | 13 +- per/drf_views.py | 5 +- per/serializers.py | 23 +- poetry.lock | 517 +++++++++++++++++++++++++----------- pyproject.toml | 1 + utils/file_check.py | 21 ++ 11 files changed, 541 insertions(+), 200 deletions(-) create mode 100644 utils/file_check.py diff --git a/api/models.py b/api/models.py index e2a111cde..8b5dcbd8b 100644 --- a/api/models.py +++ b/api/models.py @@ -647,7 +647,13 @@ class Meta: verbose_name_plural = _('region snippets') def __str__(self): - return self.snippet + return ( + self.snippet[:80] if self.snippet else None + ) or ( + self.image.url + if getattr(self, 'image', None) and self.image.url + else '' + ) @reversion.register(follow=('region',)) @@ -664,7 +670,7 @@ class Meta: verbose_name_plural = _('region emergencies snippets') def __str__(self): - return self.snippet + return (self.snippet[:80] if self.snippet else None) or self.title or '' @reversion.register(follow=('region',)) @@ -681,7 +687,7 @@ class Meta: verbose_name_plural = _('region preparedness snippets') def __str__(self): - return self.snippet + return (self.snippet[:80] if self.snippet else None) or self.title or '' @reversion.register(follow=('region',)) @@ -698,7 +704,7 @@ class Meta: verbose_name_plural = _('region profile snippets') def __str__(self): - return self.snippet + return (self.snippet[:80] if self.snippet else None) or self.title or '' # class RegionAdditionalLink(models.Model): # region = models.ForeignKey(Region, related_name='additional_links', on_delete=models.CASCADE) @@ -724,7 +730,13 @@ class Meta: verbose_name_plural = _('country snippets') def __str__(self): - return self.snippet + return ( + self.snippet[:80] if self.snippet else None + ) or ( + self.image.url + if getattr(self, 'image', None) and self.image.url + else '' + ) @reversion.register() @@ -1020,7 +1032,13 @@ class Meta: verbose_name_plural = _('snippets') def __str__(self): - return self.snippet if self.snippet else '' + return ( + self.snippet[:80] if self.snippet else None + ) or ( + self.image.url + if getattr(self, 'image', None) and self.image.url + else '' + ) class SituationReportType(models.Model): diff --git a/api/serializers.py b/api/serializers.py index bede22b19..f2828dfe6 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -77,6 +77,7 @@ ) from local_units.serializers import MiniDelegationOfficeSerializer from local_units.models import DelegationOffice +from utils.file_check import validate_file_type class GeoSerializerMixin: @@ -200,6 +201,10 @@ class Meta: "average_household_size", ) + def validate_logo(self, logo): + validate_file_type(logo) + return logo + class CountryGeoSerializer(ModelSerializer): bbox = serializers.SerializerMethodField() @@ -487,6 +492,10 @@ class Meta: "id", ) + def validate_image(self, image): + validate_file_type(image) + return image + class RegionEmergencySnippetSerializer(ModelSerializer): class Meta: @@ -551,6 +560,10 @@ class Meta: "id", ) + def validate_image(self, image): + validate_file_type(image) + return image + class RegionLinkSerializer(ModelSerializer): class Meta: @@ -778,6 +791,7 @@ def get_country_delegation(self, country): class CountryKeyDocumentSerializer(ModelSerializer): country_details = MiniCountrySerializer(source='country', read_only=True) + class Meta: model = CountryKeyDocument fields = "__all__" @@ -832,6 +846,10 @@ class Meta: "tab_display", ) + def validate_image(self, image): + validate_file_type(image) + return image + class EventContactSerializer(ModelSerializer): class Meta: @@ -931,6 +949,7 @@ class Meta: class EventFeaturedDocumentSerializer(serializers.ModelSerializer): + class Meta: model = EventFeaturedDocument fields = ( @@ -941,6 +960,14 @@ class Meta: "file", ) + def validate_thumbnail(self, thumbnail): + validate_file_type(thumbnail) + return thumbnail + + def validate_file(self, file): + validate_file_type(file) + return file + class EventLinkSerializer(ModelSerializer): class Meta: @@ -1376,6 +1403,10 @@ class Meta: "visibility_display", ) + def validate_document(self, document): + validate_file_type(document) + return document + class AppealTableauSerializer(serializers.ModelSerializer): country = MiniCountrySerializer() @@ -1559,8 +1590,8 @@ class AppealDocumentAppealSerializer(serializers.ModelSerializer): class Meta: model = Appeal fields = ( - 'id', - 'code', + "id", + "code", ) @@ -1582,6 +1613,10 @@ class Meta: "id", ) + def validate_document(self, document): + validate_file_type(document) + return document + class ProfileSerializer(ModelSerializer): country = MiniCountrySerializer() @@ -1666,7 +1701,7 @@ class Meta: class UserCountryCountrySerializer(serializers.ModelSerializer): - region_details = MiniRegionSerialzier(source='region', read_only=True) + region_details = MiniRegionSerialzier(source="region", read_only=True) class Meta: model = Country @@ -1680,12 +1715,12 @@ class Meta: class UserCountrySerializer(serializers.ModelSerializer): country_name = serializers.CharField(source="country.name", read_only=True) - region = serializers.IntegerField(source='country.region.name', read_only=True) - region_details = MiniRegionSerialzier(source='country.region', read_only=True) + region = serializers.IntegerField(source="country.region.name", read_only=True) + region_details = MiniRegionSerialzier(source="country.region", read_only=True) class Meta: model = UserCountry - exclude = ('id', 'user') + exclude = ("id", "user") class UserMeSerializer(UserSerializer): @@ -1737,9 +1772,9 @@ def get_lang_permissions(user) -> dict: def get_is_dref_coordinator_for_regions(user) -> List[int]: data = list( Permission.objects.filter( - codename__startswith='dref_region_admin_', + codename__startswith="dref_region_admin_", group__user=user - ).values_list('codename', flat=True) + ).values_list("codename", flat=True) ) regions = [] for d in data: @@ -1750,27 +1785,27 @@ def get_is_dref_coordinator_for_regions(user) -> List[int]: @staticmethod def get_is_per_admin_for_regions(user) -> List[int]: permission_codenames = Permission.objects.filter( - codename__startswith='per_region_admin', + codename__startswith="per_region_admin", group__user=user - ).values_list('codename', flat=True) + ).values_list("codename", flat=True) - regions = {int(code.split('_')[-1]) for code in permission_codenames} + regions = {int(code.split("_")[-1]) for code in permission_codenames} return list(regions) @staticmethod def get_is_per_admin_for_countries(user) -> List[int]: permission_codenames = Permission.objects.filter( - codename__startswith='per_country_admin', + codename__startswith="per_country_admin", group__user=user - ).values_list('codename', flat=True) + ).values_list("codename", flat=True) - countries = {int(code.split('_')[-1]) for code in permission_codenames} + countries = {int(code.split("_")[-1]) for code in permission_codenames} return list(countries) @staticmethod @extend_schema_field(UserCountrySerializer(many=True)) def get_user_countries_regions(user): - qs = UserCountry.objects.filter(user=user).distinct('country') + qs = UserCountry.objects.filter(user=user).distinct("country") return UserCountrySerializer(qs, many=True).data @@ -1818,7 +1853,7 @@ class Meta: class FieldReportEnumDisplayMixin: """ - Use for fields = '__all__' + Use for fields = "__all__" """ epi_figures_source_display = serializers.CharField(source="get_epi_figures_source_display", read_only=True) @@ -1961,7 +1996,7 @@ def __init__(self, *args, **kwargs): external_partners = ExternalPartnerSerializer(many=True) supported_activities = SupportedActivitySerializer(many=True) regions = RegionSerializer(many=True) - visibility_display = serializers.CharField(source='get_visibility_display', read_only=True) + visibility_display = serializers.CharField(source="get_visibility_display", read_only=True) class Meta: model = FieldReport @@ -1972,11 +2007,11 @@ class FieldReportMiniUserSerializer(ModelSerializer): class Meta: model = User fields = ( - 'id', - 'username', - 'email', - 'first_name', - 'last_name' + "id", + "username", + "email", + "first_name", + "last_name" ) @@ -2015,7 +2050,7 @@ class FieldReportSerializer( dtype_details = DisasterTypeSerializer(source="dtype", read_only=True) external_partners_details = ExternalPartnerSerializer(source="external_partners", many=True, read_only=True) supported_activities_details = SupportedActivitySerializer(source="supported_activities", many=True, read_only=True) - user_details = FieldReportMiniUserSerializer(source='user', read_only=True) + user_details = FieldReportMiniUserSerializer(source="user", read_only=True) class Meta: model = FieldReport @@ -2037,7 +2072,7 @@ def create_event(self, report): event.regions.add(*report.regions.all()) FieldReportSerializer.trigger_field_translation(event) report.event = event - report.save(update_fields=['event']) + report.save(update_fields=["event"]) def validate(self, data): # Set RecentAffected according to the sent _affected key – see (¤) in other code parts @@ -2058,7 +2093,7 @@ def validate(self, data): return data def create(self, validated_data): - validated_data['user'] = self.context["request"].user + validated_data["user"] = self.context["request"].user countries = validated_data["countries"] field_report = super().create(validated_data) # also add regions for the coutries selected @@ -2068,7 +2103,7 @@ def create(self, validated_data): return field_report def update(self, instance, validated_data): - validated_data['user'] = self.context["request"].user + validated_data["user"] = self.context["request"].user return super().update(instance, validated_data) @@ -2339,7 +2374,7 @@ class HistoricalDisasterSerializer(serializers.Serializer): class ExportSerializer(serializers.ModelSerializer): - status_display = serializers.CharField(source='get_status_display', read_only=True) + status_display = serializers.CharField(source="get_status_display", read_only=True) class Meta: model = Export @@ -2354,10 +2389,14 @@ class Meta: "url" ) + def validate_pdf_file(self, pdf_file): + validate_file_type(pdf_file) + return pdf_file + def create(self, validated_data): - export_id = validated_data.get('export_id') - export_type = validated_data.get('export_type') - country_id = validated_data.get('per_country') + export_id = validated_data.get("export_id") + export_type = validated_data.get("export_type") + country_id = validated_data.get("per_country") if export_type == Export.ExportType.DREF: title = Dref.objects.filter( id=export_id diff --git a/country_plan/serializers.py b/country_plan/serializers.py index 2ce0f5bad..029d6018a 100644 --- a/country_plan/serializers.py +++ b/country_plan/serializers.py @@ -5,6 +5,7 @@ StrategicPriority, MembershipCoordination, ) +from utils.file_check import validate_file_type class StrategicPrioritySerializer(serializers.ModelSerializer): @@ -67,3 +68,11 @@ def get_internal_plan_file(self, obj): return request.build_absolute_uri( serializers.FileField().to_representation(file) ) + + def validate_internal_plan_file(self, internal_plan_file): + validate_file_type(internal_plan_file) + return internal_plan_file + + def validate_public_plan_file(self, public_plan_file): + validate_file_type(public_plan_file) + return public_plan_file diff --git a/databank/serializers.py b/databank/serializers.py index 952494a2e..a215d8647 100644 --- a/databank/serializers.py +++ b/databank/serializers.py @@ -19,6 +19,7 @@ FDRSIncome, FDRSAnnualIncome ) +from utils.file_check import validate_file_type class KeyClimateEventSerializer(serializers.ModelSerializer): @@ -83,6 +84,10 @@ class Meta: model = KeyDocument exclude = ('overview',) + def validate_file(self, file): + validate_file_type(file) + return file + class ExternalSourceSerializer(serializers.ModelSerializer): class Meta: @@ -109,6 +114,7 @@ class Meta: model = FDRSAnnualIncome fields = "__all__" + class CountryKeyClimateSerializer(serializers.ModelSerializer): month_display = serializers.CharField(source='get_month_display', read_only=True) diff --git a/dref/serializers.py b/dref/serializers.py index 71b4d44e2..f02d1061c 100644 --- a/dref/serializers.py +++ b/dref/serializers.py @@ -30,6 +30,7 @@ from .tasks import send_dref_email from dref.utils import get_dref_users +from utils.file_check import validate_file_type class RiskSecuritySerializer(ModelSerializer): @@ -65,6 +66,10 @@ class Meta: fields = "__all__" read_only_fields = ("created_by",) + def validate_file(self, file): + validate_file_type(file) + return file + def create(self, validated_data): validated_data["created_by"] = self.context["request"].user return super().create(validated_data) @@ -470,6 +475,10 @@ def validate_operation_timeframe(self, operation_timeframe): ) return operation_timeframe + def validate_budget_file_preview(self, budget_file_preview): + validate_file_type(budget_file_preview) + return budget_file_preview + def create(self, validated_data): validated_data["created_by"] = self.context["request"].user validated_data["is_active"] = True @@ -616,6 +625,10 @@ def get_total_timeframe(self, start_date, end_date): return abs(end_date_month - start_date_month) return None + def validate_budget_file_preview(self, budget_file_preview): + validate_file_type(budget_file_preview) + return budget_file_preview + def create(self, validated_data): dref = validated_data["dref"] dref_operational_update = ( @@ -923,6 +936,10 @@ def validate_photos(self, photos): raise serializers.ValidationError("Can add utmost %s photos" % self.MAX_NUMBER_OF_PHOTOS) return photos + def validate_financial_report_preview(self, financial_report_preview): + validate_file_type(financial_report_preview) + return financial_report_preview + def create(self, validated_data): # here check if there is operational update for corresponding dref # if yes copy from the latest operational update diff --git a/flash_update/serializers.py b/flash_update/serializers.py index 3fa6b54c8..f3ea50df3 100644 --- a/flash_update/serializers.py +++ b/flash_update/serializers.py @@ -1,8 +1,7 @@ from django.db import transaction from django.utils.translation import gettext - from rest_framework import serializers - +from utils.file_check import validate_file_type from .tasks import share_flash_update, send_flash_update_email from api.serializers import ( @@ -58,6 +57,10 @@ class Meta: fields = '__all__' read_only_fields = ('created_by',) + def validate_file(self, file): + validate_file_type(file) + return file + def create(self, validated_data): validated_data['created_by'] = self.context['request'].user return super().create(validated_data) @@ -134,13 +137,17 @@ class Meta: def validate_country_district(self, attrs): if len(attrs) > 10: raise serializers.ValidationError("Number of countries selected should not be greater than 10") - # check for dublicate country + # check for duplicate country country_list = [] for country_district in attrs: country_list.append(country_district['country']) if len(country_list) > len(set(country_list)): raise serializers.ValidationError("Duplicate country selected") + def validate_extracted_file(self, extracted_file): + validate_file_type(extracted_file) + return extracted_file + def create(self, validated_data): validated_data['created_by'] = self.context['request'].user flash_update = super().create(validated_data) diff --git a/per/drf_views.py b/per/drf_views.py index d3fb2d36a..70379ba10 100644 --- a/per/drf_views.py +++ b/per/drf_views.py @@ -49,6 +49,7 @@ from .serializers import ( LatestCountryOverviewSerializer, ListNiceDocSerializer, + NiceDocumentSerializer, FormAreaSerializer, FormComponentSerializer, FormQuestionSerializer, @@ -143,9 +144,7 @@ def get_queryset(self): def get_serializer_class(self): if self.action == "list": return ListNiceDocSerializer - # else: - # return DetailFormDataSerializer - # ordering_fields = ('name', 'country',) + return NiceDocumentSerializer class FormAreaFilter(filters.FilterSet): diff --git a/per/serializers.py b/per/serializers.py index fe56c6f0a..f2d58d6ea 100644 --- a/per/serializers.py +++ b/per/serializers.py @@ -1,6 +1,6 @@ import typing from rest_framework import serializers - +from django.utils.translation import gettext from django.contrib.auth.models import User from django.db import models from django.contrib.auth.models import Permission @@ -43,6 +43,7 @@ from main.writable_nested_serializers import NestedUpdateMixin, NestedCreateMixin from drf_spectacular.utils import extend_schema_field from main.settings import SEP +from utils.file_check import validate_file_type def check_draft_change( @@ -222,6 +223,17 @@ class Meta: fields = ("name", "country", "document", "document_url", "visibility", "visibility_display") +class NiceDocumentSerializer(serializers.ModelSerializer): + + class Meta: + model = NiceDocument + fields = "__all__" + + def validate_document(self, document): + validate_file_type(document) + return document + + class ShortFormSerializer(serializers.ModelSerializer): area = FormAreaSerializer() overview = IsFinalOverviewSerializer() @@ -540,6 +552,10 @@ class Meta: fields = "__all__" read_only_fields = ("created_by",) + def validate_file(self, file): + validate_file_type(file) + return file + def create(self, validated_data): validated_data["created_by"] = self.context["request"].user return super().create(validated_data) @@ -995,13 +1011,16 @@ def validate(self, data): ) return data + def validate_file(self, file): + validate_file_type(file) + return file def create(self, validated_data): validated_data["created_by"] = self.context["request"].user return super().create(validated_data) def update(self, instance, validated_data): - raise serializers.ValidationError("Update is not allowed") + raise serializers.ValidationError("Update is not allowed") class ExportPerViewSerializer(serializers.Serializer): diff --git a/poetry.lock b/poetry.lock index 1138c4b6e..1c5412c37 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. [[package]] name = "amqp" version = "5.2.0" description = "Low-level AMQP client for Python (fork of amqplib)." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -18,6 +19,7 @@ vine = ">=5.0.0,<6.0.0" name = "aniso8601" version = "7.0.0" description = "A library for parsing ISO 8601 strings." +category = "main" optional = false python-versions = "*" files = [ @@ -27,19 +29,21 @@ files = [ [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" +category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] [[package]] name = "arabic-reshaper" version = "3.0.0" description = "Reconstruct Arabic sentences to be used in applications that do not support Arabic" +category = "main" optional = false python-versions = "*" files = [ @@ -54,6 +58,7 @@ with-fonttools = ["fonttools (>=4.0)"] name = "asgiref" version = "3.7.2" description = "ASGI specs, helper code, and adapters" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -71,6 +76,7 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "asn1crypto" version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" +category = "main" optional = false python-versions = "*" files = [ @@ -82,6 +88,7 @@ files = [ name = "asttokens" version = "2.4.1" description = "Annotate AST trees with source code positions" +category = "main" optional = false python-versions = "*" files = [ @@ -100,6 +107,7 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -111,6 +119,7 @@ files = [ name = "attrs" version = "23.2.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -130,6 +139,7 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p name = "azure-common" version = "1.1.19" description = "Microsoft Azure Client Library for Python (Common)" +category = "main" optional = false python-versions = "*" files = [ @@ -141,6 +151,7 @@ files = [ name = "azure-nspkg" version = "3.0.2" description = "Microsoft Azure Namespace Package [Internal]" +category = "main" optional = false python-versions = "*" files = [ @@ -153,6 +164,7 @@ files = [ name = "azure-storage" version = "0.36.0" description = "Microsoft Azure Storage Client Library for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -171,6 +183,7 @@ requests = "*" name = "azure-storage-blob" version = "1.5.0" description = "Microsoft Azure Storage Blob Client Library for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -186,6 +199,7 @@ azure-storage-common = ">=1.4,<2.0" name = "azure-storage-common" version = "1.4.0" description = "Microsoft Azure Storage Common Client Library for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -203,6 +217,7 @@ requests = "*" name = "azure-storage-logging" version = "0.5.1" description = "Logging handlers to send logs to Microsoft Azure Storage" +category = "main" optional = false python-versions = "*" files = [ @@ -216,6 +231,7 @@ azure-storage = ">=0.33.0" name = "azure-storage-nspkg" version = "3.1.0" description = "Microsoft Azure Storage Namespace Package [Internal]" +category = "main" optional = false python-versions = "*" files = [ @@ -230,6 +246,7 @@ azure-nspkg = ">=2.0.0" name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" +category = "main" optional = false python-versions = "*" files = [ @@ -241,6 +258,7 @@ files = [ name = "backports-zoneinfo" version = "0.2.1" description = "Backport of the standard library zoneinfo module" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -272,6 +290,7 @@ tzdata = ["tzdata"] name = "beautifulsoup4" version = "4.6.3" description = "Screen-scraping library" +category = "main" optional = false python-versions = "*" files = [ @@ -288,6 +307,7 @@ lxml = ["lxml"] name = "billiard" version = "3.6.4.0" description = "Python multiprocessing fork with improvements and bugfixes" +category = "main" optional = false python-versions = "*" files = [ @@ -299,6 +319,7 @@ files = [ name = "boto3" version = "1.20.38" description = "The AWS SDK for Python" +category = "main" optional = false python-versions = ">= 3.6" files = [ @@ -318,6 +339,7 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] name = "botocore" version = "1.23.54" description = "Low-level, data-driven core of boto 3." +category = "main" optional = false python-versions = ">= 3.6" files = [ @@ -335,19 +357,21 @@ crt = ["awscrt (==0.12.5)"] [[package]] name = "cachetools" -version = "5.3.2" +version = "5.3.3" description = "Extensible memoizing collections and decorators" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, - {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, + {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, + {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, ] [[package]] name = "celery" version = "5.1.2" description = "Distributed Task Queue." +category = "main" optional = false python-versions = ">=3.6," files = [ @@ -402,19 +426,21 @@ zstd = ["zstandard"] [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -479,6 +505,7 @@ pycparser = "*" name = "chardet" version = "5.2.0" description = "Universal encoding detector for Python 3" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -490,6 +517,7 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -589,6 +617,7 @@ files = [ name = "choicesenum" version = "0.7.0" description = "Python's Enum with extra powers to play nice with labels and choices fields" +category = "main" optional = false python-versions = "*" files = [ @@ -603,6 +632,7 @@ six = "*" name = "click" version = "7.1.2" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -614,6 +644,7 @@ files = [ name = "click-didyoumean" version = "0.3.0" description = "Enables git-like *did-you-mean* feature in click" +category = "main" optional = false python-versions = ">=3.6.2,<4.0.0" files = [ @@ -628,6 +659,7 @@ click = ">=7" name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +category = "main" optional = false python-versions = "*" files = [ @@ -645,6 +677,7 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "click-repl" version = "0.3.0" description = "REPL plugin for Click" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -663,6 +696,7 @@ testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] name = "cligj" version = "0.7.2" description = "Click params for commmand line interfaces to GeoJSON" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" files = [ @@ -680,6 +714,7 @@ test = ["pytest-cov"] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -691,6 +726,7 @@ files = [ name = "coreapi" version = "2.3.3" description = "Python client library for Core API." +category = "main" optional = false python-versions = "*" files = [ @@ -708,6 +744,7 @@ uritemplate = "*" name = "coreschema" version = "0.0.4" description = "Core Schema." +category = "main" optional = false python-versions = "*" files = [ @@ -722,6 +759,7 @@ jinja2 = "*" name = "coverage" version = "4.4.2" description = "Code coverage measurement for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -763,6 +801,7 @@ files = [ name = "cryptography" version = "42.0.4" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -817,6 +856,7 @@ test-randomorder = ["pytest-randomly"] name = "cssselect2" version = "0.7.0" description = "CSS selectors for Python ElementTree" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -836,6 +876,7 @@ test = ["flake8", "isort", "pytest"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -847,6 +888,7 @@ files = [ name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -856,13 +898,14 @@ files = [ [[package]] name = "django" -version = "3.2.24" +version = "3.2.25" description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." +category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "Django-3.2.24-py3-none-any.whl", hash = "sha256:5dd5b787c3ba39637610fe700f54bf158e33560ea0dba600c19921e7ff926ec5"}, - {file = "Django-3.2.24.tar.gz", hash = "sha256:aaee9fb0fb4ebd4311520887ad2e33313d368846607f82a9a0ed461cd4c35b18"}, + {file = "Django-3.2.25-py3-none-any.whl", hash = "sha256:a52ea7fcf280b16f7b739cec38fa6d3f8953a5456986944c3ca97e79882b4e38"}, + {file = "Django-3.2.25.tar.gz", hash = "sha256:7ca38a78654aee72378594d63e51636c04b8e28574f5505dff630895b5472777"}, ] [package.dependencies] @@ -878,6 +921,7 @@ bcrypt = ["bcrypt"] name = "django-admin-autocomplete-filter" version = "0.7.1" description = "A simple Django app to render list filters in django admin using autocomplete widget" +category = "main" optional = false python-versions = "*" files = [ @@ -892,6 +936,7 @@ django = ">=2.0" name = "django-admin-list-filter-dropdown" version = "1.0.3" description = "Use dropdowns in Django admin list filter" +category = "main" optional = false python-versions = "*" files = [ @@ -903,6 +948,7 @@ files = [ name = "django-cors-headers" version = "3.11.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -917,6 +963,7 @@ Django = ">=2.2" name = "django-coverage" version = "1.2.4" description = "Django Test Coverage App" +category = "main" optional = false python-versions = "*" files = [ @@ -927,6 +974,7 @@ files = [ name = "django-debug-toolbar" version = "4.1.0" description = "A configurable set of panels that display various debug information about the current request/response." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -942,6 +990,7 @@ sqlparse = ">=0.2" name = "django-enumfield" version = "2.0.2" description = "Custom Django field for using enumerations of named constants" +category = "main" optional = false python-versions = "*" files = [ @@ -959,6 +1008,7 @@ dev = ["Django", "black", "django-stubs", "djangorestframework-stubs", "isort", name = "django-environ" version = "0.8.1" description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application." +category = "main" optional = false python-versions = ">=3.4,<4" files = [ @@ -967,14 +1017,15 @@ files = [ ] [package.extras] -develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.dev0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] -docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] +develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] +docs = ["furo (>=2021.8.17b43,<2021.9.0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"] [[package]] name = "django-extensions" version = "2.0.6" description = "Extensions for Django" +category = "main" optional = false python-versions = "*" files = [ @@ -989,6 +1040,7 @@ six = ">=1.2" name = "django-filter" version = "2.4.0" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1003,6 +1055,7 @@ Django = ">=2.2" name = "django-guardian" version = "2.4.0" description = "Implementation of per object permissions for Django." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1017,6 +1070,7 @@ Django = ">=2.2" name = "django-haystack" version = "3.2.1" description = "Pluggable search for Django." +category = "main" optional = false python-versions = "*" files = [ @@ -1034,6 +1088,7 @@ elasticsearch = ["elasticsearch (>=5,<8)"] name = "django-modeltranslation" version = "0.17.5" description = "Translates Django models using a registration approach." +category = "main" optional = false python-versions = ">=3.6.2" files = [ @@ -1048,6 +1103,7 @@ six = ">=1.15.0,<2.0.0" name = "django-read-only" version = "1.12.0" description = "Disable Django database writes." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1062,6 +1118,7 @@ Django = ">=3.2" name = "django-redis" version = "5.0.0" description = "Full featured redis cache backend for Django." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1077,6 +1134,7 @@ redis = ">=3.0.0" name = "django-reversion" version = "3.0.5" description = "An extension to the Django web framework that provides version control for model instances." +category = "main" optional = false python-versions = "*" files = [ @@ -1091,6 +1149,7 @@ django = ">=1.11" name = "django-reversion-compare" version = "0.9.0" description = "history compare for django-reversion" +category = "main" optional = false python-versions = "*" files = [ @@ -1106,6 +1165,7 @@ django-reversion = ">=2.0" name = "django-storages" version = "1.11.1" description = "Support for many storage backends in Django" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1128,6 +1188,7 @@ sftp = ["paramiko"] name = "django-stubs" version = "4.2.7" description = "Mypy stubs for Django" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1150,6 +1211,7 @@ compatible-mypy = ["mypy (>=1.7.0,<1.8.0)"] name = "django-stubs-ext" version = "4.2.7" description = "Monkey-patching and extensions for django-stubs" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1165,6 +1227,7 @@ typing-extensions = "*" name = "django-tinymce4-lite" version = "1.7.4" description = "A Django application that provides a fully functional TinyMCE 4 editor widget for models and forms." +category = "main" optional = false python-versions = "*" files = [ @@ -1180,6 +1243,7 @@ jsmin = "*" name = "djangorestframework" version = "3.11.2" description = "Web APIs for Django, made easy." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1194,6 +1258,7 @@ django = ">=1.11" name = "djangorestframework-camel-case" version = "1.2.0" description = "Camel case JSON support for Django REST framework." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1204,6 +1269,7 @@ files = [ name = "djangorestframework-csv" version = "2.1.1" description = "CSV Tools for Django REST Framework" +category = "main" optional = false python-versions = "*" files = [ @@ -1219,6 +1285,7 @@ unicodecsv = "*" name = "djangorestframework-guardian" version = "0.1.1" description = "django-guardian support for Django REST Framework" +category = "main" optional = false python-versions = "*" files = [ @@ -1234,6 +1301,7 @@ djangorestframework = "*" name = "drf-spectacular" version = "0.27.1" description = "Sane and flexible OpenAPI 3 schema generation for Django REST framework" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1258,6 +1326,7 @@ sidecar = ["drf-spectacular-sidecar"] name = "elasticsearch" version = "7.0.0" description = "Python client for Elasticsearch" +category = "main" optional = false python-versions = "*" files = [ @@ -1276,6 +1345,7 @@ requests = ["requests (>=2.4.0,<3.0.0)"] name = "et-xmlfile" version = "1.1.0" description = "An implementation of lxml.xmlfile for the standard library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1287,6 +1357,7 @@ files = [ name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1301,6 +1372,7 @@ test = ["pytest (>=6)"] name = "executing" version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1315,6 +1387,7 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth name = "factory-boy" version = "2.12.0" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1327,13 +1400,14 @@ Faker = ">=0.7.0" [[package]] name = "faker" -version = "22.6.0" +version = "24.2.0" description = "Faker is a Python package that generates fake data for you." +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "Faker-22.6.0-py3-none-any.whl", hash = "sha256:2b57f0256da6b45b7851dca87836ef5e2ae2fbb64d63d8697f1e47830d7b505d"}, - {file = "Faker-22.6.0.tar.gz", hash = "sha256:fa6d969728ef3da6229da91267a1bd4e6b902044c4822012d4fc46c71bb92b26"}, + {file = "Faker-24.2.0-py3-none-any.whl", hash = "sha256:dce4754921f9fa7e2003c26834093361b8f45072e0f46f172d6ca1234774ecd4"}, + {file = "Faker-24.2.0.tar.gz", hash = "sha256:87d5e7730426e7b36817921679c4eaf3d810cedb8c81194f47adc3df2122ca18"}, ] [package.dependencies] @@ -1344,6 +1418,7 @@ typing-extensions = {version = ">=3.10.0.1", markers = "python_version <= \"3.8\ name = "fastdiff" version = "0.3.0" description = "A fast native implementation of diff algorithm with a pure python fallback" +category = "dev" optional = false python-versions = "*" files = [ @@ -1359,6 +1434,7 @@ wasmer-compiler-cranelift = ">=1.0.0" name = "fuzzywuzzy" version = "0.17.0" description = "Fuzzy string matching in python" +category = "main" optional = false python-versions = "*" files = [ @@ -1371,13 +1447,14 @@ speedup = ["python-levenshtein (>=0.12)"] [[package]] name = "google-api-core" -version = "2.16.0" +version = "2.17.1" description = "Google API client core library" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-core-2.16.0.tar.gz", hash = "sha256:d1fc42e52aa4042ad812827b7aad858394e2bf73da8329af95ad8efa30bc886b"}, - {file = "google_api_core-2.16.0-py3-none-any.whl", hash = "sha256:c424f9f271c7f55366254708e0d0383963a72376286018af0a04f322be843400"}, + {file = "google-api-core-2.17.1.tar.gz", hash = "sha256:9df18a1f87ee0df0bc4eea2770ebc4228392d8cc4066655b320e2cfccb15db95"}, + {file = "google_api_core-2.17.1-py3-none-any.whl", hash = "sha256:610c5b90092c360736baccf17bd3efbcb30dd380e7a6dc28a71059edb8bd0d8e"}, ] [package.dependencies] @@ -1393,13 +1470,14 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.27.0" +version = "2.28.2" description = "Google Authentication Library" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "google-auth-2.27.0.tar.gz", hash = "sha256:e863a56ccc2d8efa83df7a80272601e43487fa9a728a376205c86c26aaefa821"}, - {file = "google_auth-2.27.0-py2.py3-none-any.whl", hash = "sha256:8e4bad367015430ff253fe49d500fdc3396c1a434db5740828c728e45bcce245"}, + {file = "google-auth-2.28.2.tar.gz", hash = "sha256:80b8b4969aa9ed5938c7828308f20f035bc79f9d8fb8120bf9dc8db20b41ba30"}, + {file = "google_auth-2.28.2-py2.py3-none-any.whl", hash = "sha256:9fd67bbcd40f16d9d42f950228e9cf02a2ded4ae49198b27432d0cded5a74c38"}, ] [package.dependencies] @@ -1416,13 +1494,14 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "googleapis-common-protos" -version = "1.62.0" +version = "1.63.0" description = "Common protobufs used in Google APIs" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.62.0.tar.gz", hash = "sha256:83f0ece9f94e5672cced82f592d2a5edf527a96ed1794f0bab36d5735c996277"}, - {file = "googleapis_common_protos-1.62.0-py2.py3-none-any.whl", hash = "sha256:4750113612205514f9f6aa4cb00d523a94f3e8c06c5ad2fee466387dc4875f07"}, + {file = "googleapis-common-protos-1.63.0.tar.gz", hash = "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e"}, + {file = "googleapis_common_protos-1.63.0-py2.py3-none-any.whl", hash = "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632"}, ] [package.dependencies] @@ -1435,6 +1514,7 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] name = "gprof2dot" version = "2022.7.29" description = "Generate a dot graph from the output of several profilers." +category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -1446,6 +1526,7 @@ files = [ name = "graphene" version = "2.1.9" description = "GraphQL Framework for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1468,6 +1549,7 @@ test = ["coveralls", "fastdiff (==0.2.0)", "iso8601", "mock", "promise", "pytest name = "graphene-django" version = "2.16.0" description = "Graphene Django integration" +category = "main" optional = false python-versions = "*" files = [ @@ -1492,6 +1574,7 @@ test = ["coveralls", "django-filter (>=2)", "djangorestframework (>=3.6.3)", "mo name = "graphql-core" version = "2.3.2" description = "GraphQL implementation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1512,6 +1595,7 @@ test = ["coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pyann name = "graphql-relay" version = "2.0.1" description = "Relay implementation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1528,6 +1612,7 @@ six = ">=1.12" name = "gunicorn" version = "19.7.1" description = "WSGI HTTP Server for UNIX" +category = "main" optional = false python-versions = "*" files = [ @@ -1539,6 +1624,7 @@ files = [ name = "html5lib" version = "1.1" description = "HTML parser based on the WHATWG HTML specification" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1560,6 +1646,7 @@ lxml = ["lxml"] name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1571,6 +1658,7 @@ files = [ name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1582,6 +1670,7 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1593,6 +1682,7 @@ files = [ name = "ipython" version = "8.12.3" description = "IPython: Productive Interactive Computing" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1632,6 +1722,7 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "itypes" version = "1.2.0" description = "Simple immutable types for python." +category = "main" optional = false python-versions = "*" files = [ @@ -1643,6 +1734,7 @@ files = [ name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1662,6 +1754,7 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.3" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1679,6 +1772,7 @@ i18n = ["Babel (>=2.7)"] name = "jmespath" version = "0.10.0" description = "JSON Matching Expressions" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1690,6 +1784,7 @@ files = [ name = "jsmin" version = "3.0.1" description = "JavaScript minifier." +category = "main" optional = false python-versions = "*" files = [ @@ -1700,6 +1795,7 @@ files = [ name = "jsonschema" version = "3.2.0" description = "An implementation of JSON Schema validation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1721,6 +1817,7 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va name = "jsonseq" version = "1.0.0" description = "Python support for RFC 7464 JSON text sequences" +category = "main" optional = false python-versions = "*" files = [ @@ -1736,6 +1833,7 @@ test = ["pytest", "pytest-cover"] name = "kombu" version = "5.3.5" description = "Messaging library for Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1770,6 +1868,7 @@ zookeeper = ["kazoo (>=2.8.0)"] name = "lxml" version = "4.9.1" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -1855,6 +1954,7 @@ source = ["Cython (>=0.29.7)"] name = "mapbox-tilesets" version = "1.7.3" description = "CLI for interacting with and preparing data for the Tilesets API" +category = "main" optional = false python-versions = "*" files = [ @@ -1881,6 +1981,7 @@ test = ["black (==20.8b1)", "codecov", "pep8", "pre-commit", "pytest (==4.6.11)" name = "markdown" version = "3.3.4" description = "Python implementation of Markdown." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1893,77 +1994,79 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "2.1.4" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, - {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1978,6 +2081,7 @@ traitlets = "*" name = "mercantile" version = "1.1.6" description = "Web mercator XYZ tile utilities" +category = "main" optional = false python-versions = "*" files = [ @@ -1996,6 +2100,7 @@ test = ["coveralls", "hypothesis", "pydocstyle", "pytest-cov"] name = "numpy" version = "1.24.4" description = "Fundamental package for array computing in Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2033,6 +2138,7 @@ files = [ name = "opencensus" version = "0.11.4" description = "A stats collection and distributed tracing framework" +category = "main" optional = false python-versions = "*" files = [ @@ -2049,6 +2155,7 @@ six = ">=1.16,<2.0" name = "opencensus-context" version = "0.1.3" description = "OpenCensus Runtime Context" +category = "main" optional = false python-versions = "*" files = [ @@ -2060,6 +2167,7 @@ files = [ name = "opencensus-ext-azure" version = "1.0.7" description = "OpenCensus Azure Monitor Exporter" +category = "main" optional = false python-versions = "*" files = [ @@ -2076,6 +2184,7 @@ requests = ">=2.19.0" name = "opencensus-ext-django" version = "0.7.4" description = "OpenCensus Django Integration" +category = "main" optional = false python-versions = "*" files = [ @@ -2091,6 +2200,7 @@ opencensus = ">=0.7.12,<1.0.0" name = "openpyxl" version = "3.0.10" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2105,6 +2215,7 @@ et-xmlfile = "*" name = "oscrypto" version = "1.3.0" description = "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD." +category = "main" optional = false python-versions = "*" files = [ @@ -2117,19 +2228,21 @@ asn1crypto = ">=1.5.1" [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "pandas" version = "1.3.5" description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" optional = false python-versions = ">=3.7.1" files = [ @@ -2162,7 +2275,7 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.17.3", markers = "(platform_machine != \"aarch64\" and platform_machine != \"arm64\") and python_version < \"3.10\""}, + {version = ">=1.17.3", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, @@ -2177,6 +2290,7 @@ test = ["hypothesis (>=3.58)", "pytest (>=6.0)", "pytest-xdist"] name = "parso" version = "0.8.3" description = "A Python Parser" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2192,6 +2306,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pdf2image" version = "1.16.0" description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list." +category = "main" optional = false python-versions = "*" files = [ @@ -2206,6 +2321,7 @@ pillow = "*" name = "pdfminer-six" version = "20191110" description = "PDF parser and analyzer" +category = "main" optional = false python-versions = "*" files = [ @@ -2227,6 +2343,7 @@ docs = ["sphinx", "sphinx-argparse"] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." +category = "main" optional = false python-versions = "*" files = [ @@ -2241,6 +2358,7 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" +category = "main" optional = false python-versions = "*" files = [ @@ -2252,6 +2370,7 @@ files = [ name = "pillow" version = "10.2.0" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2337,6 +2456,7 @@ xmp = ["defusedxml"] name = "pluggy" version = "1.4.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2352,6 +2472,7 @@ testing = ["pytest", "pytest-benchmark"] name = "polib" version = "1.1.0" description = "A library to manipulate gettext files (po and mo files)." +category = "main" optional = false python-versions = "*" files = [ @@ -2363,6 +2484,7 @@ files = [ name = "promise" version = "2.3" description = "Promises/A+ implementation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -2379,6 +2501,7 @@ test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", name = "prompt-toolkit" version = "3.0.43" description = "Library for building powerful interactive command lines in Python" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -2391,28 +2514,30 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.25.2" +version = "4.25.3" description = "" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6"}, - {file = "protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9"}, - {file = "protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d"}, - {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62"}, - {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020"}, - {file = "protobuf-4.25.2-cp38-cp38-win32.whl", hash = "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61"}, - {file = "protobuf-4.25.2-cp38-cp38-win_amd64.whl", hash = "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62"}, - {file = "protobuf-4.25.2-cp39-cp39-win32.whl", hash = "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3"}, - {file = "protobuf-4.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0"}, - {file = "protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830"}, - {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, + {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, + {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, + {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, + {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, + {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, + {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, + {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, + {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, + {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, ] [[package]] name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2441,6 +2566,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "psycopg2-binary" version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2522,6 +2648,7 @@ files = [ name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -2533,6 +2660,7 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" +category = "main" optional = false python-versions = "*" files = [ @@ -2547,6 +2675,7 @@ tests = ["pytest"] name = "pyasn1" version = "0.5.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2558,6 +2687,7 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2572,6 +2702,7 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pycountry" version = "19.8.18" description = "ISO country, subdivision, language, currency and script definitions and their translations" +category = "main" optional = false python-versions = "*" files = [ @@ -2582,6 +2713,7 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2593,6 +2725,7 @@ files = [ name = "pycryptodome" version = "3.20.0" description = "Cryptographic library for Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2634,6 +2767,7 @@ files = [ name = "pydash" version = "4.8.0" description = "The kitchen sink of Python utility libraries for doing \"stuff\" in a functional way. Based on the Lo-Dash Javascript library." +category = "main" optional = false python-versions = "*" files = [ @@ -2648,6 +2782,7 @@ dev = ["Sphinx", "coverage", "flake8", "mock", "pylint", "pytest", "pytest-cov", name = "pygments" version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2663,6 +2798,7 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyhanko" version = "0.20.1" description = "Tools for stamping and signing PDF files" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2674,7 +2810,7 @@ files = [ asn1crypto = ">=1.5.1" click = ">=7.1.2" cryptography = ">=3.3.1" -pyhanko-certvalidator = "==0.24.*" +pyhanko-certvalidator = ">=0.24.0,<0.25.0" pyyaml = ">=5.3.1" qrcode = ">=6.1" requests = ">=2.24.0" @@ -2690,13 +2826,14 @@ mypy = ["pyHanko[async-http,extra-pubkey-algs,image-support,opentype,pkcs11,xmp] opentype = ["fonttools (>=4.33.3)", "uharfbuzz (>=0.25.0,<0.38.0)"] pkcs11 = ["python-pkcs11 (>=0.7.0,<0.8.0)"] testing = ["certomancer-csc-dummy (==0.2.2)", "pyHanko[async-http,extra-pubkey-algs,image-support,opentype,pkcs11,testing-basic,xmp]", "pytest-aiohttp (>=1.0.4,<1.1.0)"] -testing-basic = ["backports.zoneinfo[tzdata]", "certomancer (==0.11.*)", "freezegun (>=1.1.0)", "pytest (>=6.1.1)", "pytest-asyncio (==0.21.1)", "pytest-cov (>=4.0,<4.2)", "requests-mock (>=1.8.0)"] +testing-basic = ["backports.zoneinfo[tzdata]", "certomancer (>=0.11.0,<0.12.0)", "freezegun (>=1.1.0)", "pytest (>=6.1.1)", "pytest-asyncio (==0.21.1)", "pytest-cov (>=4.0,<4.2)", "requests-mock (>=1.8.0)"] xmp = ["defusedxml (>=0.7.1,<0.8.0)"] [[package]] name = "pyhanko-certvalidator" version = "0.24.1" description = "Validates X.509 certificates and paths; forked from wbond/certvalidator" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2718,13 +2855,14 @@ testing = ["aiohttp (>=3.8.0,<3.9.0)", "freezegun (>=1.1.0)", "pyhanko-certvalid [[package]] name = "pypdf" -version = "4.0.1" +version = "4.1.0" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "pypdf-4.0.1-py3-none-any.whl", hash = "sha256:fe7c313c7e8074a516eae9d9df0111b7b9769f7a210479af7a342d27270ef81a"}, - {file = "pypdf-4.0.1.tar.gz", hash = "sha256:871badcfe335dd68b6b563aa7646288c6b86f9ceecffb21e86341261d65d8173"}, + {file = "pypdf-4.1.0-py3-none-any.whl", hash = "sha256:16cac912a05200099cef3f347c4c7e0aaf0a6d027603b8f9a973c0ea500dff89"}, + {file = "pypdf-4.1.0.tar.gz", hash = "sha256:01c3257ec908676efd60a4537e525b89d48e0852bc92b4e0aa4cc646feda17cc"}, ] [package.dependencies] @@ -2741,6 +2879,7 @@ image = ["Pillow (>=8.0.0)"] name = "pypdf2" version = "1.27.9" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +category = "main" optional = false python-versions = ">=2.7" files = [ @@ -2752,6 +2891,7 @@ files = [ name = "pypng" version = "0.20220715.0" description = "Pure Python library for saving and loading PNG images" +category = "main" optional = false python-versions = "*" files = [ @@ -2763,6 +2903,7 @@ files = [ name = "pyrsistent" version = "0.20.0" description = "Persistent/Functional/Immutable data structures" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2802,13 +2943,14 @@ files = [ [[package]] name = "pytest" -version = "8.0.0" +version = "8.1.1" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, - {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, + {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, + {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] @@ -2816,21 +2958,22 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.3.0,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.4,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-django" -version = "4.7.0" +version = "4.8.0" description = "A Django plugin for pytest." +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-django-4.7.0.tar.gz", hash = "sha256:92d6fd46b1d79b54fb6b060bbb39428073396cec717d5f2e122a990d4b6aa5e8"}, - {file = "pytest_django-4.7.0-py3-none-any.whl", hash = "sha256:4e1c79d5261ade2dd58d91208017cd8f62cb4710b56e012ecd361d15d5d662a2"}, + {file = "pytest-django-4.8.0.tar.gz", hash = "sha256:5d054fe011c56f3b10f978f41a8efb2e5adfc7e680ef36fb571ada1f24779d90"}, + {file = "pytest_django-4.8.0-py3-none-any.whl", hash = "sha256:ca1ddd1e0e4c227cf9e3e40a6afc6d106b3e70868fd2ac5798a22501271cd0c7"}, ] [package.dependencies] @@ -2844,6 +2987,7 @@ testing = ["Django", "django-configurations (>=2.0)"] name = "pytest-ordering" version = "0.6" description = "pytest plugin to run your tests in a specific order" +category = "dev" optional = false python-versions = "*" files = [ @@ -2859,6 +3003,7 @@ pytest = "*" name = "pytest-profiling" version = "1.7.0" description = "Profiling plugin for py.test" +category = "dev" optional = false python-versions = "*" files = [ @@ -2878,6 +3023,7 @@ tests = ["pytest-virtualenv"] name = "python-bidi" version = "0.4.2" description = "Pure python implementation of the BiDi layout algorithm" +category = "main" optional = false python-versions = "*" files = [ @@ -2892,6 +3038,7 @@ six = "*" name = "python-dateutil" version = "2.8.0" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2906,6 +3053,7 @@ six = ">=1.5" name = "python-levenshtein" version = "0.12.1" description = "Python extension for computing string edit distances and similarities." +category = "main" optional = false python-versions = "*" files = [ @@ -2915,10 +3063,23 @@ files = [ [package.dependencies] setuptools = "*" +[[package]] +name = "python-magic" +version = "0.4.27" +description = "File type identification using libmagic" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, + {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, +] + [[package]] name = "python-mimeparse" version = "1.6.0" description = "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges." +category = "main" optional = false python-versions = "*" files = [ @@ -2930,6 +3091,7 @@ files = [ name = "pytidylib" version = "0.3.2" description = "Python wrapper for HTML Tidy (tidylib) on Python 2 and 3" +category = "main" optional = false python-versions = "*" files = [ @@ -2940,6 +3102,7 @@ files = [ name = "pytz" version = "2019.1" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ @@ -2951,6 +3114,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3011,6 +3175,7 @@ files = [ name = "qrcode" version = "7.4.2" description = "QR Code image generator" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3032,17 +3197,18 @@ test = ["coverage", "pytest"] [[package]] name = "redis" -version = "5.0.1" +version = "5.0.3" description = "Python client for Redis database and key-value store" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"}, - {file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"}, + {file = "redis-5.0.3-py3-none-any.whl", hash = "sha256:5da9b8fe9e1254293756c16c008e8620b3d15fcc6dde6babde9541850e72a32d"}, + {file = "redis-5.0.3.tar.gz", hash = "sha256:4973bae7444c0fbed64a06b87446f79361cb7e4ec1538c022d696ed7a5015580"}, ] [package.dependencies] -async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} +async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""} [package.extras] hiredis = ["hiredis (>=1.0.0)"] @@ -3052,6 +3218,7 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "reportlab" version = "4.0.9" description = "The Reportlab Toolkit" +category = "main" optional = false python-versions = ">=3.7,<4" files = [ @@ -3072,6 +3239,7 @@ renderpm = ["rl-renderPM (>=4.0.3,<4.1)"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3093,6 +3261,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3107,6 +3276,7 @@ requests = ">=2.0.1,<3.0.0" name = "rsa" version = "4.9" description = "Pure-Python RSA implementation" +category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -3121,6 +3291,7 @@ pyasn1 = ">=0.1.3" name = "rx" version = "1.6.3" description = "Reactive Extensions (Rx) for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -3131,6 +3302,7 @@ files = [ name = "s3transfer" version = "0.5.2" description = "An Amazon S3 Transfer Manager" +category = "main" optional = false python-versions = ">= 3.6" files = [ @@ -3146,13 +3318,14 @@ crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] [[package]] name = "sentry-sdk" -version = "1.39.2" +version = "1.42.0" description = "Python client for Sentry (https://sentry.io)" +category = "main" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.39.2.tar.gz", hash = "sha256:24c83b0b41c887d33328a9166f5950dc37ad58f01c9f2fbff6b87a6f1094170c"}, - {file = "sentry_sdk-1.39.2-py2.py3-none-any.whl", hash = "sha256:acaf597b30258fc7663063b291aa99e58f3096e91fe1e6634f4b79f9c1943e8e"}, + {file = "sentry-sdk-1.42.0.tar.gz", hash = "sha256:4a8364b8f7edbf47f95f7163e48334c96100d9c098f0ae6606e2e18183c223e6"}, + {file = "sentry_sdk-1.42.0-py2.py3-none-any.whl", hash = "sha256:a654ee7e497a3f5f6368b36d4f04baeab1fe92b3105f7f6965d6ef0de35a9ba4"}, ] [package.dependencies] @@ -3176,9 +3349,10 @@ grpcio = ["grpcio (>=1.21.1)"] httpx = ["httpx (>=0.16.0)"] huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure_eval"] +pure-eval = ["asttokens", "executing", "pure-eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] @@ -3191,24 +3365,26 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "69.0.3" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, - {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "singledispatch" version = "4.1.0" description = "Backport functools.singledispatch to older Pythons." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3224,6 +3400,7 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -3235,6 +3412,7 @@ files = [ name = "snapshottest" version = "0.6.0" description = "Snapshot testing for pytest, unittest, Django, and Nose" +category = "dev" optional = false python-versions = "*" files = [ @@ -3256,6 +3434,7 @@ test = ["django (>=1.10.6)", "nose", "pytest (>=4.6)", "pytest-cov", "six"] name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "main" optional = false python-versions = "*" files = [ @@ -3267,6 +3446,7 @@ files = [ name = "sqlparse" version = "0.4.4" description = "A non-validating SQL parser." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3283,6 +3463,7 @@ test = ["pytest", "pytest-cov"] name = "stack-data" version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" +category = "main" optional = false python-versions = "*" files = [ @@ -3302,6 +3483,7 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "svglib" version = "1.5.1" description = "A pure-Python library for reading and converting SVG" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3318,6 +3500,7 @@ tinycss2 = ">=0.6.0" name = "tabula-py" version = "1.2.0" description = "Simple wrapper for tabula-java, read tables from PDF into DataFrame" +category = "main" optional = false python-versions = "*" files = [ @@ -3334,6 +3517,7 @@ requests = "*" name = "termcolor" version = "2.4.0" description = "ANSI color formatting for output in terminal" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3348,6 +3532,7 @@ tests = ["pytest", "pytest-cov"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" +category = "main" optional = false python-versions = "*" files = [ @@ -3359,6 +3544,7 @@ files = [ name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3377,6 +3563,7 @@ test = ["flake8", "isort", "pytest"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3386,45 +3573,49 @@ files = [ [[package]] name = "traitlets" -version = "5.14.1" +version = "5.14.2" description = "Traitlets Python configuration system" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, - {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, + {file = "traitlets-5.14.2-py3-none-any.whl", hash = "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80"}, + {file = "traitlets-5.14.2.tar.gz", hash = "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.1)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "types-pytz" -version = "2023.4.0.20240130" +version = "2024.1.0.20240203" description = "Typing stubs for pytz" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "types-pytz-2023.4.0.20240130.tar.gz", hash = "sha256:33676a90bf04b19f92c33eec8581136bea2f35ddd12759e579a624a006fd387a"}, - {file = "types_pytz-2023.4.0.20240130-py3-none-any.whl", hash = "sha256:6ce76a9f8fd22bd39b01a59c35bfa2db39b60d11a2f77145e97b730de7e64fe0"}, + {file = "types-pytz-2024.1.0.20240203.tar.gz", hash = "sha256:c93751ee20dfc6e054a0148f8f5227b9a00b79c90a4d3c9f464711a73179c89e"}, + {file = "types_pytz-2024.1.0.20240203-py3-none-any.whl", hash = "sha256:9679eef0365db3af91ef7722c199dbb75ee5c1b67e3c4dd7bfbeb1b8a71c21a3"}, ] [[package]] name = "types-pyyaml" -version = "6.0.12.12" +version = "6.0.12.20240311" description = "Typing stubs for PyYAML" +category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"}, - {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"}, + {file = "types-PyYAML-6.0.12.20240311.tar.gz", hash = "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342"}, + {file = "types_PyYAML-6.0.12.20240311-py3-none-any.whl", hash = "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"}, ] [[package]] name = "typing" version = "3.6.2" description = "Type Hints for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -3435,30 +3626,33 @@ files = [ [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] name = "tzdata" -version = "2023.4" +version = "2024.1" description = "Provider of IANA time zone data" +category = "main" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"}, - {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"}, + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] [[package]] name = "tzlocal" version = "5.2" description = "tzinfo object for the local timezone" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3477,6 +3671,7 @@ devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3) name = "unicodecsv" version = "0.14.1" description = "Python2's stdlib csv module is nice, but it doesn't support unicode. This module is a drop-in replacement which *does*." +category = "main" optional = false python-versions = "*" files = [ @@ -3487,6 +3682,7 @@ files = [ name = "uritemplate" version = "4.1.1" description = "Implementation of RFC 6570 URI Templates" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3498,6 +3694,7 @@ files = [ name = "uritools" version = "4.0.2" description = "URI parsing, classification and composition" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3509,6 +3706,7 @@ files = [ name = "urllib3" version = "1.26.18" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -3525,6 +3723,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "vine" version = "5.1.0" description = "Python promises." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3536,6 +3735,7 @@ files = [ name = "wasmer" version = "1.1.0" description = "Python extension to run WebAssembly binaries" +category = "dev" optional = false python-versions = "*" files = [ @@ -3559,6 +3759,7 @@ files = [ name = "wasmer-compiler-cranelift" version = "1.1.0" description = "The Cranelift compiler for the `wasmer` package (to compile WebAssembly module)" +category = "dev" optional = false python-versions = "*" files = [ @@ -3582,6 +3783,7 @@ files = [ name = "wcwidth" version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -3593,6 +3795,7 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" +category = "main" optional = false python-versions = "*" files = [ @@ -3602,13 +3805,14 @@ files = [ [[package]] name = "xhtml2pdf" -version = "0.2.14" +version = "0.2.15" description = "PDF generator using HTML and CSS" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "xhtml2pdf-0.2.14-py3-none-any.whl", hash = "sha256:dfdd81c5b6fbb06fc7afb1db7af2a313cbaee14e7aa079ead43189a27722b09f"}, - {file = "xhtml2pdf-0.2.14.tar.gz", hash = "sha256:4b33a94921898ed5c0431b46701380dc91ff4aae6d28c99679431ea696edd38c"}, + {file = "xhtml2pdf-0.2.15-py3-none-any.whl", hash = "sha256:ba81ca18a236478eb0d98fffb2d55871642d19cb6927383932a1954111449e5d"}, + {file = "xhtml2pdf-0.2.15.tar.gz", hash = "sha256:cc9c68551677f831d836e7fc94196fa777d3c4d500754aa4dc5c02d45c0e19d1"}, ] [package.dependencies] @@ -3619,20 +3823,21 @@ pyHanko = ">=0.12.1" pyhanko-certvalidator = ">=0.19.5" pypdf = ">=3.1.0" python-bidi = ">=0.4.2" -reportlab = ">=4.0.4" +reportlab = ">=4.0.4,<4.1" svglib = ">=1.2.1" [package.extras] docs = ["sphinx (>=6)", "sphinx-rtd-theme (>=0.5.0)"] -pycairo = ["reportlab[pycairo] (>=4.0.4)"] +pycairo = ["reportlab[pycairo] (>=4.0.4,<4.1)"] release = ["build", "twine"] -renderpm = ["reportlab[renderpm] (>=4.0.4)"] +renderpm = ["reportlab[renderpm] (>=4.0.4,<4.1)"] test = ["coverage (>=5.3)", "tomli (>=2.0.1)", "tox"] [[package]] name = "xmltodict" version = "0.11.0" description = "Makes working with XML feel like you are working with JSON" +category = "main" optional = false python-versions = "*" files = [ @@ -3643,4 +3848,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "9c7f471bb4b7c1346e0230660a42741f72ccc4969122467f5981a34a378b0fc1" +content-hash = "0a6a65e642cad2500a40859d7f509ca421ffbdb55e1d3f91524dbbad69b1b46d" diff --git a/pyproject.toml b/pyproject.toml index 13f33bca6..98fcc30e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,7 @@ pycountry = "==19.8.18" pydash = "==4.8.0" python-Levenshtein = "==0.12.1" python-dateutil = "==2.8.0" +python-magic = "==0.4.27" python-mimeparse = "==1.6.0" pytz = "==2019.1" openpyxl = "==3.0.10" diff --git a/utils/file_check.py b/utils/file_check.py new file mode 100644 index 000000000..eac3621e6 --- /dev/null +++ b/utils/file_check.py @@ -0,0 +1,21 @@ +from django.core.exceptions import ValidationError +from magic import Magic + + +def validate_file_type(file, raise_exception=True) -> bool: + """ + This function validates a file object based on a disallowed mimetype. + Arg: + file: The file object to validate. + Raises: + ValidationError: If the file type is disallowed. + """ + if file: + mime = Magic(mime=True) + file_type = mime.from_buffer(file.read(1024)) + file.seek(0) # Read a portion for analysis, then reset file pointer + if file_type == "image/svg+xml": + if raise_exception: + raise ValidationError("SVG image upload is not allowed. Please use another image type.") + return False + return True