From 703f122ccf9aecedfaf0eb15912df3dea6ca9222 Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Fri, 27 Dec 2024 19:35:54 -0600 Subject: [PATCH 01/21] feat(recap): Replicate RECAP PDF uploads to subdockets Fixes: #4826 --- cl/recap/tasks.py | 135 +++++++++++++---- cl/recap/tests.py | 378 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 412 insertions(+), 101 deletions(-) diff --git a/cl/recap/tasks.py b/cl/recap/tasks.py index 026b1ca2ef..7e8fd676bc 100644 --- a/cl/recap/tasks.py +++ b/cl/recap/tasks.py @@ -20,6 +20,7 @@ from django.core.files.base import ContentFile, File from django.core.files.uploadedfile import SimpleUploadedFile from django.db import IntegrityError, transaction +from django.db.models import QuerySet from django.utils.timezone import now from juriscraper.lib.exceptions import PacerLoginException, ParsingException from juriscraper.lib.string_utils import CaseNameTweaker, harmonize @@ -114,7 +115,9 @@ async def process_recap_upload(pq: ProcessingQueue) -> None: for pq_pk in sub_docket_att_page_pks: await process_recap_attachment(pq_pk) elif pq.upload_type == UPLOAD_TYPE.PDF: - await process_recap_pdf(pq.pk) + sub_docket_pdf_pks = await find_subdocket_pdf_rds(pq.pk) + for pq_pk in sub_docket_pdf_pks: + await process_recap_pdf(pq_pk) elif pq.upload_type == UPLOAD_TYPE.DOCKET_HISTORY_REPORT: docket = await process_recap_docket_history_report(pq.pk) elif pq.upload_type == UPLOAD_TYPE.APPELLATE_DOCKET: @@ -676,6 +679,30 @@ async def get_att_data_from_pq( return pq, att_data, text +def get_main_rds(court: Court, pacer_doc_id: str) -> QuerySet: + """ + Return the main RECAPDocument queryset for a given court and pacer_doc_id. + :param court: The court to query. + :param pacer_doc_id: The pacer document ID. + :return: The main RECAPDocument queryset. + """ + main_rds_qs = ( + RECAPDocument.objects.select_related("docket_entry__docket") + .filter( + pacer_doc_id=pacer_doc_id, + docket_entry__docket__court=court, + ) + .order_by("docket_entry__docket__pacer_case_id") + .distinct("docket_entry__docket__pacer_case_id") + .only( + "pacer_doc_id", + "docket_entry__docket__pacer_case_id", + "docket_entry__docket__court_id", + ) + ) + return main_rds_qs + + async def find_subdocket_att_page_rds( pk: int, ) -> list[int]: @@ -690,40 +717,92 @@ async def find_subdocket_att_page_rds( court = await Court.objects.aget(id=pq.court_id) pq, att_data, text = await get_att_data_from_pq(pq) pacer_doc_id = att_data["pacer_doc_id"] - main_rds = ( - RECAPDocument.objects.select_related("docket_entry__docket") - .filter( - pacer_doc_id=pacer_doc_id, - docket_entry__docket__court=court, - ) - .order_by("docket_entry__docket__pacer_case_id") - .distinct("docket_entry__docket__pacer_case_id") - .only( - "pacer_doc_id", - "docket_entry__docket__pacer_case_id", - "docket_entry__docket__court_id", - ) - .exclude(docket_entry__docket__pacer_case_id=pq.pacer_case_id) + main_rds = get_main_rds(court, pacer_doc_id).exclude( + docket_entry__docket__pacer_case_id=pq.pacer_case_id ) pqs_to_process_pks = [ pq.pk ] # Add the original pq to the list of pqs to process original_file_content = text.encode("utf-8") original_file_name = pq.filepath_local.name - async for main_rd in main_rds: - main_pacer_case_id = main_rd.docket_entry.docket.pacer_case_id - # Create additional pqs for each subdocket case found. - pq_created = await ProcessingQueue.objects.acreate( - uploader_id=pq.uploader_id, - pacer_doc_id=pacer_doc_id, - pacer_case_id=main_pacer_case_id, - court_id=court.pk, - upload_type=UPLOAD_TYPE.ATTACHMENT_PAGE, - filepath_local=ContentFile( - original_file_content, name=original_file_name - ), + + @sync_to_async + def save_pq_instances(): + with transaction.atomic(): + for main_rd in main_rds: + main_pacer_case_id = main_rd.docket_entry.docket.pacer_case_id + # Create additional pqs for each subdocket case found. + pq_created = ProcessingQueue.objects.create( + uploader_id=pq.uploader_id, + pacer_doc_id=pacer_doc_id, + pacer_case_id=main_pacer_case_id, + court_id=court.pk, + upload_type=UPLOAD_TYPE.ATTACHMENT_PAGE, + filepath_local=ContentFile( + original_file_content, name=original_file_name + ), + ) + pqs_to_process_pks.append(pq_created.pk) + + await save_pq_instances() + return pqs_to_process_pks + + +async def find_subdocket_pdf_rds( + pk: int, +) -> list[int]: + """Look for RECAP Documents that belong to subdockets, and create a PQ + object for each additional PDF upload that requires processing. + + :param pk: Primary key of the processing queue item. + :return: A list of ProcessingQueue pks to process. + """ + + pq = await ProcessingQueue.objects.aget(pk=pk) + court = await Court.objects.aget(id=pq.court_id) + pacer_doc_id = pq.pacer_doc_id + main_rds = get_main_rds(court, pacer_doc_id) + pqs_to_process_pks = [ + pq.pk + ] # Add the original pq to the list of pqs to process + if pq.pacer_case_id: + main_rds = main_rds.exclude( + docket_entry__docket__pacer_case_id=pq.pacer_case_id ) - pqs_to_process_pks.append(pq_created.pk) + pdf_binary_content = pq.filepath_local.read() + + @sync_to_async + def save_pq_instances(): + with transaction.atomic(): + for i, main_rd in enumerate(main_rds): + if not pq.pacer_case_id and i == 0: + # If there's no pacer_case_id from the original PQ, + # set a pacer_case_id from one of the matched RDs + # to make the RD lookup process_recap_pdf succeed. + pq.pacer_case_id = ( + main_rd.docket_entry.docket.pacer_case_id + ) + pq.save() + continue + + main_pacer_case_id = main_rd.docket_entry.docket.pacer_case_id + # Create additional pqs for each subdocket case found. + pdf_file = ContentFile( + pdf_binary_content, name=pq.filepath_local.name + ) + pq_created = ProcessingQueue.objects.create( + uploader_id=pq.uploader_id, + pacer_doc_id=pacer_doc_id, + pacer_case_id=main_pacer_case_id, + document_number=pq.document_number, + attachment_number=pq.attachment_number, + court_id=court.pk, + upload_type=UPLOAD_TYPE.PDF, + filepath_local=pdf_file, + ) + pqs_to_process_pks.append(pq_created.pk) + + await save_pq_instances() return pqs_to_process_pks diff --git a/cl/recap/tests.py b/cl/recap/tests.py index bb249b6246..991f77617e 100644 --- a/cl/recap/tests.py +++ b/cl/recap/tests.py @@ -17,6 +17,7 @@ from django.core.files.base import ContentFile from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command +from django.db import transaction from django.test import RequestFactory, override_settings from django.urls import reverse from django.utils.timezone import now @@ -182,28 +183,6 @@ def setUpTestData(cls): ], ) - cls.att_data_2 = AppellateAttachmentPageFactory( - attachments=[ - AppellateAttachmentFactory( - pacer_doc_id="04505578698", attachment_number=1 - ), - AppellateAttachmentFactory( - pacer_doc_id="04505578699", attachment_number=2 - ), - ], - pacer_doc_id="04505578697", - pacer_case_id="104491", - document_number="1", - ) - cls.de_data_2 = DocketEntriesDataFactory( - docket_entries=[ - DocketEntryDataFactory( - pacer_doc_id="04505578697", - document_number=1, - ) - ], - ) - def setUp(self) -> None: self.async_client = AsyncAPIClient() self.user = User.objects.get(username="recap") @@ -793,39 +772,70 @@ def test_processing_an_acms_attachment_page(self, mock_upload): main_attachment[0].document_type, RECAPDocument.ATTACHMENT ) - def test_processing_subdocket_case_attachment_page(self, mock_upload): - """Can we replicate an attachment page upload from a subdocket case - to its corresponding RD across all related dockets? - """ - d_1 = DocketFactory( +class ReplicateRecapUploadsTest(TestCase): + """Test RECAP uploads are properly replicated to subdockets.""" + + @classmethod + def setUpTestData(cls): + cls.user = User.objects.get(username="recap") + cls.f = SimpleUploadedFile("file.txt", b"file content more content") + cls.court = CourtFactory.create(jurisdiction="FD", in_use=True) + cls.att_data_2 = AppellateAttachmentPageFactory( + attachments=[ + AppellateAttachmentFactory( + pacer_doc_id="04505578698", attachment_number=1 + ), + AppellateAttachmentFactory( + pacer_doc_id="04505578699", attachment_number=2 + ), + ], + pacer_doc_id="04505578697", + pacer_case_id="104491", + document_number="1", + ) + cls.de_data_2 = DocketEntriesDataFactory( + docket_entries=[ + DocketEntryDataFactory( + pacer_doc_id="04505578697", + document_number=1, + ) + ], + ) + + cls.d_1 = DocketFactory( source=Docket.RECAP, docket_number="23-4567", - court=self.court, + court=cls.court, pacer_case_id="104490", ) - d_2 = DocketFactory( + cls.d_2 = DocketFactory( source=Docket.RECAP, docket_number="23-4567", - court=self.court, + court=cls.court, pacer_case_id="104491", ) - d_3 = DocketFactory( + cls.d_3 = DocketFactory( source=Docket.RECAP, docket_number="23-4567", - court=self.court, + court=cls.court, pacer_case_id="104492", ) + def test_processing_subdocket_case_attachment_page(self): + """Can we replicate an attachment page upload from a subdocket case + to its corresponding RD across all related dockets? + """ + # Add the docket entry to every case. async_to_sync(add_docket_entries)( - d_1, self.de_data_2["docket_entries"] + self.d_1, self.de_data_2["docket_entries"] ) async_to_sync(add_docket_entries)( - d_2, self.de_data_2["docket_entries"] + self.d_2, self.de_data_2["docket_entries"] ) async_to_sync(add_docket_entries)( - d_3, self.de_data_2["docket_entries"] + self.d_3, self.de_data_2["docket_entries"] ) # Create an initial PQ. @@ -837,18 +847,18 @@ def test_processing_subdocket_case_attachment_page(self, mock_upload): filepath_local=self.f, ) d_1_recap_document = RECAPDocument.objects.filter( - docket_entry__docket=d_1 + docket_entry__docket=self.d_1 ) d_2_recap_document = RECAPDocument.objects.filter( - docket_entry__docket=d_2 + docket_entry__docket=self.d_2 ) d_3_recap_document = RECAPDocument.objects.filter( - docket_entry__docket=d_3 + docket_entry__docket=self.d_3 ) main_d_1_rd = d_1_recap_document[0] main_d_2_rd = d_2_recap_document[0] - main_d_3_rd = d_2_recap_document[0] + main_d_3_rd = d_3_recap_document[0] # After adding 1 docket entry, it should only exist its main RD on # every docket @@ -877,22 +887,22 @@ def test_processing_subdocket_case_attachment_page(self, mock_upload): self.assertEqual( d_1_recap_document.count(), 3, - msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {d_2.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {self.d_2.pacer_case_id}.", ) self.assertEqual( d_2_recap_document.count(), 3, - msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {d_1.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {self.d_1.pacer_case_id}.", ) self.assertEqual( d_3_recap_document.count(), 3, - msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {d_3.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {self.d_3.pacer_case_id}.", ) main_d_1_rd.refresh_from_db() main_d_2_rd.refresh_from_db() - main_d_2_rd.refresh_from_db() + main_d_3_rd.refresh_from_db() self.assertEqual( main_d_1_rd.pacer_doc_id, self.de_data_2["docket_entries"][0]["pacer_doc_id"], @@ -908,29 +918,32 @@ def test_processing_subdocket_case_attachment_page(self, mock_upload): # Two of them should be attachments. d_1_attachments = RECAPDocument.objects.filter( - docket_entry__docket=d_1, document_type=RECAPDocument.ATTACHMENT + docket_entry__docket=self.d_1, + document_type=RECAPDocument.ATTACHMENT, ) d_2_attachments = RECAPDocument.objects.filter( - docket_entry__docket=d_2, document_type=RECAPDocument.ATTACHMENT + docket_entry__docket=self.d_2, + document_type=RECAPDocument.ATTACHMENT, ) d_3_attachments = RECAPDocument.objects.filter( - docket_entry__docket=d_3, document_type=RECAPDocument.ATTACHMENT + docket_entry__docket=self.d_3, + document_type=RECAPDocument.ATTACHMENT, ) self.assertEqual( d_1_attachments.count(), 2, - msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {d_1.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {self.d_1.pacer_case_id}.", ) self.assertEqual( d_2_attachments.count(), 2, - msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {d_2.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {self.d_2.pacer_case_id}.", ) self.assertEqual( d_3_attachments.count(), 2, - msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {d_3.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs Attachments for the docket with PACER case ID {self.d_3.pacer_case_id}.", ) att_1_data = self.att_data_2["attachments"][0] @@ -969,7 +982,9 @@ def test_processing_subdocket_case_attachment_page(self, mock_upload): self.assertEqual(pqs_status, {PROCESSING_STATUS.SUCCESSFUL}) pqs_related_dockets = {pq.docket_id for pq in pqs_created} - self.assertEqual(pqs_related_dockets, {d_1.pk, d_2.pk, d_3.pk}) + self.assertEqual( + pqs_related_dockets, {self.d_1.pk, self.d_2.pk, self.d_3.pk} + ) # 3 PacerHtmlFiles should have been created, one for each case. att_html_created = PacerHtmlFiles.objects.all() @@ -981,29 +996,15 @@ def test_processing_subdocket_case_attachment_page(self, mock_upload): {de.pk for de in DocketEntry.objects.all()}, related_htmls_de ) - def test_process_attachments_for_subdocket_pq_with_missing_main_rd( - self, mock_upload - ): + def test_process_attachments_for_subdocket_pq_with_missing_main_rd(self): """Confirm that if the RD related to the initial PQ is missing, we can still process attachments for subdocket cases where the main RD matches. """ - d_1 = DocketFactory( - source=Docket.RECAP, - docket_number="23-4567", - court=self.court, - pacer_case_id="104490", - ) - d_2 = DocketFactory( - source=Docket.RECAP, - docket_number="23-4567", - court=self.court, - pacer_case_id="104491", - ) # Add the docket entry only to d_1. async_to_sync(add_docket_entries)( - d_1, self.de_data_2["docket_entries"] + self.d_1, self.de_data_2["docket_entries"] ) # Create an initial PQ related to d_1 @@ -1015,22 +1016,22 @@ def test_process_attachments_for_subdocket_pq_with_missing_main_rd( filepath_local=self.f, ) d_1_recap_document = RECAPDocument.objects.filter( - docket_entry__docket=d_1 + docket_entry__docket=self.d_1 ) d_2_recap_document = RECAPDocument.objects.filter( - docket_entry__docket=d_2 + docket_entry__docket=self.d_2 ) # After adding 1 docket entry d_1 self.assertEqual( d_1_recap_document.count(), 1, - msg=f"Didn't get the initial number of RDs for the docket with PACER case ID {d_1.pacer_case_id}", + msg=f"Didn't get the initial number of RDs for the docket with PACER case ID {self.d_1.pacer_case_id}", ) self.assertEqual( d_2_recap_document.count(), 0, - msg=f"Didn't get the initial number of RDs for the docket with PACER case ID {d_2.pacer_case_id}", + msg=f"Didn't get the initial number of RDs for the docket with PACER case ID {self.d_2.pacer_case_id}", ) with mock.patch( @@ -1044,12 +1045,12 @@ def test_process_attachments_for_subdocket_pq_with_missing_main_rd( self.assertEqual( d_1_recap_document.count(), 3, - msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {d_2.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {self.d_2.pacer_case_id}.", ) self.assertEqual( d_2_recap_document.count(), 0, - msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {d_1.pacer_case_id}.", + msg=f"Didn't get the expected number of RDs for the docket with PACER case ID {self.d_1.pacer_case_id}.", ) pq.refresh_from_db() @@ -1068,10 +1069,241 @@ def test_process_attachments_for_subdocket_pq_with_missing_main_rd( self.assertEqual(successful_pq[0].status, PROCESSING_STATUS.SUCCESSFUL) self.assertEqual( successful_pq[0].docket_id, - d_1.pk, + self.d_1.pk, msg="Didn't get the expected docket ID.", ) + @mock.patch("cl.recap.tasks.extract_recap_pdf_base") + def test_processing_subdocket_case_pdf_upload(self, mock_extract): + """Can we replicate a PDF document upload from a subdocket case + to its corresponding RD across all related dockets? + """ + + # Add the docket entry to every case. + async_to_sync(add_docket_entries)( + self.d_1, self.de_data_2["docket_entries"] + ) + async_to_sync(add_docket_entries)( + self.d_2, self.de_data_2["docket_entries"] + ) + async_to_sync(add_docket_entries)( + self.d_3, self.de_data_2["docket_entries"] + ) + + d_1_recap_document = RECAPDocument.objects.filter( + docket_entry__docket=self.d_1 + ) + d_2_recap_document = RECAPDocument.objects.filter( + docket_entry__docket=self.d_2 + ) + d_3_recap_document = RECAPDocument.objects.filter( + docket_entry__docket=self.d_3 + ) + + main_d_1_rd = d_1_recap_document[0] + main_d_2_rd = d_2_recap_document[0] + main_d_3_rd = d_3_recap_document[0] + + self.assertFalse(main_d_1_rd.is_available) + self.assertFalse(main_d_2_rd.is_available) + self.assertFalse(main_d_3_rd.is_available) + + # Two test cases: pacer_case_id and blank pacer_case_id + pacer_case_ids = ["104491", ""] + for pacer_case_id in pacer_case_ids: + with ( + self.subTest(pacer_case_id=pacer_case_id), + transaction.atomic(), + ): + # Create an initial PQ. + pq = ProcessingQueue.objects.create( + court=self.court, + uploader=self.user, + pacer_case_id=pacer_case_id, + pacer_doc_id="04505578697", + document_number=1, + upload_type=UPLOAD_TYPE.PDF, + filepath_local=self.f, + ) + + # Process the PDF upload. + async_to_sync(process_recap_upload)(pq) + + main_d_1_rd.refresh_from_db() + main_d_2_rd.refresh_from_db() + main_d_3_rd.refresh_from_db() + + self.assertTrue( + main_d_1_rd.is_available, + msg="is_available value doesn't match", + ) + self.assertTrue( + main_d_2_rd.is_available, + msg="is_available value doesn't match", + ) + self.assertTrue( + main_d_3_rd.is_available, + msg="is_available value doesn't match", + ) + + self.assertTrue(main_d_1_rd.filepath_local) + self.assertTrue(main_d_2_rd.filepath_local) + self.assertTrue(main_d_3_rd.filepath_local) + + # Assert the number of PQs created to process the additional subdocket RDs. + pqs_created = ProcessingQueue.objects.all() + self.assertEqual( + pqs_created.count(), + 3, + msg="The number of PQs doesn't match.", + ) + + pqs_status = {pq.status for pq in pqs_created} + self.assertEqual(pqs_status, {PROCESSING_STATUS.SUCCESSFUL}) + + pqs_related_dockets = {pq.docket_id for pq in pqs_created} + self.assertEqual( + pqs_related_dockets, + {self.d_1.pk, self.d_2.pk, self.d_3.pk}, + ) + pqs_related_docket_entries = { + pq.docket_entry_id for pq in pqs_created + } + self.assertEqual( + pqs_related_docket_entries, + { + main_d_1_rd.docket_entry.pk, + main_d_2_rd.docket_entry.pk, + main_d_3_rd.docket_entry.pk, + }, + ) + pqs_related_rds = {pq.recap_document_id for pq in pqs_created} + self.assertEqual( + pqs_related_rds, + {main_d_1_rd.pk, main_d_2_rd.pk, main_d_3_rd.pk}, + ) + + transaction.set_rollback(True) + + @mock.patch("cl.recap.tasks.extract_recap_pdf_base") + def test_processing_subdocket_case_pdf_attachment_upload( + self, mock_extract + ): + """Can we replicate a PDF attachment document upload from a subdocket case + to its corresponding RD across all related dockets? + """ + + # Add the docket entry to every case. + async_to_sync(add_docket_entries)( + self.d_1, self.de_data_2["docket_entries"] + ) + async_to_sync(add_docket_entries)( + self.d_2, self.de_data_2["docket_entries"] + ) + + pq_att = ProcessingQueue.objects.create( + court=self.court, + uploader=self.user, + pacer_case_id="104491", + upload_type=UPLOAD_TYPE.ATTACHMENT_PAGE, + filepath_local=self.f, + ) + + with mock.patch( + "cl.recap.tasks.get_data_from_att_report", + side_effect=lambda x, y: self.att_data_2, + ): + # Process the attachment page containing 2 attachments. + async_to_sync(process_recap_upload)(pq_att) + + d_1_recap_document = RECAPDocument.objects.filter( + docket_entry__docket=self.d_1 + ) + d_2_recap_document = RECAPDocument.objects.filter( + docket_entry__docket=self.d_2 + ) + self.assertEqual(d_1_recap_document.count(), 3) + self.assertEqual(d_2_recap_document.count(), 3) + + att_d_1_rd = d_1_recap_document.filter(attachment_number=2).first() + att_d_2_rd = d_2_recap_document.filter(attachment_number=2).first() + + self.assertFalse(att_d_1_rd.is_available) + self.assertFalse(att_d_2_rd.is_available) + + # Two test cases: pacer_case_id and blank pacer_case_id + pacer_case_ids = ["104491", ""] + for pacer_case_id in pacer_case_ids: + with ( + self.subTest(pacer_case_id=pacer_case_id), + transaction.atomic(), + ): + # Create an initial PQ. + pq = ProcessingQueue.objects.create( + court=self.court, + uploader=self.user, + pacer_case_id=pacer_case_id, + pacer_doc_id="04505578699", + document_number=1, + attachment_number=2, + upload_type=UPLOAD_TYPE.PDF, + filepath_local=self.f, + ) + + # Process the PDF upload. + async_to_sync(process_recap_upload)(pq) + + att_d_1_rd.refresh_from_db() + att_d_2_rd.refresh_from_db() + + self.assertTrue( + att_d_1_rd.is_available, + msg="is_available value doesn't match", + ) + self.assertTrue( + att_d_2_rd.is_available, + msg="is_available value doesn't match", + ) + + self.assertTrue(att_d_1_rd.filepath_local) + self.assertTrue(att_d_2_rd.filepath_local) + + # Assert the number of PQs created to process the additional subdocket RDs. + pqs_created = ProcessingQueue.objects.filter( + upload_type=UPLOAD_TYPE.PDF + ) + self.assertEqual( + pqs_created.count(), + 2, + msg="The number of PQs doesn't match.", + ) + + pqs_status = {pq.status for pq in pqs_created} + self.assertEqual(pqs_status, {PROCESSING_STATUS.SUCCESSFUL}) + + pqs_related_dockets = {pq.docket_id for pq in pqs_created} + self.assertEqual( + pqs_related_dockets, + {self.d_1.pk, self.d_2.pk}, + ) + pqs_related_docket_entries = { + pq.docket_entry_id for pq in pqs_created + } + self.assertEqual( + pqs_related_docket_entries, + { + att_d_1_rd.docket_entry.pk, + att_d_2_rd.docket_entry.pk, + }, + ) + pqs_related_rds = {pq.recap_document_id for pq in pqs_created} + self.assertEqual( + pqs_related_rds, + {att_d_1_rd.pk, att_d_2_rd.pk}, + ) + + transaction.set_rollback(True) + @mock.patch("cl.recap.tasks.DocketReport", new=fakes.FakeDocketReport) @mock.patch( From 65da6ede8818f39c0d31f77fc0a5eeb411cbf4fa Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Mon, 30 Dec 2024 10:39:46 -0600 Subject: [PATCH 02/21] fix(recap): Avoid PDF upload replication in appellate cases --- cl/recap/tasks.py | 54 +++++++++++++++++++++++++++-------------------- cl/recap/tests.py | 8 +++---- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/cl/recap/tasks.py b/cl/recap/tasks.py index 7e8fd676bc..874aec1455 100644 --- a/cl/recap/tasks.py +++ b/cl/recap/tasks.py @@ -679,10 +679,10 @@ async def get_att_data_from_pq( return pq, att_data, text -def get_main_rds(court: Court, pacer_doc_id: str) -> QuerySet: +def get_main_rds(court_id: str, pacer_doc_id: str) -> QuerySet: """ Return the main RECAPDocument queryset for a given court and pacer_doc_id. - :param court: The court to query. + :param court_id: The court ID to query. :param pacer_doc_id: The pacer document ID. :return: The main RECAPDocument queryset. """ @@ -690,7 +690,7 @@ def get_main_rds(court: Court, pacer_doc_id: str) -> QuerySet: RECAPDocument.objects.select_related("docket_entry__docket") .filter( pacer_doc_id=pacer_doc_id, - docket_entry__docket__court=court, + docket_entry__docket__court_id=court_id, ) .order_by("docket_entry__docket__pacer_case_id") .distinct("docket_entry__docket__pacer_case_id") @@ -714,10 +714,9 @@ async def find_subdocket_att_page_rds( """ pq = await ProcessingQueue.objects.aget(pk=pk) - court = await Court.objects.aget(id=pq.court_id) pq, att_data, text = await get_att_data_from_pq(pq) pacer_doc_id = att_data["pacer_doc_id"] - main_rds = get_main_rds(court, pacer_doc_id).exclude( + main_rds = get_main_rds(pq.court_id, pacer_doc_id).exclude( docket_entry__docket__pacer_case_id=pq.pacer_case_id ) pqs_to_process_pks = [ @@ -736,7 +735,7 @@ def save_pq_instances(): uploader_id=pq.uploader_id, pacer_doc_id=pacer_doc_id, pacer_case_id=main_pacer_case_id, - court_id=court.pk, + court_id=pq.court_id, upload_type=UPLOAD_TYPE.ATTACHMENT_PAGE, filepath_local=ContentFile( original_file_content, name=original_file_name @@ -759,26 +758,40 @@ async def find_subdocket_pdf_rds( """ pq = await ProcessingQueue.objects.aget(pk=pk) - court = await Court.objects.aget(id=pq.court_id) - pacer_doc_id = pq.pacer_doc_id - main_rds = get_main_rds(court, pacer_doc_id) + main_rds = get_main_rds(pq.court_id, pq.pacer_doc_id) pqs_to_process_pks = [ pq.pk ] # Add the original pq to the list of pqs to process + + appellate_court_ids = [ + court_pk + async for court_pk in ( + Court.federal_courts.appellate_pacer_courts().values_list( + "pk", flat=True + ) + ) + ] + if pq.court_id in appellate_court_ids: + # Abort the process for appellate documents. Subdockets cannot be found + # in appellate cases. + return pqs_to_process_pks + if pq.pacer_case_id: + # If pq already has a pacer_case_id, exclude it from the queryset. main_rds = main_rds.exclude( docket_entry__docket__pacer_case_id=pq.pacer_case_id ) + pdf_binary_content = pq.filepath_local.read() @sync_to_async def save_pq_instances(): with transaction.atomic(): for i, main_rd in enumerate(main_rds): - if not pq.pacer_case_id and i == 0: - # If there's no pacer_case_id from the original PQ, - # set a pacer_case_id from one of the matched RDs - # to make the RD lookup process_recap_pdf succeed. + if i == 0 and not pq.pacer_case_id: + # If the original PQ does not have a pacer_case_id, + # assign it a pacer_case_id from one of the matched RDs + # to ensure the RD lookup in process_recap_pdf succeeds. pq.pacer_case_id = ( main_rd.docket_entry.docket.pacer_case_id ) @@ -787,18 +800,17 @@ def save_pq_instances(): main_pacer_case_id = main_rd.docket_entry.docket.pacer_case_id # Create additional pqs for each subdocket case found. - pdf_file = ContentFile( - pdf_binary_content, name=pq.filepath_local.name - ) pq_created = ProcessingQueue.objects.create( uploader_id=pq.uploader_id, - pacer_doc_id=pacer_doc_id, + pacer_doc_id=pq.pacer_doc_id, pacer_case_id=main_pacer_case_id, document_number=pq.document_number, attachment_number=pq.attachment_number, - court_id=court.pk, + court_id=pq.court_id, upload_type=UPLOAD_TYPE.PDF, - filepath_local=pdf_file, + filepath_local=ContentFile( + pdf_binary_content, name=pq.filepath_local.name + ), ) pqs_to_process_pks.append(pq_created.pk) @@ -826,10 +838,6 @@ async def process_recap_attachment( await mark_pq_status(pq, "", PROCESSING_STATUS.IN_PROGRESS) logger.info(f"Processing RECAP item (debug is: {pq.debug}): {pq}") - pq = await ProcessingQueue.objects.aget(pk=pk) - await mark_pq_status(pq, "", PROCESSING_STATUS.IN_PROGRESS) - logger.info(f"Processing RECAP item (debug is: {pq.debug}): {pq}") - pq, att_data, text = await get_att_data_from_pq(pq) if document_number is None: diff --git a/cl/recap/tests.py b/cl/recap/tests.py index 991f77617e..eb27e32ba3 100644 --- a/cl/recap/tests.py +++ b/cl/recap/tests.py @@ -1075,8 +1075,8 @@ def test_process_attachments_for_subdocket_pq_with_missing_main_rd(self): @mock.patch("cl.recap.tasks.extract_recap_pdf_base") def test_processing_subdocket_case_pdf_upload(self, mock_extract): - """Can we replicate a PDF document upload from a subdocket case - to its corresponding RD across all related dockets? + """Can we duplicate a PDF document upload from a subdocket case to the + corresponding RD across all related dockets? """ # Add the docket entry to every case. @@ -1189,8 +1189,8 @@ def test_processing_subdocket_case_pdf_upload(self, mock_extract): def test_processing_subdocket_case_pdf_attachment_upload( self, mock_extract ): - """Can we replicate a PDF attachment document upload from a subdocket case - to its corresponding RD across all related dockets? + """Can we duplicate a PDF attachment document upload from a subdocket + case to the corresponding RD across all related dockets? """ # Add the docket entry to every case. From 839d39c3a4a92eced5b8a018fe327c8f1f2c918b Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:39:08 +0200 Subject: [PATCH 03/21] Fix finding document entries with a bad pacer_doc_id --- cl/recap/mergers.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index 0bbef5a5ec..64bc3eba70 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -934,16 +934,25 @@ async def add_docket_entries( rd = await RECAPDocument.objects.aget(**get_params) rds_updated.append(rd) except RECAPDocument.DoesNotExist: - try: - params["pacer_doc_id"] = docket_entry["pacer_doc_id"] - rd = await RECAPDocument.objects.acreate( - document_number=docket_entry["document_number"] or "", - is_available=False, - **params, - ) - except ValidationError: - # Happens from race conditions. - continue + rd = None + if de_created is False and not appelate_court_id_exists: + try: + # Check for documents with a bad pacer_doc_id + rd = await RECAPDocument.objects.aget(**params) + except RECAPDocument.DoesNotExist: + # Fallback to creating document + pass + if rd is None: + try: + params["pacer_doc_id"] = docket_entry["pacer_doc_id"] + rd = await RECAPDocument.objects.acreate( + document_number=docket_entry["document_number"] or "", + is_available=False, + **params, + ) + except ValidationError: + # Happens from race conditions. + continue rds_created.append(rd) except RECAPDocument.MultipleObjectsReturned: logger.info( From 6332cdb8e38e91084d3656e25b19f17c23d40b24 Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Fri, 3 Jan 2025 19:01:38 -0600 Subject: [PATCH 04/21] fix(recap): Added tests for matching a RECAPDocument with a bad pacer_doc_id --- cl/recap/factories.py | 1 + cl/recap/tests.py | 96 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/cl/recap/factories.py b/cl/recap/factories.py index 9b786ed4fd..64f3afb714 100644 --- a/cl/recap/factories.py +++ b/cl/recap/factories.py @@ -93,6 +93,7 @@ class RECAPEmailDocketEntryDataFactory(DictFactory): pacer_doc_id = Faker("random_id_string") pacer_magic_num = Faker("random_id_string") pacer_seq_no = Faker("random_id_string") + short_description = Faker("text", max_nb_chars=15) class RECAPEmailDocketDataFactory(DictFactory): diff --git a/cl/recap/tests.py b/cl/recap/tests.py index bb249b6246..d82b06354a 100644 --- a/cl/recap/tests.py +++ b/cl/recap/tests.py @@ -1072,6 +1072,102 @@ def test_process_attachments_for_subdocket_pq_with_missing_main_rd( msg="Didn't get the expected docket ID.", ) + def test_match_recap_document_with_wrong_pacer_doc_id(self, mock_upload): + """Confirm that when an existing RECAPDocument has an invalid + pacer_doc_id, we can still match it after excluding the pacer_doc_id + from the lookup. + """ + + de_data = DocketEntriesDataFactory( + docket_entries=[ + RECAPEmailDocketEntryDataFactory( + pacer_doc_id="04505578690", + document_number=5, + ) + ], + ) + de = DocketEntryWithParentsFactory( + docket__court=self.court, entry_number=5 + ) + rd = RECAPDocumentFactory( + docket_entry=de, + document_type=RECAPDocument.PACER_DOCUMENT, + pacer_doc_id="04505578691", + document_number="5", + description="", + ) + # Add the docket entry with the updated pacer_doc_id + async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) + recap_documents = RECAPDocument.objects.all() + self.assertEqual( + recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" + ) + rd.refresh_from_db() + self.assertEqual( + rd.description, + de_data["docket_entries"][0]["short_description"], + msg="The short description doesn't match.", + ) + self.assertEqual( + rd.pacer_doc_id, + de_data["docket_entries"][0]["pacer_doc_id"], + msg="The pacer_doc_id doesn't match.", + ) + + def test_match_recap_document_with_wrong_pacer_doc_id_duplicated( + self, mock_upload + ): + """Confirm that when an existing RECAPDocument has an invalid + pacer_doc_id, we can still match it after excluding the pacer_doc_id + from the lookup, even if there is more than one PACER_DOCUMENT that + belongs to the docket entry. + """ + + de_data = DocketEntriesDataFactory( + docket_entries=[ + RECAPEmailDocketEntryDataFactory( + pacer_doc_id="04505578690", + document_number=5, + ) + ], + ) + de = DocketEntryWithParentsFactory( + docket__court=self.court, entry_number=5 + ) + RECAPDocumentFactory( + document_type=RECAPDocument.PACER_DOCUMENT, + docket_entry=de, + pacer_doc_id="04505578691", + document_number="5", + description="", + ) + rd_2 = RECAPDocumentFactory( + document_type=RECAPDocument.PACER_DOCUMENT, + docket_entry=de, + pacer_doc_id="04505578691", + document_number="6", + description="", + is_available=True, + ) + # Add the docket entry with the updated pacer_doc_id, remove the + # duplicated RD, and keep the one that is available. + async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) + recap_documents = RECAPDocument.objects.all() + self.assertEqual( + recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" + ) + rd_2.refresh_from_db() + self.assertEqual( + rd_2.description, + de_data["docket_entries"][0]["short_description"], + msg="The short description doesn't match.", + ) + self.assertEqual( + rd_2.pacer_doc_id, + de_data["docket_entries"][0]["pacer_doc_id"], + msg="The pacer_doc_id doesn't match.", + ) + @mock.patch("cl.recap.tasks.DocketReport", new=fakes.FakeDocketReport) @mock.patch( From aee59120a742ba51ef531cbd0a0a6a2f080b5080 Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Sat, 4 Jan 2025 11:20:36 +0200 Subject: [PATCH 05/21] Update pacer_doc_id from docket_entry --- cl/recap/mergers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index 64bc3eba70..eb26e75fb6 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -971,7 +971,8 @@ async def add_docket_entries( rd = await duplicate_rd_queryset.alatest("date_created") await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() - rd.pacer_doc_id = rd.pacer_doc_id or docket_entry["pacer_doc_id"] + if docket_entry["pacer_doc_id"]: + rd.pacer_doc_id = docket_entry["pacer_doc_id"] description = docket_entry.get("short_description") if rd.document_type == RECAPDocument.PACER_DOCUMENT and description: rd.description = description From 48a4a0c963ae8261e4aa81d32673ee8149cc7523 Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Sat, 4 Jan 2025 11:33:43 +0200 Subject: [PATCH 06/21] Handle duplicate documents --- cl/recap/mergers.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index eb26e75fb6..cbba4cf29e 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -942,6 +942,20 @@ async def add_docket_entries( except RECAPDocument.DoesNotExist: # Fallback to creating document pass + except RECAPDocument.MultipleObjectsReturned: + duplicate_rd_queryset = RECAPDocument.objects.filter( + **params + ) + rd_with_pdf_queryset = duplicate_rd_queryset.filter( + is_available=True + ).exclude(filepath_local="") + if await rd_with_pdf_queryset.aexists(): + rd = await rd_with_pdf_queryset.alatest("date_created") + else: + rd = await duplicate_rd_queryset.alatest( + "date_created" + ) + await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() if rd is None: try: params["pacer_doc_id"] = docket_entry["pacer_doc_id"] From 0d93d2bfffdf8785cd87a33f939c58ecc6606469 Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Sat, 4 Jan 2025 12:02:13 +0200 Subject: [PATCH 07/21] Refactor duplicate cleaning logic into function --- cl/recap/mergers.py | 69 ++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index cbba4cf29e..f9e62a64ed 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -822,6 +822,23 @@ async def get_or_make_docket_entry( return de, de_created +async def clean_duplicate_documents(params) -> RECAPDocument: + duplicate_rd_queryset = RECAPDocument.objects.filter( + **params + ) + rd_with_pdf_queryset = duplicate_rd_queryset.filter( + is_available=True + ).exclude(filepath_local="") + if await rd_with_pdf_queryset.aexists(): + rd = await rd_with_pdf_queryset.alatest("date_created") + else: + rd = await duplicate_rd_queryset.alatest( + "date_created" + ) + await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() + return rd + + async def add_docket_entries( d: Docket, docket_entries: list[dict[str, Any]], @@ -943,19 +960,7 @@ async def add_docket_entries( # Fallback to creating document pass except RECAPDocument.MultipleObjectsReturned: - duplicate_rd_queryset = RECAPDocument.objects.filter( - **params - ) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( - is_available=True - ).exclude(filepath_local="") - if await rd_with_pdf_queryset.aexists(): - rd = await rd_with_pdf_queryset.alatest("date_created") - else: - rd = await duplicate_rd_queryset.alatest( - "date_created" - ) - await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() + rd = await clean_duplicate_documents(params) if rd is None: try: params["pacer_doc_id"] = docket_entry["pacer_doc_id"] @@ -975,15 +980,7 @@ async def add_docket_entries( ) if params["document_type"] == RECAPDocument.ATTACHMENT: continue - duplicate_rd_queryset = RECAPDocument.objects.filter(**params) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( - is_available=True - ).exclude(filepath_local="") - if await rd_with_pdf_queryset.aexists(): - rd = await rd_with_pdf_queryset.alatest("date_created") - else: - rd = await duplicate_rd_queryset.alatest("date_created") - await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() + rd = await clean_duplicate_documents(params) if docket_entry["pacer_doc_id"]: rd.pacer_doc_id = docket_entry["pacer_doc_id"] @@ -1697,15 +1694,7 @@ async def merge_attachment_page_data( except RECAPDocument.MultipleObjectsReturned as exc: if pacer_case_id: - duplicate_rd_queryset = RECAPDocument.objects.filter(**params) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( - is_available=True - ).exclude(filepath_local="") - if await rd_with_pdf_queryset.aexists(): - keep_rd = await rd_with_pdf_queryset.alatest("date_created") - else: - keep_rd = await duplicate_rd_queryset.alatest("date_created") - await duplicate_rd_queryset.exclude(pk=keep_rd.pk).adelete() + await clean_duplicate_documents(params) main_rd = await RECAPDocument.objects.select_related( "docket_entry", "docket_entry__docket" ).aget(**params) @@ -1735,23 +1724,7 @@ async def merge_attachment_page_data( break except RECAPDocument.MultipleObjectsReturned as exc: if pacer_case_id: - duplicate_rd_queryset = RECAPDocument.objects.filter( - **params - ) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( - is_available=True - ).exclude(filepath_local="") - if await rd_with_pdf_queryset.aexists(): - keep_rd = await rd_with_pdf_queryset.alatest( - "date_created" - ) - else: - keep_rd = await duplicate_rd_queryset.alatest( - "date_created" - ) - await duplicate_rd_queryset.exclude( - pk=keep_rd.pk - ).adelete() + await clean_duplicate_documents(params) main_rd = await RECAPDocument.objects.select_related( "docket_entry", "docket_entry__docket" ).aget(**params) From a822888d592bbe6b9bb945a7c17dc6efd9cec7b2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 10:02:56 +0000 Subject: [PATCH 08/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cl/recap/mergers.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index f9e62a64ed..16d7292c48 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -823,18 +823,14 @@ async def get_or_make_docket_entry( async def clean_duplicate_documents(params) -> RECAPDocument: - duplicate_rd_queryset = RECAPDocument.objects.filter( - **params - ) + duplicate_rd_queryset = RECAPDocument.objects.filter(**params) rd_with_pdf_queryset = duplicate_rd_queryset.filter( is_available=True ).exclude(filepath_local="") if await rd_with_pdf_queryset.aexists(): rd = await rd_with_pdf_queryset.alatest("date_created") else: - rd = await duplicate_rd_queryset.alatest( - "date_created" - ) + rd = await duplicate_rd_queryset.alatest("date_created") await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() return rd From a8c3d9e6a091557198ca3b3041d981e163982427 Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:51:29 +0200 Subject: [PATCH 09/21] Add types/docstring to clean_duplicate_documents Co-authored-by: Alberto Islas --- cl/recap/mergers.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index 16d7292c48..fb304c2e56 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -822,7 +822,13 @@ async def get_or_make_docket_entry( return de, de_created -async def clean_duplicate_documents(params) -> RECAPDocument: +async def clean_duplicate_documents(params:dict[str, Any]) -> RECAPDocument: + """ Removes duplicate RECAPDocuments, keeping the most recent with PDF if + available or otherwise the most recent overall. + + :param params: Query parameters to filter the RECAPDocuments. + :return: The matched RECAPDocument after cleaning. + """ duplicate_rd_queryset = RECAPDocument.objects.filter(**params) rd_with_pdf_queryset = duplicate_rd_queryset.filter( is_available=True From b430d231189cc7b337292abcd713e9e11cfa7a2c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:52:05 +0000 Subject: [PATCH 10/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cl/recap/mergers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index fb304c2e56..d9cdb62da2 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -822,8 +822,8 @@ async def get_or_make_docket_entry( return de, de_created -async def clean_duplicate_documents(params:dict[str, Any]) -> RECAPDocument: - """ Removes duplicate RECAPDocuments, keeping the most recent with PDF if +async def clean_duplicate_documents(params: dict[str, Any]) -> RECAPDocument: + """Removes duplicate RECAPDocuments, keeping the most recent with PDF if available or otherwise the most recent overall. :param params: Query parameters to filter the RECAPDocuments. From eb9cf9c53d4e8f21d24b4c82b5f5d455cac6d58c Mon Sep 17 00:00:00 2001 From: ttys0dev <126845556+ttys0dev@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:00:20 +0200 Subject: [PATCH 11/21] Add keep_latest_rd_document method --- cl/recap/mergers.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index d9cdb62da2..a7f07303f0 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -822,25 +822,35 @@ async def get_or_make_docket_entry( return de, de_created -async def clean_duplicate_documents(params: dict[str, Any]) -> RECAPDocument: +async def keep_latest_rd_document(queryset: QuerySet) -> RECAPDocument: """Removes duplicate RECAPDocuments, keeping the most recent with PDF if available or otherwise the most recent overall. - :param params: Query parameters to filter the RECAPDocuments. + :param params: RECAPDocument QuerySet to clean duplicates from. :return: The matched RECAPDocument after cleaning. """ - duplicate_rd_queryset = RECAPDocument.objects.filter(**params) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( + rd_with_pdf_queryset = queryset.filter( is_available=True ).exclude(filepath_local="") if await rd_with_pdf_queryset.aexists(): rd = await rd_with_pdf_queryset.alatest("date_created") else: - rd = await duplicate_rd_queryset.alatest("date_created") - await duplicate_rd_queryset.exclude(pk=rd.pk).adelete() + rd = await queryset.alatest("date_created") + await queryset.exclude(pk=rd.pk).adelete() return rd +async def clean_duplicate_documents(params: dict[str, Any]) -> RECAPDocument: + """Removes duplicate RECAPDocuments, keeping the most recent with PDF if + available or otherwise the most recent overall. + + :param params: Query parameters to filter the RECAPDocuments. + :return: The matched RECAPDocument after cleaning. + """ + duplicate_rd_queryset = RECAPDocument.objects.filter(**params) + return await keep_latest_rd_document(duplicate_rd_queryset) + + async def add_docket_entries( d: Docket, docket_entries: list[dict[str, Any]], @@ -1627,14 +1637,7 @@ async def clean_duplicate_attachment_entries( ) async for dupe in dupes.aiterator(): duplicate_rd_queryset = rds.filter(pacer_doc_id=dupe.pacer_doc_id) - rd_with_pdf_queryset = duplicate_rd_queryset.filter( - is_available=True - ).exclude(filepath_local="") - if await rd_with_pdf_queryset.aexists(): - keep_rd = await rd_with_pdf_queryset.alatest("date_created") - else: - keep_rd = await duplicate_rd_queryset.alatest("date_created") - await duplicate_rd_queryset.exclude(pk=keep_rd.pk).adelete() + await keep_latest_rd_document(duplicate_rd_queryset) async def merge_attachment_page_data( From 35c9536326b77d11482a7be76ccdf360fdf68fa3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:01:09 +0000 Subject: [PATCH 12/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cl/recap/mergers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index a7f07303f0..a554b9ae65 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -829,9 +829,9 @@ async def keep_latest_rd_document(queryset: QuerySet) -> RECAPDocument: :param params: RECAPDocument QuerySet to clean duplicates from. :return: The matched RECAPDocument after cleaning. """ - rd_with_pdf_queryset = queryset.filter( - is_available=True - ).exclude(filepath_local="") + rd_with_pdf_queryset = queryset.filter(is_available=True).exclude( + filepath_local="" + ) if await rd_with_pdf_queryset.aexists(): rd = await rd_with_pdf_queryset.alatest("date_created") else: From 3388e05fa7a2bcafe670b8e740fe709d9ba227d6 Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Mon, 6 Jan 2025 14:50:29 -0600 Subject: [PATCH 13/21] fix(recap): Fix append rd created and tweak docstrings --- cl/recap/mergers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cl/recap/mergers.py b/cl/recap/mergers.py index a554b9ae65..95fd75cc98 100644 --- a/cl/recap/mergers.py +++ b/cl/recap/mergers.py @@ -823,10 +823,10 @@ async def get_or_make_docket_entry( async def keep_latest_rd_document(queryset: QuerySet) -> RECAPDocument: - """Removes duplicate RECAPDocuments, keeping the most recent with PDF if - available or otherwise the most recent overall. + """Retains the most recent item with a PDF, if available otherwise, + retains the most recent item overall. - :param params: RECAPDocument QuerySet to clean duplicates from. + :param queryset: RECAPDocument QuerySet to clean duplicates from. :return: The matched RECAPDocument after cleaning. """ rd_with_pdf_queryset = queryset.filter(is_available=True).exclude( @@ -981,10 +981,10 @@ async def add_docket_entries( is_available=False, **params, ) + rds_created.append(rd) except ValidationError: # Happens from race conditions. continue - rds_created.append(rd) except RECAPDocument.MultipleObjectsReturned: logger.info( "Multiple recap documents found for document entry number'%s' " From f68adfcef589e311c6c6f7024071fc0a99aa7697 Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Tue, 7 Jan 2025 16:03:38 -0600 Subject: [PATCH 14/21] fix(recap): Fixed RecapUploadsTest merge conflicts --- cl/recap/tests.py | 192 +++++++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/cl/recap/tests.py b/cl/recap/tests.py index 9c75f93eff..5013ff062c 100644 --- a/cl/recap/tests.py +++ b/cl/recap/tests.py @@ -772,6 +772,102 @@ def test_processing_an_acms_attachment_page(self, mock_upload): main_attachment[0].document_type, RECAPDocument.ATTACHMENT ) + def test_match_recap_document_with_wrong_pacer_doc_id(self, mock_upload): + """Confirm that when an existing RECAPDocument has an invalid + pacer_doc_id, we can still match it after excluding the pacer_doc_id + from the lookup. + """ + + de_data = DocketEntriesDataFactory( + docket_entries=[ + RECAPEmailDocketEntryDataFactory( + pacer_doc_id="04505578690", + document_number=5, + ) + ], + ) + de = DocketEntryWithParentsFactory( + docket__court=self.court, entry_number=5 + ) + rd = RECAPDocumentFactory( + docket_entry=de, + document_type=RECAPDocument.PACER_DOCUMENT, + pacer_doc_id="04505578691", + document_number="5", + description="", + ) + # Add the docket entry with the updated pacer_doc_id + async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) + recap_documents = RECAPDocument.objects.all() + self.assertEqual( + recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" + ) + rd.refresh_from_db() + self.assertEqual( + rd.description, + de_data["docket_entries"][0]["short_description"], + msg="The short description doesn't match.", + ) + self.assertEqual( + rd.pacer_doc_id, + de_data["docket_entries"][0]["pacer_doc_id"], + msg="The pacer_doc_id doesn't match.", + ) + + def test_match_recap_document_with_wrong_pacer_doc_id_duplicated( + self, mock_upload + ): + """Confirm that when an existing RECAPDocument has an invalid + pacer_doc_id, we can still match it after excluding the pacer_doc_id + from the lookup, even if there is more than one PACER_DOCUMENT that + belongs to the docket entry. + """ + + de_data = DocketEntriesDataFactory( + docket_entries=[ + RECAPEmailDocketEntryDataFactory( + pacer_doc_id="04505578690", + document_number=5, + ) + ], + ) + de = DocketEntryWithParentsFactory( + docket__court=self.court, entry_number=5 + ) + RECAPDocumentFactory( + document_type=RECAPDocument.PACER_DOCUMENT, + docket_entry=de, + pacer_doc_id="04505578691", + document_number="5", + description="", + ) + rd_2 = RECAPDocumentFactory( + document_type=RECAPDocument.PACER_DOCUMENT, + docket_entry=de, + pacer_doc_id="04505578691", + document_number="6", + description="", + is_available=True, + ) + # Add the docket entry with the updated pacer_doc_id, remove the + # duplicated RD, and keep the one that is available. + async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) + recap_documents = RECAPDocument.objects.all() + self.assertEqual( + recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" + ) + rd_2.refresh_from_db() + self.assertEqual( + rd_2.description, + de_data["docket_entries"][0]["short_description"], + msg="The short description doesn't match.", + ) + self.assertEqual( + rd_2.pacer_doc_id, + de_data["docket_entries"][0]["pacer_doc_id"], + msg="The pacer_doc_id doesn't match.", + ) + class ReplicateRecapUploadsTest(TestCase): """Test RECAP uploads are properly replicated to subdockets.""" @@ -1304,102 +1400,6 @@ def test_processing_subdocket_case_pdf_attachment_upload( transaction.set_rollback(True) - def test_match_recap_document_with_wrong_pacer_doc_id(self, mock_upload): - """Confirm that when an existing RECAPDocument has an invalid - pacer_doc_id, we can still match it after excluding the pacer_doc_id - from the lookup. - """ - - de_data = DocketEntriesDataFactory( - docket_entries=[ - RECAPEmailDocketEntryDataFactory( - pacer_doc_id="04505578690", - document_number=5, - ) - ], - ) - de = DocketEntryWithParentsFactory( - docket__court=self.court, entry_number=5 - ) - rd = RECAPDocumentFactory( - docket_entry=de, - document_type=RECAPDocument.PACER_DOCUMENT, - pacer_doc_id="04505578691", - document_number="5", - description="", - ) - # Add the docket entry with the updated pacer_doc_id - async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) - recap_documents = RECAPDocument.objects.all() - self.assertEqual( - recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" - ) - rd.refresh_from_db() - self.assertEqual( - rd.description, - de_data["docket_entries"][0]["short_description"], - msg="The short description doesn't match.", - ) - self.assertEqual( - rd.pacer_doc_id, - de_data["docket_entries"][0]["pacer_doc_id"], - msg="The pacer_doc_id doesn't match.", - ) - - def test_match_recap_document_with_wrong_pacer_doc_id_duplicated( - self, mock_upload - ): - """Confirm that when an existing RECAPDocument has an invalid - pacer_doc_id, we can still match it after excluding the pacer_doc_id - from the lookup, even if there is more than one PACER_DOCUMENT that - belongs to the docket entry. - """ - - de_data = DocketEntriesDataFactory( - docket_entries=[ - RECAPEmailDocketEntryDataFactory( - pacer_doc_id="04505578690", - document_number=5, - ) - ], - ) - de = DocketEntryWithParentsFactory( - docket__court=self.court, entry_number=5 - ) - RECAPDocumentFactory( - document_type=RECAPDocument.PACER_DOCUMENT, - docket_entry=de, - pacer_doc_id="04505578691", - document_number="5", - description="", - ) - rd_2 = RECAPDocumentFactory( - document_type=RECAPDocument.PACER_DOCUMENT, - docket_entry=de, - pacer_doc_id="04505578691", - document_number="6", - description="", - is_available=True, - ) - # Add the docket entry with the updated pacer_doc_id, remove the - # duplicated RD, and keep the one that is available. - async_to_sync(add_docket_entries)(de.docket, de_data["docket_entries"]) - recap_documents = RECAPDocument.objects.all() - self.assertEqual( - recap_documents.count(), 1, msg="Wrong number of RECAPDocuments" - ) - rd_2.refresh_from_db() - self.assertEqual( - rd_2.description, - de_data["docket_entries"][0]["short_description"], - msg="The short description doesn't match.", - ) - self.assertEqual( - rd_2.pacer_doc_id, - de_data["docket_entries"][0]["pacer_doc_id"], - msg="The pacer_doc_id doesn't match.", - ) - @mock.patch("cl.recap.tasks.DocketReport", new=fakes.FakeDocketReport) @mock.patch( From dfee2d57df602426ab405f83be113d276abebbed Mon Sep 17 00:00:00 2001 From: Alberto Islas Date: Tue, 7 Jan 2025 16:40:33 -0600 Subject: [PATCH 15/21] fix(recap): Simplified PACER court validation queries --- cl/recap/api_serializers.py | 34 ++++++++++++---------------------- cl/recap/tasks.py | 11 ++--------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/cl/recap/api_serializers.py b/cl/recap/api_serializers.py index e20c5be0a8..48fc52ef66 100644 --- a/cl/recap/api_serializers.py +++ b/cl/recap/api_serializers.py @@ -95,10 +95,10 @@ def validate(self, attrs): UPLOAD_TYPE.CASE_QUERY_RESULT_PAGE, ]: # These are district or bankruptcy court dockets. Is the court valid? - court_ids = Court.federal_courts.district_or_bankruptcy_pacer_courts().values_list( - "pk", flat=True + court_ids = ( + Court.federal_courts.district_or_bankruptcy_pacer_courts() ) - if attrs["court"].pk not in court_ids: + if not court_ids.filter(pk=attrs["court"].pk).exists(): raise ValidationError( "%s is not a district or bankruptcy court ID. Did you " "mean to use the upload_type for appellate dockets?" @@ -108,11 +108,9 @@ def validate(self, attrs): if attrs["upload_type"] == UPLOAD_TYPE.CLAIMS_REGISTER: # Only allowed on bankruptcy courts bankruptcy_court_ids = ( - Court.federal_courts.bankruptcy_pacer_courts().values_list( - "pk", flat=True - ) + Court.federal_courts.bankruptcy_pacer_courts() ) - if attrs["court"].pk not in bankruptcy_court_ids: + if not bankruptcy_court_ids.filter(pk=attrs["court"].pk).exists(): raise ValidationError( "%s is not a bankruptcy court ID. Only bankruptcy cases " "should have claims registry pages." % attrs["court"] @@ -127,12 +125,8 @@ def validate(self, attrs): UPLOAD_TYPE.APPELLATE_CASE_QUERY_RESULT_PAGE, ]: # Appellate court dockets. Is the court valid? - appellate_court_ids = ( - Court.federal_courts.appellate_pacer_courts().values_list( - "pk", flat=True - ) - ) - if attrs["court"].pk not in appellate_court_ids: + appellate_court_ids = Court.federal_courts.appellate_pacer_courts() + if not appellate_court_ids.filter(pk=attrs["court"].pk).exists(): raise ValidationError( "%s is not an appellate court ID. Did you mean to use the " "upload_type for district dockets?" % attrs["court"] @@ -203,11 +197,8 @@ def validate(self, attrs): mail = attrs["mail"] receipt = attrs["receipt"] - all_court_ids = Court.federal_courts.all_pacer_courts().values_list( - "pk", flat=True - ) - - if court_id not in all_court_ids: + all_court_ids = Court.federal_courts.all_pacer_courts() + if not all_court_ids.filter(pk=court_id).exists(): raise ValidationError( f"{attrs['court'].pk} is not a PACER court ID." ) @@ -274,10 +265,9 @@ class Meta: def validate(self, attrs): # Is it a good court value? - valid_court_ids = Court.federal_courts.district_or_bankruptcy_pacer_courts().values_list( - "pk", flat=True + valid_court_ids = ( + Court.federal_courts.district_or_bankruptcy_pacer_courts() ) - if ( attrs.get("court") or attrs.get("docket") @@ -293,7 +283,7 @@ def validate(self, attrs): if attrs.get("court") else attrs["docket"].court_id ) - if court_id not in valid_court_ids: + if not valid_court_ids.filter(pk=court_id).exists(): raise ValidationError(f"Invalid court id: {court_id}") # Docket validations diff --git a/cl/recap/tasks.py b/cl/recap/tasks.py index 874aec1455..ee674a9f25 100644 --- a/cl/recap/tasks.py +++ b/cl/recap/tasks.py @@ -763,15 +763,8 @@ async def find_subdocket_pdf_rds( pq.pk ] # Add the original pq to the list of pqs to process - appellate_court_ids = [ - court_pk - async for court_pk in ( - Court.federal_courts.appellate_pacer_courts().values_list( - "pk", flat=True - ) - ) - ] - if pq.court_id in appellate_court_ids: + appellate_court_ids = Court.federal_courts.appellate_pacer_courts() + if await appellate_court_ids.filter(pk=pq.court_id).aexists(): # Abort the process for appellate documents. Subdockets cannot be found # in appellate cases. return pqs_to_process_pks From 12e75e3b2c7d7ecc4f232dd4a5d0dcb736b5a468 Mon Sep 17 00:00:00 2001 From: grossir <14970769+grossir@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:33:02 +0000 Subject: [PATCH 16/21] Update freelawproject dependencies --- poetry.lock | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3703770058..d38d4a5859 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand. [[package]] name = "ada-url" @@ -6,6 +6,7 @@ version = "1.15.3" description = "URL parser and manipulator based on the WHAT WG URL standard" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "ada_url-1.15.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:486ed6775faaf915efb82e4dea9224d388ca743aa572996240ffda20e19dd769"}, {file = "ada_url-1.15.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:cf0facdc4e66cadafdfb7ccb914e03aae2571dd8f70a28531a60019d8888641b"}, @@ -74,6 +75,7 @@ version = "5.2.0" description = "Low-level AMQP client for Python (fork of amqplib)." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, @@ -88,6 +90,7 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, @@ -99,6 +102,7 @@ version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, @@ -119,6 +123,7 @@ version = "1.4.0" description = "Python command-line parsing library" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"}, {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"}, @@ -130,6 +135,7 @@ version = "3.8.1" description = "ASGI specs, helper code, and adapters" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, @@ -144,6 +150,7 @@ version = "0.8.1" description = "Read/rewrite/write Python ASTs" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["dev"] files = [ {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, @@ -155,6 +162,7 @@ version = "3.3.5" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" +groups = ["dev"] files = [ {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, @@ -166,6 +174,7 @@ version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, @@ -184,6 +193,7 @@ version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, @@ -203,6 +213,7 @@ version = "24.4.2" description = "WebSocket client & server library, WAMP real-time framework" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "autobahn-24.4.2-py2.py3-none-any.whl", hash = "sha256:c56a2abe7ac78abbfb778c02892d673a4de58fd004d088cd7ab297db25918e81"}, {file = "autobahn-24.4.2.tar.gz", hash = "sha256:a2d71ef1b0cf780b6d11f8b205fd2c7749765e65795f2ea7d823796642ee92c9"}, @@ -232,6 +243,7 @@ version = "24.8.1" description = "Self-service finite-state machines for the programmer on the go." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "Automat-24.8.1-py3-none-any.whl", hash = "sha256:bf029a7bc3da1e2c24da2343e7598affaa9f10bf0ab63ff808566ce90551e02a"}, {file = "automat-24.8.1.tar.gz", hash = "sha256:b34227cf63f6325b8ad2399ede780675083e439b20c323d376373d8ee6306d88"}, @@ -246,6 +258,7 @@ version = "4.12.3" description = "Screen-scraping library" optional = false python-versions = ">=3.6.0" +groups = ["main"] files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, @@ -267,6 +280,7 @@ version = "4.2.1" description = "Python multiprocessing fork with improvements and bugfixes" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "billiard-4.2.1-py3-none-any.whl", hash = "sha256:40b59a4ac8806ba2c2369ea98d876bc6108b051c227baffd928c644d15d8f3cb"}, {file = "billiard-4.2.1.tar.gz", hash = "sha256:12b641b0c539073fc8d3f5b8b7be998956665c4233c7c1fcd66a7e677c4fb36f"}, @@ -278,6 +292,7 @@ version = "24.10.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, @@ -322,6 +337,7 @@ version = "1.35.44" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "boto3-1.35.44-py3-none-any.whl", hash = "sha256:18416d07b41e6094101a44f8b881047dcec6b846dad0b9f83b9bbf2f0cd93d07"}, {file = "boto3-1.35.44.tar.gz", hash = "sha256:7f8e8a252458d584d8cf7877c372c4f74ec103356eedf43d2dd9e479f47f3639"}, @@ -341,6 +357,7 @@ version = "1.35.44" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "botocore-1.35.44-py3-none-any.whl", hash = "sha256:55388e80624401d017a9a2b8109afd94814f7e666b53e28fce51375cfa8d9326"}, {file = "botocore-1.35.44.tar.gz", hash = "sha256:1fcd97b966ad8a88de4106fe1bd3bbd6d8dadabe99bbd4a6aadcf11cb6c66b39"}, @@ -360,6 +377,7 @@ version = "5.4.0" description = "Distributed Task Queue." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "celery-5.4.0-py3-none-any.whl", hash = "sha256:369631eb580cf8c51a82721ec538684994f8277637edde2dfc0dacd73ed97f64"}, {file = "celery-5.4.0.tar.gz", hash = "sha256:504a19140e8d3029d5acad88330c541d4c3f64c789d85f94756762d8bca7e706"}, @@ -416,6 +434,7 @@ version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main", "dev"] files = [ {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, @@ -427,6 +446,7 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -496,6 +516,7 @@ files = [ {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] +markers = {dev = "platform_python_implementation != \"PyPy\""} [package.dependencies] pycparser = "*" @@ -506,6 +527,7 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -517,6 +539,7 @@ version = "5.2.0" description = "Universal encoding detector for Python 3" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, @@ -528,6 +551,7 @@ version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" +groups = ["main", "dev"] files = [ {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, @@ -642,6 +666,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -656,6 +681,7 @@ version = "0.3.1" description = "Enables git-like *did-you-mean* feature in click" optional = false python-versions = ">=3.6.2" +groups = ["main"] files = [ {file = "click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c"}, {file = "click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463"}, @@ -670,6 +696,7 @@ version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, @@ -687,6 +714,7 @@ version = "0.3.0" description = "REPL plugin for Click" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, @@ -705,6 +733,7 @@ version = "0.2.2" description = "Convert images to beautiful ANSI escape codes" optional = false python-versions = ">=3.2" +groups = ["main"] files = [ {file = "climage-0.2.2-py3-none-any.whl", hash = "sha256:0a820c7e9c51aa0f720dd3039247848db3c42ebf62475407ec33442e7919b6ab"}, {file = "climage-0.2.2.tar.gz", hash = "sha256:e6116b2f5f3d313adb0856657efe4a6d119e2218cdef23c28a993d94b871ab8e"}, @@ -720,6 +749,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] +markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -731,6 +762,7 @@ version = "23.10.4" description = "Symbolic constants in Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "constantly-23.10.4-py3-none-any.whl", hash = "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9"}, {file = "constantly-23.10.4.tar.gz", hash = "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"}, @@ -742,6 +774,7 @@ version = "0.10.25" description = "Database of Courts" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "courts_db-0.10.25-py2.py3-none-any.whl", hash = "sha256:b61783bdee2d7afd549ce767d09b4883d835242f73eab9061e74efc2f19c6f64"}, {file = "courts_db-0.10.25.tar.gz", hash = "sha256:f96b4ef3227e6844b3d2d12970373f2f05cdda66a9f15cbe69527ff66649b9d9"}, @@ -753,6 +786,7 @@ version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, @@ -802,6 +836,7 @@ version = "1.2.0" description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e"}, {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, @@ -813,6 +848,7 @@ version = "4.1.2" description = "Django ASGI (HTTP/WebSocket) server" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "daphne-4.1.2-py3-none-any.whl", hash = "sha256:618d1322bb4d875342b99dd2a10da2d9aae7ee3645f765965fdc1e658ea5290a"}, {file = "daphne-4.1.2.tar.gz", hash = "sha256:fcbcace38eb86624ae247c7ffdc8ac12f155d7d19eafac4247381896d6f33761"}, @@ -832,6 +868,7 @@ version = "1.6.5" description = "Probabilistic data structures for processing and searching very large datasets" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "datasketch-1.6.5-py3-none-any.whl", hash = "sha256:59311b2925b2f37536e9f7c2f46bbc25e8e54379c8635a3fa7ca55d2abb66d1b"}, {file = "datasketch-1.6.5.tar.gz", hash = "sha256:ba2848cb74f23d6d3dd444cf24edcbc47b1c34a171b1803231793ed4d74d4fcf"}, @@ -854,6 +891,7 @@ version = "1.2.0" description = "Date parsing library designed to parse dates from HTML pages" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"}, {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"}, @@ -876,6 +914,7 @@ version = "5.1.1" description = "Decorators for Humans" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, @@ -887,6 +926,7 @@ version = "0.7.1" description = "XML bomb protection for Python stdlib modules" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] files = [ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, @@ -898,6 +938,7 @@ version = "0.3.9" description = "serialize all of Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, @@ -913,6 +954,7 @@ version = "0.0.107" description = "A set of disposable email domains" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "disposable_email_domains-0.0.107-py2.py3-none-any.whl", hash = "sha256:1a7b891f644b1234dd2555de5208bcb35a52e32aaef156ff03ad2cc02f8564ed"}, {file = "disposable_email_domains-0.0.107.tar.gz", hash = "sha256:a5e5f267d6fe1288840ba67e03816e7478a3ec308948c9ae5aa7f7cfcc31b13c"}, @@ -927,6 +969,7 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -938,6 +981,7 @@ version = "1.9.0" description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, @@ -949,6 +993,7 @@ version = "5.1.2" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" +groups = ["main", "dev"] files = [ {file = "Django-5.1.2-py3-none-any.whl", hash = "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed"}, {file = "Django-5.1.2.tar.gz", hash = "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0"}, @@ -969,6 +1014,7 @@ version = "0.1.6" description = "Drop-in replacement for django admin default pagination that works fast with huge tables." optional = false python-versions = ">=3.4" +groups = ["main"] files = [ {file = "django-admin-cursor-paginator-0.1.6.tar.gz", hash = "sha256:42f81854c3f7774b1b9a327ce974586bdbdcca1c761b634a1ebf162c8a65cab9"}, ] @@ -982,6 +1028,7 @@ version = "0.2.0" description = "Django utility for a memoization decorator that uses the Django cache framework." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "django-cache-memoize-0.2.0.tar.gz", hash = "sha256:79950a027ba40e4aff4efed587b76036bf5ba1f59329d7b158797b832be72ca6"}, {file = "django_cache_memoize-0.2.0-py3-none-any.whl", hash = "sha256:a6bfd112da699d1fa85955a1e15b7c48ee25e58044398958e269678db10736f3"}, @@ -996,6 +1043,7 @@ version = "4.6.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "django_cors_headers-4.6.0-py3-none-any.whl", hash = "sha256:8edbc0497e611c24d5150e0055d3b178c6534b8ed826fb6f53b21c63f5d48ba3"}, {file = "django_cors_headers-4.6.0.tar.gz", hash = "sha256:14d76b4b4c8d39375baeddd89e4f08899051eeaf177cb02a29bd6eae8cf63aa8"}, @@ -1011,6 +1059,7 @@ version = "3.8" description = "Django Content Security Policy support." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "django_csp-3.8-py3-none-any.whl", hash = "sha256:19b2978b03fcd73517d7d67acbc04fbbcaec0facc3e83baa502965892d1e0719"}, {file = "django_csp-3.8.tar.gz", hash = "sha256:ef0f1a9f7d8da68ae6e169c02e9ac661c0ecf04db70e0d1d85640512a68471c0"}, @@ -1029,6 +1078,7 @@ version = "4.4.6" description = "A configurable set of panels that display various debug information about the current request/response." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "django_debug_toolbar-4.4.6-py3-none-any.whl", hash = "sha256:3beb671c9ec44ffb817fad2780667f172bd1c067dbcabad6268ce39a81335f45"}, {file = "django_debug_toolbar-4.4.6.tar.gz", hash = "sha256:36e421cb908c2f0675e07f9f41e3d1d8618dc386392ec82d23bcfcd5d29c7044"}, @@ -1044,6 +1094,7 @@ version = "8.0" description = "Wrapper around elasticsearch-dsl-py for django models" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "django-elasticsearch-dsl-8.0.tar.gz", hash = "sha256:64ee0612ced6d57515a6b7f29f1a3e1c2eea1996a6226fc72079a95c067b27ca"}, {file = "django_elasticsearch_dsl-8.0-py2.py3-none-any.whl", hash = "sha256:423784a4af336d109c3763622f1edc4973664cb5154beb55b3ff9390c1e4525e"}, @@ -1062,6 +1113,7 @@ version = "0.11.2" description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application." optional = false python-versions = ">=3.6,<4" +groups = ["main"] files = [ {file = "django-environ-0.11.2.tar.gz", hash = "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be"}, {file = "django_environ-0.11.2-py2.py3-none-any.whl", hash = "sha256:0ff95ab4344bfeff693836aa978e6840abef2e2f1145adff7735892711590c05"}, @@ -1078,6 +1130,7 @@ version = "3.2.3" description = "Extensions for Django" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"}, {file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"}, @@ -1092,6 +1145,7 @@ version = "24.3" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "django_filter-24.3-py3-none-any.whl", hash = "sha256:c4852822928ce17fb699bcfccd644b3574f1a2d80aeb2b4ff4f16b02dd49dc64"}, {file = "django_filter-24.3.tar.gz", hash = "sha256:d8ccaf6732afd21ca0542f6733b11591030fa98669f8d15599b358e24a2cd9c3"}, @@ -1106,6 +1160,7 @@ version = "0.2.0" description = "Django hCaptcha provides a simple way to protect your django forms using hCaptcha" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "django-hCaptcha-0.2.0.tar.gz", hash = "sha256:b2519eaf0cc97865ac72f825301122c5cf61e1e4852d6895994160222acb6c1a"}, {file = "django_hCaptcha-0.2.0-py3-none-any.whl", hash = "sha256:18804fb38a01827b6c65d111bac31265c1b96fcf52d7a54c3e2d2cb1c62ddcde"}, @@ -1117,6 +1172,7 @@ version = "4.0" description = "Country-specific Django helpers" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "django-localflavor-4.0.tar.gz", hash = "sha256:11859e522dba74aa6dde5a659242b1fbc5efb4dea08e9b77315402bdeca5194e"}, {file = "django_localflavor-4.0-py3-none-any.whl", hash = "sha256:7a5b1df03ca8e10df9d1b3c2e4314e43383067868183cdf41ab4e7a973694a8b"}, @@ -1132,6 +1188,7 @@ version = "1.0.6" description = "a Django app that provides template tags for using Markdown (using the python-markdown2 processor)" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "django-markdown-deux-1.0.6.zip", hash = "sha256:1f7b4da6b4dd1a9a84e3da90887d356f8afdd9a1e7d6468c081b8ac50a7980b1"}, ] @@ -1145,6 +1202,7 @@ version = "1.0.0" description = "A set of simple math filters for Django" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "django-mathfilters-1.0.0.tar.gz", hash = "sha256:c9b892ef6dfc893683e75cfd0279c187a601ca68f4684c38f9da44657fb64b07"}, {file = "django_mathfilters-1.0.0-py3-none-any.whl", hash = "sha256:64200a21bb249fbf27be601d4bbb788779e09c6e063170c097cd82c4d18ebb83"}, @@ -1156,6 +1214,7 @@ version = "5.0.0" description = "Django model mixins and utilities" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "django_model_utils-5.0.0-py3-none-any.whl", hash = "sha256:fec78e6c323d565a221f7c4edc703f4567d7bb1caeafe1acd16a80c5ff82056b"}, {file = "django_model_utils-5.0.0.tar.gz", hash = "sha256:041cdd6230d2fbf6cd943e1969318bce762272077f4ecd333ab2263924b4e5eb"}, @@ -1170,6 +1229,7 @@ version = "0.3.2" description = "Django test helpers to manage file storage side effects." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] files = [ {file = "django-override-storage-0.3.2.tar.gz", hash = "sha256:995e1a42f056c9f9bc114077c11d67520ec7d8a752a59be62729e641562b133e"}, {file = "django_override_storage-0.3.2-py2.py3-none-any.whl", hash = "sha256:1f1a13274d66cc481b19d63c8bd43c94066824008bcdd26ec65d125b1ce8ec39"}, @@ -1181,6 +1241,7 @@ version = "4.22.0" description = "Set the draft security HTTP header Permissions-Policy (previously Feature-Policy) on your Django app." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "django_permissions_policy-4.22.0-py3-none-any.whl", hash = "sha256:b8b9034f2e1b59a8ab5b701cb4000f5b3bff1445bc56347c94b3fa4e20794618"}, {file = "django_permissions_policy-4.22.0.tar.gz", hash = "sha256:a65aeeeca0673f8820b1d94490677f1f8a4c0bf28253e189142fc7b175e131dd"}, @@ -1196,6 +1257,7 @@ version = "3.5.1" description = "History tracking for Django and Postgres" optional = false python-versions = "<4,>=3.9.0" +groups = ["main"] files = [ {file = "django_pghistory-3.5.1-py3-none-any.whl", hash = "sha256:900e5be084d20519528a1c66a354464a74b80ec0101abb7541ded61ff46759b7"}, {file = "django_pghistory-3.5.1.tar.gz", hash = "sha256:28a4238326651d60c33a22337c3c93edc0e657d26ef7faac412875c7b4d40d1c"}, @@ -1211,6 +1273,7 @@ version = "4.12.2" description = "Postgres trigger support integrated with Django models." optional = false python-versions = "<4,>=3.8.0" +groups = ["main"] files = [ {file = "django_pgtrigger-4.12.2-py3-none-any.whl", hash = "sha256:1e1f6bf448997ee02a5af07d62a23b10085055e3b7e21062c8480c0b3b56f475"}, {file = "django_pgtrigger-4.12.2.tar.gz", hash = "sha256:831fd03cde31b4d7192a8c831527f062940c82faf4ccff688ad1975806087889"}, @@ -1225,6 +1288,7 @@ version = "4.1.0" description = "Cache-based rate-limiting for Django." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "django-ratelimit-4.1.0.tar.gz", hash = "sha256:555943b283045b917ad59f196829530d63be2a39adb72788d985b90c81ba808b"}, {file = "django_ratelimit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d047a31cf94d83ef1465d7543ca66c6fc16695559b5f8d814d1b51df15110b92"}, @@ -1236,6 +1300,7 @@ version = "4.1.1" description = "A Django email backend for Amazon's Simple Email Service (SES)" optional = false python-versions = "<4.0,>=3.8" +groups = ["main"] files = [ {file = "django_ses-4.1.1-py3-none-any.whl", hash = "sha256:83bb09d2b149dbc1a67a89f66a6681a99e32b8253f47ff4b7fae241d05344cc8"}, {file = "django_ses-4.1.1.tar.gz", hash = "sha256:28f9931df1251660eaf976b7413a42e7b0d25a18043316b96c721d8add7bf7b8"}, @@ -1257,6 +1322,7 @@ version = "1.14.3" description = "Support for many storage backends in Django" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "django-storages-1.14.3.tar.gz", hash = "sha256:95a12836cd998d4c7a4512347322331c662d9114c4344f932f5e9c0fce000608"}, {file = "django_storages-1.14.3-py3-none-any.whl", hash = "sha256:31f263389e95ce3a1b902fb5f739a7ed32895f7d8b80179fe7453ecc0dfe102e"}, @@ -1280,6 +1346,7 @@ version = "5.1.0" description = "Mypy stubs for Django" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "django_stubs-5.1.0-py3-none-any.whl", hash = "sha256:b98d49a80aa4adf1433a97407102d068de26c739c405431d93faad96dd282c40"}, {file = "django_stubs-5.1.0.tar.gz", hash = "sha256:86128c228b65e6c9a85e5dc56eb1c6f41125917dae0e21e6cfecdf1b27e630c5"}, @@ -1303,6 +1370,7 @@ version = "5.1.0" description = "Monkey-patching and extensions for django-stubs" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "django_stubs_ext-5.1.0-py3-none-any.whl", hash = "sha256:a455fc222c90b30b29ad8c53319559f5b54a99b4197205ddbb385aede03b395d"}, {file = "django_stubs_ext-5.1.0.tar.gz", hash = "sha256:ed7d51c0b731651879fc75f331fb0806d98b67bfab464e96e2724db6b46ef926"}, @@ -1318,6 +1386,7 @@ version = "4.1.0" description = "A feature flipper for Django." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "django-waffle-4.1.0.tar.gz", hash = "sha256:e49d7d461d89f3bd8e53f20efe39310acca8f275c9888495e68e195345bf18b1"}, {file = "django_waffle-4.1.0-py3-none-any.whl", hash = "sha256:5979a2f3dd674ef7086480525b39651fc2045427f6d8e6a614192656d3402c5b"}, @@ -1332,6 +1401,7 @@ version = "3.14.0" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.6" +groups = ["main"] files = [] develop = false @@ -1351,6 +1421,7 @@ version = "1.0.0.dev2" description = "Better filtering for Django REST Framework" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "djangorestframework-filters-1.0.0.dev2.tar.gz", hash = "sha256:ef84527e3427434d54228825b53a35098c8633c1e77b71d06b79597b749ea3f2"}, {file = "djangorestframework_filters-1.0.0.dev2-py3-none-any.whl", hash = "sha256:7369998968d656707e013da8c0c3ef1f858b99c4caaa8e9ea40861e5d6ddecff"}, @@ -1366,6 +1437,7 @@ version = "3.15.1" description = "PEP-484 stubs for django-rest-framework" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "djangorestframework_stubs-3.15.1-py3-none-any.whl", hash = "sha256:79dc9018f5d5fa420f9981eec9f1e820ecbd04719791f144419cdc6c5b8e29bd"}, {file = "djangorestframework_stubs-3.15.1.tar.gz", hash = "sha256:34539871895d66d382b6ae3655d9f95c1de7733cf50bc29097638d367ed3117d"}, @@ -1389,6 +1461,7 @@ version = "2.0.0" description = "XML support for Django REST Framework" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "djangorestframework-xml-2.0.0.tar.gz", hash = "sha256:35f6c811d0ab8c8466b26db234e16a2ed32d76381715257aebf4c7be2c202ca1"}, {file = "djangorestframework_xml-2.0.0-py2.py3-none-any.whl", hash = "sha256:975955fbb0d49ac44a90bdeb33b7923d95b79884d283f983e116c80a936ef4d0"}, @@ -1408,6 +1481,7 @@ version = "0.6.2" description = "Pythonic argument parser, that will make you smile" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] @@ -1418,6 +1492,7 @@ version = "0.4.0" description = "Dynamically return subset of Django REST Framework serializer fields" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "drf_dynamic_fields-0.4.0-py2.py3-none-any.whl", hash = "sha256:48b879fe899905bc18593a61bca43e3b595dc3431b3b4ee499a9fd6c9a53f98c"}, {file = "drf_dynamic_fields-0.4.0.tar.gz", hash = "sha256:f20a5ec27d003db7595c9315db22217493dcaed575f3811d3e12f264c791c20c"}, @@ -1429,6 +1504,7 @@ version = "8.15.1" description = "Transport classes and utilities shared among Python Elastic client libraries" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "elastic_transport-8.15.1-py3-none-any.whl", hash = "sha256:b5e82ff1679d8c7705a03fd85c7f6ef85d6689721762d41228dd312e34f331fc"}, {file = "elastic_transport-8.15.1.tar.gz", hash = "sha256:9cac4ab5cf9402668cf305ae0b7d93ddc0c7b61461d6d1027850db6da9cc5742"}, @@ -1447,6 +1523,7 @@ version = "8.15.1" description = "Python client for Elasticsearch" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "elasticsearch-8.15.1-py3-none-any.whl", hash = "sha256:02a0476e98768a30d7926335fc0d305c04fdb928eea1354c6e6040d8c2814569"}, {file = "elasticsearch-8.15.1.tar.gz", hash = "sha256:40c0d312f8adf8bdc81795bc16a0b546ddf544cb1f90e829a244e4780c4dbfd8"}, @@ -1470,6 +1547,7 @@ version = "8.11.0" description = "Python client for Elasticsearch" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "elasticsearch-dsl-8.11.0.tar.gz", hash = "sha256:44af4fd7f62009bb19193b55e1c2143b6932517e4c0ec30107e7ff4d968a127e"}, {file = "elasticsearch_dsl-8.11.0-py3-none-any.whl", hash = "sha256:61000f8ff5e9633d3381aea5a6dfba5c9c4505fe2e6c5cba6a17cd7debc890d9"}, @@ -1488,6 +1566,7 @@ version = "2.1.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, @@ -1502,6 +1581,7 @@ version = "0.11.0" description = "Irregular methods for regular expressions" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "exrex-0.11.0-py2.py3-none-any.whl", hash = "sha256:7bbc4987ebbb63cda7aad1a63b4e29032ba24826de4f295354bce1743e3aeb52"}, {file = "exrex-0.11.0.tar.gz", hash = "sha256:59912f0234567a5966b10d963c37ca9fe07f1640fd158e77c0dc7c3aee780489"}, @@ -1513,6 +1593,7 @@ version = "2.6.4" description = "Tool for extracting legal citations from text strings." optional = false python-versions = "<4.0,>=3.10" +groups = ["main"] files = [ {file = "eyecite-2.6.4-py3-none-any.whl", hash = "sha256:da6a100ca6c6fd05b9a6714fdcdaec8d2e5aa27fff550c9e6c41f75009bea81f"}, {file = "eyecite-2.6.4.tar.gz", hash = "sha256:e3a7d8d7816ee58f2966b2c571df3f97dd19746c5ea5b951b30d4d82cabd8508"}, @@ -1532,6 +1613,7 @@ version = "3.3.1" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "factory_boy-3.3.1-py2.py3-none-any.whl", hash = "sha256:7b1113c49736e1e9995bc2a18f4dbf2c52cf0f841103517010b1d825712ce3ca"}, {file = "factory_boy-3.3.1.tar.gz", hash = "sha256:8317aa5289cdfc45f9cae570feb07a6177316c82e34d14df3c2e1f22f26abef0"}, @@ -1550,6 +1632,7 @@ version = "30.8.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "Faker-30.8.0-py3-none-any.whl", hash = "sha256:4cd0c5ea4bc1e4c902967f6e662f5f5da69f1674d9a94f54e516d27f3c2a6a16"}, {file = "faker-30.8.0.tar.gz", hash = "sha256:3608c7fcac2acde0eaa6da28dae97628f18f14d54eaa2a92b96ae006f1621bd7"}, @@ -1565,6 +1648,7 @@ version = "2.1.0" description = "Packages the C++ implementation of google-diff-match-patch for Python for fast byte and string diffs." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "fast_diff_match_patch-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5670982e4d08eb7609f0b0d62990f48e458f0dc27581a9850018a0fa5f4528e1"}, {file = "fast_diff_match_patch-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5e2078b4305c3ad894bb2d405abe4119b13c3ea1ddebf3dbba3cf8beb90ea560"}, @@ -1650,6 +1734,7 @@ version = "6.0.11" description = "Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45"}, {file = "feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5"}, @@ -1664,6 +1749,7 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -1680,6 +1766,7 @@ version = "7.1.1" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" +groups = ["dev"] files = [ {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, @@ -1696,6 +1783,7 @@ version = "1.0.1" description = "CLI tool to convert a python project's %-formatted strings to f-strings." optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "flynt-1.0.1-py3-none-any.whl", hash = "sha256:65d1c546434827275123222a98408e9561bcd67db832dd58f530ff17b8329ec1"}, {file = "flynt-1.0.1.tar.gz", hash = "sha256:988aac00672a5469726cc0a17cef7d1178c284a9fe8563458db2475d0aaed965"}, @@ -1713,6 +1801,7 @@ version = "0.18.0" description = "Fuzzy string matching in python" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "fuzzywuzzy-0.18.0-py2.py3-none-any.whl", hash = "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993"}, {file = "fuzzywuzzy-0.18.0.tar.gz", hash = "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8"}, @@ -1727,6 +1816,7 @@ version = "2.0.0" description = "Geonames data for continents, cities and US states." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "geonamescache-2.0.0-py3-none-any.whl", hash = "sha256:24fdaaeaf236f88786dec8c0ab55447f5f7f95ef6c094e79fa9ef74114ea1fe2"}, {file = "geonamescache-2.0.0.tar.gz", hash = "sha256:fa1eed0b5b591b478ad81979081ac15b37aa6a1c00bb02431a570688e5c2ecc9"}, @@ -1738,6 +1828,7 @@ version = "23.0.0" description = "WSGI HTTP Server for UNIX" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, @@ -1759,6 +1850,7 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -1770,6 +1862,7 @@ version = "4.1.0" description = "HTTP/2 State-Machine based protocol implementation" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, @@ -1785,6 +1878,7 @@ version = "4.0.0" description = "Pure-Python HPACK header compression" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, @@ -1796,6 +1890,7 @@ version = "1.1" description = "HTML parser based on the WHATWG HTML specification" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] files = [ {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, @@ -1817,6 +1912,7 @@ version = "1.0.6" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, @@ -1838,6 +1934,7 @@ version = "0.22.0" description = "A comprehensive HTTP client library." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] files = [ {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, @@ -1852,6 +1949,7 @@ version = "0.6.4" description = "A collection of framework independent HTTP protocol utils." optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0"}, {file = "httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da"}, @@ -1907,6 +2005,7 @@ version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, @@ -1932,6 +2031,7 @@ version = "6.0.1" description = "HTTP/2 framing layer for Python" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, @@ -1943,6 +2043,7 @@ version = "21.0.0" description = "A featureful, immutable, and correct URL for Python." optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] files = [ {file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"}, {file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"}, @@ -1957,6 +2058,7 @@ version = "0.7.8" description = "Python bindings for Hyperscan." optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "hyperscan-0.7.8-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:5a769dfb53f8e9417905be310d2d60d3c2deba021703da88716b506884e9a855"}, {file = "hyperscan-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8cd9d979f7d9f8a0b9c92fd6db950ec997aff5cc79121fd997ae44e53d80f2e4"}, @@ -2001,6 +2103,7 @@ version = "2.6.1" description = "File identification library for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, @@ -2015,6 +2118,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main", "dev"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -2029,6 +2133,7 @@ version = "24.7.2" description = "A small library that versions your Python projects." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe"}, {file = "incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9"}, @@ -2046,6 +2151,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -2057,6 +2163,7 @@ version = "4.1.0" description = "A Python interface to archive.org." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "internetarchive-4.1.0-py3-none-any.whl", hash = "sha256:0a0e30ade737f7be971b31c38b8c856867a316c5b1d646f055b2b1946aa9cb00"}, {file = "internetarchive-4.1.0.tar.gz", hash = "sha256:467188386218d2c77815ca798a51dd18310b326841113bb462b24ea9a71beedc"}, @@ -2083,6 +2190,7 @@ version = "1.0.23" description = "IPv4/IPv6 manipulation library" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, {file = "ipaddress-1.0.23.tar.gz", hash = "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"}, @@ -2094,6 +2202,7 @@ version = "8.28.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "ipython-8.28.0-py3-none-any.whl", hash = "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35"}, {file = "ipython-8.28.0.tar.gz", hash = "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a"}, @@ -2130,6 +2239,7 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -2144,6 +2254,7 @@ version = "1.2.0" description = "Simple immutable types for python." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, @@ -2155,6 +2266,7 @@ version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, @@ -2174,6 +2286,7 @@ version = "0.6.1" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "jiter-0.6.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d08510593cb57296851080018006dfc394070178d238b767b1879dc1013b106c"}, {file = "jiter-0.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adef59d5e2394ebbad13b7ed5e0306cceb1df92e2de688824232a91588e77aa7"}, @@ -2256,6 +2369,7 @@ version = "1.0.1" description = "JSON Matching Expressions" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, @@ -2267,6 +2381,7 @@ version = "1.4.2" description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, @@ -2278,6 +2393,7 @@ version = "1.33" description = "Apply JSON-Patches (RFC 6902)" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +groups = ["main"] files = [ {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, @@ -2292,6 +2408,7 @@ version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, @@ -2303,6 +2420,7 @@ version = "2.0.5" description = "Database of Judge Pictures" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "judge-pics-2.0.5.tar.gz", hash = "sha256:9c17c7b5f4eb7407a606a59b11ae18724252cf176eab6e674d7e214d090dcdcc"}, {file = "judge_pics-2.0.5-py2.py3-none-any.whl", hash = "sha256:f60f386f898daac3a067f0579daa33869be6d3923883bd9e626c759bbac631fa"}, @@ -2319,13 +2437,14 @@ setuptools = "*" [[package]] name = "juriscraper" -version = "2.6.48" +version = "2.6.49" description = "An API to scrape American court websites for metadata." optional = false python-versions = "*" +groups = ["main"] files = [ - {file = "juriscraper-2.6.48-py27-none-any.whl", hash = "sha256:f2e198cb66a5d3f1423ec4928fc76e1f25c13d0caafc2a6262a7d158c39eab8e"}, - {file = "juriscraper-2.6.48.tar.gz", hash = "sha256:bc138e2c5776f55ef96c10f4a4185d0fec80d83e555e25d1f3fb4b384d399c53"}, + {file = "juriscraper-2.6.49-py27-none-any.whl", hash = "sha256:5954c15747ee5a922d8388db9bb1649100bf8376c39122dc2f4ede2b437b8d0b"}, + {file = "juriscraper-2.6.49.tar.gz", hash = "sha256:28254a22584cfd92a47bb91f9f3bc9139514ffdddfdad1085eacdc70f79fa264"}, ] [package.dependencies] @@ -2355,6 +2474,7 @@ version = "0.16" description = "A Python implemntation of a kd-tree" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "kdtree-0.16-py2.py3-none-any.whl", hash = "sha256:083945db69bc3cf0d349d8d0efe66c056de28d1c2f1e81f762dc5ce46f0dcf0a"}, {file = "kdtree-0.16.tar.gz", hash = "sha256:386df6c7816a05e0fab974e3035df944f99ef68b5615f4a416771391e33d7534"}, @@ -2366,6 +2486,7 @@ version = "5.4.2" description = "Messaging library for Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "kombu-5.4.2-py3-none-any.whl", hash = "sha256:14212f5ccf022fc0a70453bb025a1dcc32782a588c49ea866884047d66e14763"}, {file = "kombu-5.4.2.tar.gz", hash = "sha256:eef572dd2fd9fc614b37580e3caeafdd5af46c1eff31e7fba89138cdb406f2cf"}, @@ -2399,6 +2520,7 @@ version = "0.26.0" description = "Python extension for computing string edit distances and similarities." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "levenshtein-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e5fb23bf35ef1094d00415bb2116dd862fb919adc4044436508029dafedfd687"}, {file = "levenshtein-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea97df5fecf4195ed24aa4c245e5b6cf42527a5818bd7d0d92ba8c7425828861"}, @@ -2492,6 +2614,7 @@ version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, @@ -2646,6 +2769,7 @@ version = "0.5.1" description = "Type annotations for the lxml package" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "lxml-stubs-0.5.1.tar.gz", hash = "sha256:e0ec2aa1ce92d91278b719091ce4515c12adc1d564359dfaf81efa7d4feab79d"}, {file = "lxml_stubs-0.5.1-py3-none-any.whl", hash = "sha256:1f689e5dbc4b9247cb09ae820c7d34daeb1fdbd1db06123814b856dae7787272"}, @@ -2660,6 +2784,7 @@ version = "2.5.1" description = "A fast and complete Python implementation of Markdown" optional = false python-versions = "<4,>=3.8" +groups = ["main"] files = [ {file = "markdown2-2.5.1-py2.py3-none-any.whl", hash = "sha256:190ae60a4bd0425c60c863bede18a9f3d45b1cbf3fbc9f40b4fac336ff2c520b"}, {file = "markdown2-2.5.1.tar.gz", hash = "sha256:12fc04ea5a87f7bb4b65acf5bf3af1183b20838cc7d543b74c92ec7eea4bbc74"}, @@ -2677,6 +2802,7 @@ version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, @@ -2691,6 +2817,7 @@ version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -2702,6 +2829,7 @@ version = "1.12.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801"}, {file = "mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5"}, @@ -2753,6 +2881,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -2764,6 +2893,7 @@ version = "1.1.3" description = "A simple Python module for parsing human names into their individual components." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "nameparser-1.1.3-py2.py3-none-any.whl", hash = "sha256:08ccda98681d59751c82052d52f185bc52f99d43e87d46b85c015a9096ecfa66"}, {file = "nameparser-1.1.3.tar.gz", hash = "sha256:aa2400ad71ccf8070675b40311a257c934659f91854b154e1ba6c264761c049d"}, @@ -2775,6 +2905,7 @@ version = "8.4.0" description = "Simple yet flexible natural sorting in Python." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c"}, {file = "natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581"}, @@ -2790,6 +2921,7 @@ version = "0.5.1" description = "Provides enhanced HTTPS support for httplib and urllib2 using PyOpenSSL" optional = false python-versions = ">=2.7,<3.0.dev0 || >=3.4.dev0" +groups = ["main"] files = [ {file = "ndg_httpsclient-0.5.1-py2-none-any.whl", hash = "sha256:d2c7225f6a1c6cf698af4ebc962da70178a99bcde24ee6d1961c4f3338130d57"}, {file = "ndg_httpsclient-0.5.1-py3-none-any.whl", hash = "sha256:dd174c11d971b6244a891f7be2b32ca9853d3797a72edb34fa5d7b07d8fff7d4"}, @@ -2806,6 +2938,7 @@ version = "3.4.2" description = "Python package for creating and manipulating graphs and networks" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, @@ -2825,6 +2958,7 @@ version = "0.2.18" description = "Python bindings to the ammonia HTML sanitization library." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86"}, {file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811"}, @@ -2850,6 +2984,7 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -2861,6 +2996,7 @@ version = "1.3.7" description = "nose extends unittest to make testing easier" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "nose-1.3.7-py2-none-any.whl", hash = "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a"}, {file = "nose-1.3.7-py3-none-any.whl", hash = "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac"}, @@ -2873,6 +3009,7 @@ version = "2.1.2" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, @@ -2935,6 +3072,7 @@ version = "1.58.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "openai-1.58.1-py3-none-any.whl", hash = "sha256:e2910b1170a6b7f88ef491ac3a42c387f08bd3db533411f7ee391d166571d63c"}, {file = "openai-1.58.1.tar.gz", hash = "sha256:f5a035fd01e141fc743f4b0e02c41ca49be8fab0866d3b67f5f29b4f4d3c0973"}, @@ -2960,6 +3098,7 @@ version = "1.3.0.post0" description = "Capture the outcome of Python function calls." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b"}, {file = "outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8"}, @@ -2974,6 +3113,7 @@ version = "24.1" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, @@ -2985,6 +3125,7 @@ version = "2.2.3" description = "Powerful data structures for data analysis, time series, and statistics" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, @@ -3067,6 +3208,7 @@ version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, @@ -3082,6 +3224,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -3093,6 +3236,8 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" +groups = ["main"] +markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -3107,6 +3252,7 @@ version = "11.0.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, @@ -3199,6 +3345,7 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -3215,6 +3362,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -3230,6 +3378,7 @@ version = "4.0.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, @@ -3248,6 +3397,7 @@ version = "0.0.1" description = "Common methods for propbable parsers" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "probableparsing-0.0.1-py2.py3-none-any.whl", hash = "sha256:509df25fdda4fd7c0b2a100f58cc971bd23daf26f3b3320aebf2616d2e10c69e"}, {file = "probableparsing-0.0.1.tar.gz", hash = "sha256:8114bbf889e1f9456fe35946454c96e42a6ee2673a90d4f1f9c46a406f543767"}, @@ -3259,6 +3409,7 @@ version = "3.0.48" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, @@ -3273,6 +3424,7 @@ version = "3.2.3" description = "PostgreSQL database adapter for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907"}, {file = "psycopg-3.2.3.tar.gz", hash = "sha256:a5764f67c27bec8bfac85764d23c534af2c27b893550377e37ce59c12aac47a2"}, @@ -3297,6 +3449,8 @@ version = "3.2.3" description = "PostgreSQL database adapter for Python -- C optimisation distribution" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "implementation_name != \"pypy\"" files = [ {file = "psycopg_binary-3.2.3-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:965455eac8547f32b3181d5ec9ad8b9be500c10fe06193543efaaebe3e4ce70c"}, {file = "psycopg_binary-3.2.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:71adcc8bc80a65b776510bc39992edf942ace35b153ed7a9c6c573a6849ce308"}, @@ -3370,6 +3524,7 @@ version = "3.2.3" description = "Connection Pool for Psycopg" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "psycopg_pool-3.2.3-py3-none-any.whl", hash = "sha256:53bd8e640625e01b2927b2ad96df8ed8e8f91caea4597d45e7673fc7bbb85eb1"}, {file = "psycopg_pool-3.2.3.tar.gz", hash = "sha256:bb942f123bef4b7fbe4d55421bd3fb01829903c95c0f33fd42b7e94e5ac9b52a"}, @@ -3384,6 +3539,8 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" +groups = ["main"] +markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -3395,6 +3552,7 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, @@ -3409,6 +3567,7 @@ version = "2.1.0" description = "pyahocorasick is a fast and memory efficient library for exact or approximate multi-pattern string search. With the ``ahocorasick.Automaton`` class, you can find multiple key string occurrences at once in some input text. You can use it as a plain dict-like Trie or convert a Trie to an automaton for efficient Aho-Corasick search. And pickle to disk for easy reuse of large automatons. Implemented in C and tested on Python 3.6+. Works on Linux, macOS and Windows. BSD-3-Cause license." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyahocorasick-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c46288044c4f71392efb4f5da0cb8abd160787a8b027afc85079e9c3d7551eb"}, {file = "pyahocorasick-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f15529c83b8c6e0548d7d3c5631fefa23fba5190e67be49d6c9e24a6358ff9c"}, @@ -3447,6 +3606,7 @@ version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -3458,6 +3618,7 @@ version = "0.4.1" description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, @@ -3472,6 +3633,7 @@ version = "2.12.1" description = "Python style guide checker" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, @@ -3483,6 +3645,7 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -3494,6 +3657,7 @@ version = "2.9.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, @@ -3514,6 +3678,7 @@ version = "2.23.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, @@ -3615,6 +3780,7 @@ version = "3.2.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, @@ -3626,6 +3792,7 @@ version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, @@ -3640,6 +3807,7 @@ version = "3.3.1" description = "python code static checker" optional = false python-versions = ">=3.9.0" +groups = ["dev"] files = [ {file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"}, {file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"}, @@ -3664,6 +3832,7 @@ version = "24.3.0" description = "Python wrapper module around the OpenSSL library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "pyOpenSSL-24.3.0-py3-none-any.whl", hash = "sha256:e474f5a473cd7f92221cc04976e48f4d11502804657a08a989fb3be5514c904a"}, {file = "pyopenssl-24.3.0.tar.gz", hash = "sha256:49f7a019577d834746bc55c5fce6ecbcec0f2b4ec5ce1cf43a9a173b8138bb36"}, @@ -3682,6 +3851,7 @@ version = "3.2.0" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"}, {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"}, @@ -3696,6 +3866,7 @@ version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] files = [ {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, @@ -3708,6 +3879,7 @@ version = "2.2.0.3" description = "Snowball stemming algorithms, for information retrieval" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "PyStemmer-2.2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2935aa78a89b04899de4a8b8b6339806e0d5cd93811de52e98829b5762cf913c"}, {file = "PyStemmer-2.2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:31c9d3c808647d4c569737b32b40ed23c67133d2b89033ebc8b5756cadf6f1c1"}, @@ -3799,6 +3971,7 @@ version = "8.3.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, @@ -3819,6 +3992,7 @@ version = "4.9.0" description = "A Django plugin for pytest." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest_django-4.9.0-py3-none-any.whl", hash = "sha256:1d83692cb39188682dbb419ff0393867e9904094a549a7d38a3154d5731b2b99"}, {file = "pytest_django-4.9.0.tar.gz", hash = "sha256:8bf7bc358c9ae6f6fc51b6cebb190fe20212196e6807121f11bd6a3b03428314"}, @@ -3837,6 +4011,7 @@ version = "0.9.11" description = "Python binding for CRFsuite" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python_crfsuite-0.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f5ed569517e7b1fa3d32cf5d5cbe2fb6c85486195bf5cad03d52072fef7aa8a"}, {file = "python_crfsuite-0.9.11-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed10ee4334c99173940e88318d312a4f9e70ba653b8ac0e6f3ef816431af811"}, @@ -3904,6 +4079,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -3918,6 +4094,7 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -3932,6 +4109,7 @@ version = "0.26.0" description = "Python extension for computing string edit distances and similarities." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "python_Levenshtein-0.26.0-py3-none-any.whl", hash = "sha256:1d808ba2f9df04aaea5eceba6e73734f2ffeba99d98d2a91078f32276cd041f4"}, {file = "python_levenshtein-0.26.0.tar.gz", hash = "sha256:b454dd13708546649f1cba2a0f450dd98e7c1679a92e2d6f0a8b8c013c276e55"}, @@ -3946,6 +4124,7 @@ version = "0.4.27" description = "File type identification using libmagic" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] 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"}, @@ -3957,6 +4136,7 @@ version = "1.20" description = "Python module to handle standardized numbers and codes" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "python-stdnum-1.20.tar.gz", hash = "sha256:ad2a2cf2eb025de408210235f36b4ae31252de3186240ccaa8126e117cb82690"}, {file = "python_stdnum-1.20-py2.py3-none-any.whl", hash = "sha256:111008e10391d54fb2afad2a10df70d5cb0c6c0a7ec82fec6f022cb8712961d3"}, @@ -3973,6 +4153,7 @@ version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -3984,6 +4165,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -4046,6 +4228,7 @@ version = "3.10.0" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, @@ -4146,6 +4329,7 @@ version = "5.1.1" description = "Python client for Redis database and key-value store" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "redis-5.1.1-py3-none-any.whl", hash = "sha256:f8ea06b7482a668c6475ae202ed8d9bcaa409f6e87fb77ed1043d912afd62e24"}, {file = "redis-5.1.1.tar.gz", hash = "sha256:f6c997521fedbae53387307c5d0bf784d9acc28d9f1d058abeac566ec4dbed72"}, @@ -4161,6 +4345,7 @@ version = "2024.9.11" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, @@ -4264,6 +4449,7 @@ version = "3.2.46" description = "Database of Court Reporters" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "reporters_db-3.2.46-py2.py3-none-any.whl", hash = "sha256:a8c0b0212220af099714b92938d4ffe2f48e21cde6510a1141cc9dcd86f9047f"}, {file = "reporters_db-3.2.46.tar.gz", hash = "sha256:105bbab035912e3eea95059a9d7b1ee5d2941e19a07b9dd3856e9d80156d87a9"}, @@ -4278,6 +4464,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -4299,6 +4486,7 @@ version = "2.1.0" description = "File transport adapter for Requests" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c"}, {file = "requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658"}, @@ -4313,6 +4501,7 @@ version = "0.10.3" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, @@ -4330,6 +4519,7 @@ version = "0.7.7" description = "Simple data validation library" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "schema-0.7.7-py2.py3-none-any.whl", hash = "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde"}, {file = "schema-0.7.7.tar.gz", hash = "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807"}, @@ -4341,6 +4531,7 @@ version = "1.5.2" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "scikit_learn-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:299406827fb9a4f862626d0fe6c122f5f87f8910b86fe5daa4c32dcd742139b6"}, {file = "scikit_learn-1.5.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2d4cad1119c77930b235579ad0dc25e65c917e756fe80cab96aa3b9428bd3fb0"}, @@ -4391,6 +4582,7 @@ version = "1.14.1" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389"}, {file = "scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3"}, @@ -4441,6 +4633,7 @@ version = "2.2.5" description = "A collection of court seals that can be used in any project." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "seal_rookery-2.2.5-py2.py3-none-any.whl", hash = "sha256:a1bcca9c20540058ae2477b5d40e374037958e771437b1fca5338682bb8a6034"}, {file = "seal_rookery-2.2.5.tar.gz", hash = "sha256:16c8d68875f2105ff44354573be6ef098e631af97e9ac00fcd06d6614e6db17e"}, @@ -4452,6 +4645,7 @@ version = "4.25.0" description = "Official Python bindings for Selenium WebDriver" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "selenium-4.25.0-py3-none-any.whl", hash = "sha256:3798d2d12b4a570bc5790163ba57fef10b2afee958bf1d80f2a3cf07c4141f33"}, {file = "selenium-4.25.0.tar.gz", hash = "sha256:95d08d3b82fb353f3c474895154516604c7f0e6a9a565ae6498ef36c9bac6921"}, @@ -4471,6 +4665,7 @@ version = "2.19.2" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "sentry_sdk-2.19.2-py2.py3-none-any.whl", hash = "sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84"}, {file = "sentry_sdk-2.19.2.tar.gz", hash = "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d"}, @@ -4527,6 +4722,7 @@ version = "24.1.0" description = "Service identity verification for pyOpenSSL & cryptography." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"}, {file = "service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"}, @@ -4551,6 +4747,7 @@ version = "75.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, @@ -4571,6 +4768,7 @@ version = "1.0.0" description = "Py3k port of sgmllib." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"}, ] @@ -4581,6 +4779,7 @@ version = "3.19.3" description = "Simple, fast, extensible JSON encoder/decoder for Python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.5" +groups = ["main"] files = [ {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f39caec26007a2d0efab6b8b1d74873ede9351962707afab622cc2285dd26ed0"}, {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:83c87706265ae3028e8460d08b05f30254c569772e859e5ba61fe8af2c883468"}, @@ -4700,6 +4899,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -4711,6 +4911,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -4722,6 +4923,7 @@ version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, @@ -4733,6 +4935,7 @@ version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, @@ -4744,6 +4947,7 @@ version = "0.5.1" description = "A non-validating SQL parser." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"}, {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"}, @@ -4759,6 +4963,7 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, @@ -4778,6 +4983,7 @@ version = "3.0.0" description = "Traceback serialization library." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tblib-3.0.0-py3-none-any.whl", hash = "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129"}, {file = "tblib-3.0.0.tar.gz", hash = "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6"}, @@ -4789,6 +4995,7 @@ version = "3.5.0" description = "threadpoolctl" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, @@ -4800,6 +5007,7 @@ version = "0.8.0" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "tiktoken-0.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b07e33283463089c81ef1467180e3e00ab00d46c2c4bbcef0acab5f771d6695e"}, {file = "tiktoken-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9269348cb650726f44dd3bbb3f9110ac19a8dcc8f54949ad3ef652ca22a38e21"}, @@ -4847,6 +5055,7 @@ version = "2.16.0" description = "Travel through time in your tests." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "time_machine-2.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52"}, {file = "time_machine-2.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad"}, @@ -4915,6 +5124,7 @@ version = "0.5.0" description = "Timeout decorator" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "timeout-decorator-0.5.0.tar.gz", hash = "sha256:6a2f2f58db1c5b24a2cc79de6345760377ad8bdc13813f5265f6c3e63d16b3d7"}, ] @@ -4925,6 +5135,7 @@ version = "5.1.2" description = "Accurately separates a URL's subdomain, domain, and public suffix, using the Public Suffix List (PSL). By default, this includes the public ICANN TLDs and their exceptions. You can optionally support the Public Suffix List's private domains as well." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "tldextract-5.1.2-py3-none-any.whl", hash = "sha256:4dfc4c277b6b97fa053899fcdb892d2dc27295851ab5fac4e07797b6a21b2e46"}, {file = "tldextract-5.1.2.tar.gz", hash = "sha256:c9e17f756f05afb5abac04fe8f766e7e70f9fe387adb1859f0f52408ee060200"}, @@ -4946,6 +5157,7 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -4957,6 +5169,7 @@ version = "4.66.5" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, @@ -4977,6 +5190,7 @@ version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, @@ -4992,6 +5206,7 @@ version = "0.27.0" description = "A friendly Python library for async concurrency and I/O" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "trio-0.27.0-py3-none-any.whl", hash = "sha256:68eabbcf8f457d925df62da780eff15ff5dc68fd6b367e2dde59f7aaf2a0b884"}, {file = "trio-0.27.0.tar.gz", hash = "sha256:1dcc95ab1726b2da054afea8fd761af74bad79bd52381b84eae408e983c76831"}, @@ -5011,6 +5226,7 @@ version = "0.11.1" description = "WebSocket library for Trio" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f"}, {file = "trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638"}, @@ -5026,6 +5242,7 @@ version = "24.7.0" description = "An asynchronous networking framework written in Python" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "twisted-24.7.0-py3-none-any.whl", hash = "sha256:734832ef98108136e222b5230075b1079dad8a3fc5637319615619a7725b0c81"}, {file = "twisted-24.7.0.tar.gz", hash = "sha256:5a60147f044187a127ec7da96d170d49bcce50c6fd36f594e60f4587eff4d394"}, @@ -5064,6 +5281,7 @@ version = "23.1.1" description = "Compatibility API between asyncio/Twisted/Trollius" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"}, {file = "txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"}, @@ -5080,6 +5298,7 @@ version = "1.16.0.20240331" description = "Typing stubs for cffi" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-cffi-1.16.0.20240331.tar.gz", hash = "sha256:b8b20d23a2b89cfed5f8c5bc53b0cb8677c3aac6d970dbc771e28b9c698f5dee"}, {file = "types_cffi-1.16.0.20240331-py3-none-any.whl", hash = "sha256:a363e5ea54a4eb6a4a105d800685fde596bc318089b025b27dee09849fe41ff0"}, @@ -5094,6 +5313,7 @@ version = "1.2.0.20240420" description = "Typing stubs for dateparser" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "types-dateparser-1.2.0.20240420.tar.gz", hash = "sha256:8f813ddf5ef41b32cabe6167138ae833ada10c22811e42220a1e38a0be7adbdc"}, {file = "types_dateparser-1.2.0.20240420-py3-none-any.whl", hash = "sha256:bf3695ddfbadfdfc875064895a51d926fd80b04da1a44364c6c1a9703db7b194"}, @@ -5105,6 +5325,7 @@ version = "24.1.0.20240722" description = "Typing stubs for pyOpenSSL" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-pyOpenSSL-24.1.0.20240722.tar.gz", hash = "sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39"}, {file = "types_pyOpenSSL-24.1.0.20240722-py3-none-any.whl", hash = "sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54"}, @@ -5120,6 +5341,7 @@ version = "2.9.0.20241003" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, @@ -5131,6 +5353,7 @@ version = "2024.2.0.20241003" description = "Typing stubs for pytz" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "types-pytz-2024.2.0.20241003.tar.gz", hash = "sha256:575dc38f385a922a212bac00a7d6d2e16e141132a3c955078f4a4fd13ed6cb44"}, {file = "types_pytz-2024.2.0.20241003-py3-none-any.whl", hash = "sha256:3e22df1336c0c6ad1d29163c8fda82736909eb977281cb823c57f8bae07118b7"}, @@ -5142,6 +5365,7 @@ version = "6.0.12.20240917" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, @@ -5153,6 +5377,7 @@ version = "4.6.0.20241004" description = "Typing stubs for redis" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-redis-4.6.0.20241004.tar.gz", hash = "sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e"}, {file = "types_redis-4.6.0.20241004-py3-none-any.whl", hash = "sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed"}, @@ -5168,6 +5393,7 @@ version = "2.32.0.20241016" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, @@ -5182,6 +5408,7 @@ version = "75.2.0.20241019" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-setuptools-75.2.0.20241019.tar.gz", hash = "sha256:86ea31b5f6df2c6b8f2dc8ae3f72b213607f62549b6fa2ed5866e5299f968694"}, {file = "types_setuptools-75.2.0.20241019-py3-none-any.whl", hash = "sha256:2e48ff3acd4919471e80d5e3f049cce5c177e108d5d36d2d4cee3fa4d4104258"}, @@ -5193,6 +5420,7 @@ version = "3.19.0.20240801" description = "Typing stubs for simplejson" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-simplejson-3.19.0.20240801.tar.gz", hash = "sha256:ef90cc81dd915f26c452fa2b5e0cbd3a36af81074ae63878fcf8a477e7594e4d"}, {file = "types_simplejson-3.19.0.20240801-py3-none-any.whl", hash = "sha256:37f1b33c8626d7f072ea87737629310674845d54d187f12387fe33d31c938288"}, @@ -5204,6 +5432,7 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -5215,10 +5444,12 @@ version = "2024.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" +groups = ["main", "dev"] files = [ {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] +markers = {dev = "sys_platform == \"win32\""} [[package]] name = "tzlocal" @@ -5226,6 +5457,7 @@ version = "5.2" description = "tzinfo object for the local timezone" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, @@ -5243,6 +5475,7 @@ version = "1.3.8" description = "ASCII transliterations of Unicode text" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, @@ -5254,6 +5487,7 @@ version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -5274,6 +5508,7 @@ version = "0.5.11" description = "Parse US addresses using conditional random fields" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "usaddress-0.5.11-py3-none-any.whl", hash = "sha256:a745be0ff0c525d64463f19f2ec798bb1679a9bb6864b0d9a8b9054023f683b5"}, {file = "usaddress-0.5.11.tar.gz", hash = "sha256:eec4c473b94e2a29350ee335f18bac7fe4fa698e08271211dad5fed63bdd3e60"}, @@ -5292,6 +5527,7 @@ version = "0.34.0" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4"}, {file = "uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9"}, @@ -5317,6 +5553,8 @@ version = "0.21.0" description = "Fast implementation of asyncio event loop on top of libuv" optional = false python-versions = ">=3.8.0" +groups = ["main"] +markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\"" files = [ {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"}, {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"}, @@ -5368,6 +5606,7 @@ version = "5.1.0" description = "Python promises." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, @@ -5379,6 +5618,7 @@ version = "20.27.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"}, {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"}, @@ -5399,6 +5639,7 @@ version = "0.24.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0"}, {file = "watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c"}, @@ -5494,6 +5735,7 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -5505,6 +5747,7 @@ version = "0.5.1" description = "Character encoding aliases for legacy web content" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, @@ -5516,6 +5759,7 @@ version = "1.8.0" description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, @@ -5532,6 +5776,7 @@ version = "13.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee"}, {file = "websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7"}, @@ -5627,6 +5872,7 @@ version = "1.2.0" description = "WebSockets state-machine based protocol implementation" optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, @@ -5641,6 +5887,7 @@ version = "7.1.0" description = "Interfaces for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "zope.interface-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a"}, {file = "zope.interface-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef"}, @@ -5690,6 +5937,6 @@ test = ["coverage[toml]", "zope.event", "zope.testing"] testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = ">=3.13, <3.14" content-hash = "8703160c5832be62299f5a926fa8670aed8715cb7c03dc7dd7be2d1a5c84fb2a" From 366038d093f25c7dd3154c1be2b0e1db7846cafc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:49:57 +0000 Subject: [PATCH 17/21] build(deps): bump django from 5.1.2 to 5.1.4 Bumps [django](https://github.com/django/django) from 5.1.2 to 5.1.4. - [Commits](https://github.com/django/django/compare/5.1.2...5.1.4) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- poetry.lock | 259 ++----------------------------------------------- pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 254 deletions(-) diff --git a/poetry.lock b/poetry.lock index d38d4a5859..be4b8ae1a8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "ada-url" @@ -6,7 +6,6 @@ version = "1.15.3" description = "URL parser and manipulator based on the WHAT WG URL standard" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "ada_url-1.15.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:486ed6775faaf915efb82e4dea9224d388ca743aa572996240ffda20e19dd769"}, {file = "ada_url-1.15.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:cf0facdc4e66cadafdfb7ccb914e03aae2571dd8f70a28531a60019d8888641b"}, @@ -75,7 +74,6 @@ version = "5.2.0" description = "Low-level AMQP client for Python (fork of amqplib)." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, @@ -90,7 +88,6 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, @@ -102,7 +99,6 @@ version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, @@ -123,7 +119,6 @@ version = "1.4.0" description = "Python command-line parsing library" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"}, {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"}, @@ -135,7 +130,6 @@ version = "3.8.1" description = "ASGI specs, helper code, and adapters" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, @@ -150,7 +144,6 @@ version = "0.8.1" description = "Read/rewrite/write Python ASTs" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -groups = ["dev"] files = [ {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, @@ -162,7 +155,6 @@ version = "3.3.5" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" -groups = ["dev"] files = [ {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, @@ -174,7 +166,6 @@ version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, @@ -193,7 +184,6 @@ version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, @@ -213,7 +203,6 @@ version = "24.4.2" description = "WebSocket client & server library, WAMP real-time framework" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "autobahn-24.4.2-py2.py3-none-any.whl", hash = "sha256:c56a2abe7ac78abbfb778c02892d673a4de58fd004d088cd7ab297db25918e81"}, {file = "autobahn-24.4.2.tar.gz", hash = "sha256:a2d71ef1b0cf780b6d11f8b205fd2c7749765e65795f2ea7d823796642ee92c9"}, @@ -243,7 +232,6 @@ version = "24.8.1" description = "Self-service finite-state machines for the programmer on the go." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "Automat-24.8.1-py3-none-any.whl", hash = "sha256:bf029a7bc3da1e2c24da2343e7598affaa9f10bf0ab63ff808566ce90551e02a"}, {file = "automat-24.8.1.tar.gz", hash = "sha256:b34227cf63f6325b8ad2399ede780675083e439b20c323d376373d8ee6306d88"}, @@ -258,7 +246,6 @@ version = "4.12.3" description = "Screen-scraping library" optional = false python-versions = ">=3.6.0" -groups = ["main"] files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, @@ -280,7 +267,6 @@ version = "4.2.1" description = "Python multiprocessing fork with improvements and bugfixes" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "billiard-4.2.1-py3-none-any.whl", hash = "sha256:40b59a4ac8806ba2c2369ea98d876bc6108b051c227baffd928c644d15d8f3cb"}, {file = "billiard-4.2.1.tar.gz", hash = "sha256:12b641b0c539073fc8d3f5b8b7be998956665c4233c7c1fcd66a7e677c4fb36f"}, @@ -292,7 +278,6 @@ version = "24.10.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" -groups = ["dev"] files = [ {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, @@ -337,7 +322,6 @@ version = "1.35.44" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "boto3-1.35.44-py3-none-any.whl", hash = "sha256:18416d07b41e6094101a44f8b881047dcec6b846dad0b9f83b9bbf2f0cd93d07"}, {file = "boto3-1.35.44.tar.gz", hash = "sha256:7f8e8a252458d584d8cf7877c372c4f74ec103356eedf43d2dd9e479f47f3639"}, @@ -357,7 +341,6 @@ version = "1.35.44" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "botocore-1.35.44-py3-none-any.whl", hash = "sha256:55388e80624401d017a9a2b8109afd94814f7e666b53e28fce51375cfa8d9326"}, {file = "botocore-1.35.44.tar.gz", hash = "sha256:1fcd97b966ad8a88de4106fe1bd3bbd6d8dadabe99bbd4a6aadcf11cb6c66b39"}, @@ -377,7 +360,6 @@ version = "5.4.0" description = "Distributed Task Queue." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "celery-5.4.0-py3-none-any.whl", hash = "sha256:369631eb580cf8c51a82721ec538684994f8277637edde2dfc0dacd73ed97f64"}, {file = "celery-5.4.0.tar.gz", hash = "sha256:504a19140e8d3029d5acad88330c541d4c3f64c789d85f94756762d8bca7e706"}, @@ -434,7 +416,6 @@ version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" -groups = ["main", "dev"] files = [ {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, @@ -446,7 +427,6 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -516,7 +496,6 @@ files = [ {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] -markers = {dev = "platform_python_implementation != \"PyPy\""} [package.dependencies] pycparser = "*" @@ -527,7 +506,6 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -539,7 +517,6 @@ version = "5.2.0" description = "Universal encoding detector for Python 3" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, @@ -551,7 +528,6 @@ version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" -groups = ["main", "dev"] files = [ {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, @@ -666,7 +642,6 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" -groups = ["main", "dev"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -681,7 +656,6 @@ version = "0.3.1" description = "Enables git-like *did-you-mean* feature in click" optional = false python-versions = ">=3.6.2" -groups = ["main"] files = [ {file = "click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c"}, {file = "click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463"}, @@ -696,7 +670,6 @@ version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, @@ -714,7 +687,6 @@ version = "0.3.0" description = "REPL plugin for Click" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, @@ -733,7 +705,6 @@ version = "0.2.2" description = "Convert images to beautiful ANSI escape codes" optional = false python-versions = ">=3.2" -groups = ["main"] files = [ {file = "climage-0.2.2-py3-none-any.whl", hash = "sha256:0a820c7e9c51aa0f720dd3039247848db3c42ebf62475407ec33442e7919b6ab"}, {file = "climage-0.2.2.tar.gz", hash = "sha256:e6116b2f5f3d313adb0856657efe4a6d119e2218cdef23c28a993d94b871ab8e"}, @@ -749,8 +720,6 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev"] -markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -762,7 +731,6 @@ version = "23.10.4" description = "Symbolic constants in Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "constantly-23.10.4-py3-none-any.whl", hash = "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9"}, {file = "constantly-23.10.4.tar.gz", hash = "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"}, @@ -774,7 +742,6 @@ version = "0.10.25" description = "Database of Courts" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "courts_db-0.10.25-py2.py3-none-any.whl", hash = "sha256:b61783bdee2d7afd549ce767d09b4883d835242f73eab9061e74efc2f19c6f64"}, {file = "courts_db-0.10.25.tar.gz", hash = "sha256:f96b4ef3227e6844b3d2d12970373f2f05cdda66a9f15cbe69527ff66649b9d9"}, @@ -786,7 +753,6 @@ version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" -groups = ["main", "dev"] files = [ {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, @@ -836,7 +802,6 @@ version = "1.2.0" description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e"}, {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, @@ -848,7 +813,6 @@ version = "4.1.2" description = "Django ASGI (HTTP/WebSocket) server" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "daphne-4.1.2-py3-none-any.whl", hash = "sha256:618d1322bb4d875342b99dd2a10da2d9aae7ee3645f765965fdc1e658ea5290a"}, {file = "daphne-4.1.2.tar.gz", hash = "sha256:fcbcace38eb86624ae247c7ffdc8ac12f155d7d19eafac4247381896d6f33761"}, @@ -868,7 +832,6 @@ version = "1.6.5" description = "Probabilistic data structures for processing and searching very large datasets" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "datasketch-1.6.5-py3-none-any.whl", hash = "sha256:59311b2925b2f37536e9f7c2f46bbc25e8e54379c8635a3fa7ca55d2abb66d1b"}, {file = "datasketch-1.6.5.tar.gz", hash = "sha256:ba2848cb74f23d6d3dd444cf24edcbc47b1c34a171b1803231793ed4d74d4fcf"}, @@ -891,7 +854,6 @@ version = "1.2.0" description = "Date parsing library designed to parse dates from HTML pages" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"}, {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"}, @@ -914,7 +876,6 @@ version = "5.1.1" description = "Decorators for Humans" optional = false python-versions = ">=3.5" -groups = ["main"] files = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, @@ -926,7 +887,6 @@ version = "0.7.1" description = "XML bomb protection for Python stdlib modules" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -groups = ["main"] files = [ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, @@ -938,7 +898,6 @@ version = "0.3.9" description = "serialize all of Python" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, @@ -954,7 +913,6 @@ version = "0.0.107" description = "A set of disposable email domains" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "disposable_email_domains-0.0.107-py2.py3-none-any.whl", hash = "sha256:1a7b891f644b1234dd2555de5208bcb35a52e32aaef156ff03ad2cc02f8564ed"}, {file = "disposable_email_domains-0.0.107.tar.gz", hash = "sha256:a5e5f267d6fe1288840ba67e03816e7478a3ec308948c9ae5aa7f7cfcc31b13c"}, @@ -969,7 +927,6 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -981,7 +938,6 @@ version = "1.9.0" description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, @@ -989,14 +945,13 @@ files = [ [[package]] name = "django" -version = "5.1.2" +version = "5.1.4" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" -groups = ["main", "dev"] files = [ - {file = "Django-5.1.2-py3-none-any.whl", hash = "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed"}, - {file = "Django-5.1.2.tar.gz", hash = "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0"}, + {file = "Django-5.1.4-py3-none-any.whl", hash = "sha256:236e023f021f5ce7dee5779de7b286565fdea5f4ab86bae5338e3f7b69896cf0"}, + {file = "Django-5.1.4.tar.gz", hash = "sha256:de450c09e91879fa5a307f696e57c851955c910a438a35e6b4c895e86bedc82a"}, ] [package.dependencies] @@ -1014,7 +969,6 @@ version = "0.1.6" description = "Drop-in replacement for django admin default pagination that works fast with huge tables." optional = false python-versions = ">=3.4" -groups = ["main"] files = [ {file = "django-admin-cursor-paginator-0.1.6.tar.gz", hash = "sha256:42f81854c3f7774b1b9a327ce974586bdbdcca1c761b634a1ebf162c8a65cab9"}, ] @@ -1028,7 +982,6 @@ version = "0.2.0" description = "Django utility for a memoization decorator that uses the Django cache framework." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django-cache-memoize-0.2.0.tar.gz", hash = "sha256:79950a027ba40e4aff4efed587b76036bf5ba1f59329d7b158797b832be72ca6"}, {file = "django_cache_memoize-0.2.0-py3-none-any.whl", hash = "sha256:a6bfd112da699d1fa85955a1e15b7c48ee25e58044398958e269678db10736f3"}, @@ -1043,7 +996,6 @@ version = "4.6.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "django_cors_headers-4.6.0-py3-none-any.whl", hash = "sha256:8edbc0497e611c24d5150e0055d3b178c6534b8ed826fb6f53b21c63f5d48ba3"}, {file = "django_cors_headers-4.6.0.tar.gz", hash = "sha256:14d76b4b4c8d39375baeddd89e4f08899051eeaf177cb02a29bd6eae8cf63aa8"}, @@ -1059,7 +1011,6 @@ version = "3.8" description = "Django Content Security Policy support." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "django_csp-3.8-py3-none-any.whl", hash = "sha256:19b2978b03fcd73517d7d67acbc04fbbcaec0facc3e83baa502965892d1e0719"}, {file = "django_csp-3.8.tar.gz", hash = "sha256:ef0f1a9f7d8da68ae6e169c02e9ac661c0ecf04db70e0d1d85640512a68471c0"}, @@ -1078,7 +1029,6 @@ version = "4.4.6" description = "A configurable set of panels that display various debug information about the current request/response." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "django_debug_toolbar-4.4.6-py3-none-any.whl", hash = "sha256:3beb671c9ec44ffb817fad2780667f172bd1c067dbcabad6268ce39a81335f45"}, {file = "django_debug_toolbar-4.4.6.tar.gz", hash = "sha256:36e421cb908c2f0675e07f9f41e3d1d8618dc386392ec82d23bcfcd5d29c7044"}, @@ -1094,7 +1044,6 @@ version = "8.0" description = "Wrapper around elasticsearch-dsl-py for django models" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django-elasticsearch-dsl-8.0.tar.gz", hash = "sha256:64ee0612ced6d57515a6b7f29f1a3e1c2eea1996a6226fc72079a95c067b27ca"}, {file = "django_elasticsearch_dsl-8.0-py2.py3-none-any.whl", hash = "sha256:423784a4af336d109c3763622f1edc4973664cb5154beb55b3ff9390c1e4525e"}, @@ -1113,7 +1062,6 @@ version = "0.11.2" description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application." optional = false python-versions = ">=3.6,<4" -groups = ["main"] files = [ {file = "django-environ-0.11.2.tar.gz", hash = "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be"}, {file = "django_environ-0.11.2-py2.py3-none-any.whl", hash = "sha256:0ff95ab4344bfeff693836aa978e6840abef2e2f1145adff7735892711590c05"}, @@ -1130,7 +1078,6 @@ version = "3.2.3" description = "Extensions for Django" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"}, {file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"}, @@ -1145,7 +1092,6 @@ version = "24.3" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django_filter-24.3-py3-none-any.whl", hash = "sha256:c4852822928ce17fb699bcfccd644b3574f1a2d80aeb2b4ff4f16b02dd49dc64"}, {file = "django_filter-24.3.tar.gz", hash = "sha256:d8ccaf6732afd21ca0542f6733b11591030fa98669f8d15599b358e24a2cd9c3"}, @@ -1160,7 +1106,6 @@ version = "0.2.0" description = "Django hCaptcha provides a simple way to protect your django forms using hCaptcha" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "django-hCaptcha-0.2.0.tar.gz", hash = "sha256:b2519eaf0cc97865ac72f825301122c5cf61e1e4852d6895994160222acb6c1a"}, {file = "django_hCaptcha-0.2.0-py3-none-any.whl", hash = "sha256:18804fb38a01827b6c65d111bac31265c1b96fcf52d7a54c3e2d2cb1c62ddcde"}, @@ -1172,7 +1117,6 @@ version = "4.0" description = "Country-specific Django helpers" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "django-localflavor-4.0.tar.gz", hash = "sha256:11859e522dba74aa6dde5a659242b1fbc5efb4dea08e9b77315402bdeca5194e"}, {file = "django_localflavor-4.0-py3-none-any.whl", hash = "sha256:7a5b1df03ca8e10df9d1b3c2e4314e43383067868183cdf41ab4e7a973694a8b"}, @@ -1188,7 +1132,6 @@ version = "1.0.6" description = "a Django app that provides template tags for using Markdown (using the python-markdown2 processor)" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "django-markdown-deux-1.0.6.zip", hash = "sha256:1f7b4da6b4dd1a9a84e3da90887d356f8afdd9a1e7d6468c081b8ac50a7980b1"}, ] @@ -1202,7 +1145,6 @@ version = "1.0.0" description = "A set of simple math filters for Django" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "django-mathfilters-1.0.0.tar.gz", hash = "sha256:c9b892ef6dfc893683e75cfd0279c187a601ca68f4684c38f9da44657fb64b07"}, {file = "django_mathfilters-1.0.0-py3-none-any.whl", hash = "sha256:64200a21bb249fbf27be601d4bbb788779e09c6e063170c097cd82c4d18ebb83"}, @@ -1214,7 +1156,6 @@ version = "5.0.0" description = "Django model mixins and utilities" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django_model_utils-5.0.0-py3-none-any.whl", hash = "sha256:fec78e6c323d565a221f7c4edc703f4567d7bb1caeafe1acd16a80c5ff82056b"}, {file = "django_model_utils-5.0.0.tar.gz", hash = "sha256:041cdd6230d2fbf6cd943e1969318bce762272077f4ecd333ab2263924b4e5eb"}, @@ -1229,7 +1170,6 @@ version = "0.3.2" description = "Django test helpers to manage file storage side effects." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -groups = ["main"] files = [ {file = "django-override-storage-0.3.2.tar.gz", hash = "sha256:995e1a42f056c9f9bc114077c11d67520ec7d8a752a59be62729e641562b133e"}, {file = "django_override_storage-0.3.2-py2.py3-none-any.whl", hash = "sha256:1f1a13274d66cc481b19d63c8bd43c94066824008bcdd26ec65d125b1ce8ec39"}, @@ -1241,7 +1181,6 @@ version = "4.22.0" description = "Set the draft security HTTP header Permissions-Policy (previously Feature-Policy) on your Django app." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "django_permissions_policy-4.22.0-py3-none-any.whl", hash = "sha256:b8b9034f2e1b59a8ab5b701cb4000f5b3bff1445bc56347c94b3fa4e20794618"}, {file = "django_permissions_policy-4.22.0.tar.gz", hash = "sha256:a65aeeeca0673f8820b1d94490677f1f8a4c0bf28253e189142fc7b175e131dd"}, @@ -1257,7 +1196,6 @@ version = "3.5.1" description = "History tracking for Django and Postgres" optional = false python-versions = "<4,>=3.9.0" -groups = ["main"] files = [ {file = "django_pghistory-3.5.1-py3-none-any.whl", hash = "sha256:900e5be084d20519528a1c66a354464a74b80ec0101abb7541ded61ff46759b7"}, {file = "django_pghistory-3.5.1.tar.gz", hash = "sha256:28a4238326651d60c33a22337c3c93edc0e657d26ef7faac412875c7b4d40d1c"}, @@ -1273,7 +1211,6 @@ version = "4.12.2" description = "Postgres trigger support integrated with Django models." optional = false python-versions = "<4,>=3.8.0" -groups = ["main"] files = [ {file = "django_pgtrigger-4.12.2-py3-none-any.whl", hash = "sha256:1e1f6bf448997ee02a5af07d62a23b10085055e3b7e21062c8480c0b3b56f475"}, {file = "django_pgtrigger-4.12.2.tar.gz", hash = "sha256:831fd03cde31b4d7192a8c831527f062940c82faf4ccff688ad1975806087889"}, @@ -1288,7 +1225,6 @@ version = "4.1.0" description = "Cache-based rate-limiting for Django." optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "django-ratelimit-4.1.0.tar.gz", hash = "sha256:555943b283045b917ad59f196829530d63be2a39adb72788d985b90c81ba808b"}, {file = "django_ratelimit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d047a31cf94d83ef1465d7543ca66c6fc16695559b5f8d814d1b51df15110b92"}, @@ -1300,7 +1236,6 @@ version = "4.1.1" description = "A Django email backend for Amazon's Simple Email Service (SES)" optional = false python-versions = "<4.0,>=3.8" -groups = ["main"] files = [ {file = "django_ses-4.1.1-py3-none-any.whl", hash = "sha256:83bb09d2b149dbc1a67a89f66a6681a99e32b8253f47ff4b7fae241d05344cc8"}, {file = "django_ses-4.1.1.tar.gz", hash = "sha256:28f9931df1251660eaf976b7413a42e7b0d25a18043316b96c721d8add7bf7b8"}, @@ -1322,7 +1257,6 @@ version = "1.14.3" description = "Support for many storage backends in Django" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "django-storages-1.14.3.tar.gz", hash = "sha256:95a12836cd998d4c7a4512347322331c662d9114c4344f932f5e9c0fce000608"}, {file = "django_storages-1.14.3-py3-none-any.whl", hash = "sha256:31f263389e95ce3a1b902fb5f739a7ed32895f7d8b80179fe7453ecc0dfe102e"}, @@ -1346,7 +1280,6 @@ version = "5.1.0" description = "Mypy stubs for Django" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "django_stubs-5.1.0-py3-none-any.whl", hash = "sha256:b98d49a80aa4adf1433a97407102d068de26c739c405431d93faad96dd282c40"}, {file = "django_stubs-5.1.0.tar.gz", hash = "sha256:86128c228b65e6c9a85e5dc56eb1c6f41125917dae0e21e6cfecdf1b27e630c5"}, @@ -1370,7 +1303,6 @@ version = "5.1.0" description = "Monkey-patching and extensions for django-stubs" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "django_stubs_ext-5.1.0-py3-none-any.whl", hash = "sha256:a455fc222c90b30b29ad8c53319559f5b54a99b4197205ddbb385aede03b395d"}, {file = "django_stubs_ext-5.1.0.tar.gz", hash = "sha256:ed7d51c0b731651879fc75f331fb0806d98b67bfab464e96e2724db6b46ef926"}, @@ -1386,7 +1318,6 @@ version = "4.1.0" description = "A feature flipper for Django." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django-waffle-4.1.0.tar.gz", hash = "sha256:e49d7d461d89f3bd8e53f20efe39310acca8f275c9888495e68e195345bf18b1"}, {file = "django_waffle-4.1.0-py3-none-any.whl", hash = "sha256:5979a2f3dd674ef7086480525b39651fc2045427f6d8e6a614192656d3402c5b"}, @@ -1401,7 +1332,6 @@ version = "3.14.0" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.6" -groups = ["main"] files = [] develop = false @@ -1421,7 +1351,6 @@ version = "1.0.0.dev2" description = "Better filtering for Django REST Framework" optional = false python-versions = ">=3.5" -groups = ["main"] files = [ {file = "djangorestframework-filters-1.0.0.dev2.tar.gz", hash = "sha256:ef84527e3427434d54228825b53a35098c8633c1e77b71d06b79597b749ea3f2"}, {file = "djangorestframework_filters-1.0.0.dev2-py3-none-any.whl", hash = "sha256:7369998968d656707e013da8c0c3ef1f858b99c4caaa8e9ea40861e5d6ddecff"}, @@ -1437,7 +1366,6 @@ version = "3.15.1" description = "PEP-484 stubs for django-rest-framework" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "djangorestframework_stubs-3.15.1-py3-none-any.whl", hash = "sha256:79dc9018f5d5fa420f9981eec9f1e820ecbd04719791f144419cdc6c5b8e29bd"}, {file = "djangorestframework_stubs-3.15.1.tar.gz", hash = "sha256:34539871895d66d382b6ae3655d9f95c1de7733cf50bc29097638d367ed3117d"}, @@ -1461,7 +1389,6 @@ version = "2.0.0" description = "XML support for Django REST Framework" optional = false python-versions = ">=3.5" -groups = ["main"] files = [ {file = "djangorestframework-xml-2.0.0.tar.gz", hash = "sha256:35f6c811d0ab8c8466b26db234e16a2ed32d76381715257aebf4c7be2c202ca1"}, {file = "djangorestframework_xml-2.0.0-py2.py3-none-any.whl", hash = "sha256:975955fbb0d49ac44a90bdeb33b7923d95b79884d283f983e116c80a936ef4d0"}, @@ -1481,7 +1408,6 @@ version = "0.6.2" description = "Pythonic argument parser, that will make you smile" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] @@ -1492,7 +1418,6 @@ version = "0.4.0" description = "Dynamically return subset of Django REST Framework serializer fields" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "drf_dynamic_fields-0.4.0-py2.py3-none-any.whl", hash = "sha256:48b879fe899905bc18593a61bca43e3b595dc3431b3b4ee499a9fd6c9a53f98c"}, {file = "drf_dynamic_fields-0.4.0.tar.gz", hash = "sha256:f20a5ec27d003db7595c9315db22217493dcaed575f3811d3e12f264c791c20c"}, @@ -1504,7 +1429,6 @@ version = "8.15.1" description = "Transport classes and utilities shared among Python Elastic client libraries" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "elastic_transport-8.15.1-py3-none-any.whl", hash = "sha256:b5e82ff1679d8c7705a03fd85c7f6ef85d6689721762d41228dd312e34f331fc"}, {file = "elastic_transport-8.15.1.tar.gz", hash = "sha256:9cac4ab5cf9402668cf305ae0b7d93ddc0c7b61461d6d1027850db6da9cc5742"}, @@ -1523,7 +1447,6 @@ version = "8.15.1" description = "Python client for Elasticsearch" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "elasticsearch-8.15.1-py3-none-any.whl", hash = "sha256:02a0476e98768a30d7926335fc0d305c04fdb928eea1354c6e6040d8c2814569"}, {file = "elasticsearch-8.15.1.tar.gz", hash = "sha256:40c0d312f8adf8bdc81795bc16a0b546ddf544cb1f90e829a244e4780c4dbfd8"}, @@ -1547,7 +1470,6 @@ version = "8.11.0" description = "Python client for Elasticsearch" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "elasticsearch-dsl-8.11.0.tar.gz", hash = "sha256:44af4fd7f62009bb19193b55e1c2143b6932517e4c0ec30107e7ff4d968a127e"}, {file = "elasticsearch_dsl-8.11.0-py3-none-any.whl", hash = "sha256:61000f8ff5e9633d3381aea5a6dfba5c9c4505fe2e6c5cba6a17cd7debc890d9"}, @@ -1566,7 +1488,6 @@ version = "2.1.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, @@ -1581,7 +1502,6 @@ version = "0.11.0" description = "Irregular methods for regular expressions" optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "exrex-0.11.0-py2.py3-none-any.whl", hash = "sha256:7bbc4987ebbb63cda7aad1a63b4e29032ba24826de4f295354bce1743e3aeb52"}, {file = "exrex-0.11.0.tar.gz", hash = "sha256:59912f0234567a5966b10d963c37ca9fe07f1640fd158e77c0dc7c3aee780489"}, @@ -1593,7 +1513,6 @@ version = "2.6.4" description = "Tool for extracting legal citations from text strings." optional = false python-versions = "<4.0,>=3.10" -groups = ["main"] files = [ {file = "eyecite-2.6.4-py3-none-any.whl", hash = "sha256:da6a100ca6c6fd05b9a6714fdcdaec8d2e5aa27fff550c9e6c41f75009bea81f"}, {file = "eyecite-2.6.4.tar.gz", hash = "sha256:e3a7d8d7816ee58f2966b2c571df3f97dd19746c5ea5b951b30d4d82cabd8508"}, @@ -1613,7 +1532,6 @@ version = "3.3.1" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "factory_boy-3.3.1-py2.py3-none-any.whl", hash = "sha256:7b1113c49736e1e9995bc2a18f4dbf2c52cf0f841103517010b1d825712ce3ca"}, {file = "factory_boy-3.3.1.tar.gz", hash = "sha256:8317aa5289cdfc45f9cae570feb07a6177316c82e34d14df3c2e1f22f26abef0"}, @@ -1632,7 +1550,6 @@ version = "30.8.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "Faker-30.8.0-py3-none-any.whl", hash = "sha256:4cd0c5ea4bc1e4c902967f6e662f5f5da69f1674d9a94f54e516d27f3c2a6a16"}, {file = "faker-30.8.0.tar.gz", hash = "sha256:3608c7fcac2acde0eaa6da28dae97628f18f14d54eaa2a92b96ae006f1621bd7"}, @@ -1648,7 +1565,6 @@ version = "2.1.0" description = "Packages the C++ implementation of google-diff-match-patch for Python for fast byte and string diffs." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "fast_diff_match_patch-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5670982e4d08eb7609f0b0d62990f48e458f0dc27581a9850018a0fa5f4528e1"}, {file = "fast_diff_match_patch-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5e2078b4305c3ad894bb2d405abe4119b13c3ea1ddebf3dbba3cf8beb90ea560"}, @@ -1734,7 +1650,6 @@ version = "6.0.11" description = "Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45"}, {file = "feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5"}, @@ -1749,7 +1664,6 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -1766,7 +1680,6 @@ version = "7.1.1" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" -groups = ["dev"] files = [ {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, @@ -1783,7 +1696,6 @@ version = "1.0.1" description = "CLI tool to convert a python project's %-formatted strings to f-strings." optional = false python-versions = ">=3.7" -groups = ["dev"] files = [ {file = "flynt-1.0.1-py3-none-any.whl", hash = "sha256:65d1c546434827275123222a98408e9561bcd67db832dd58f530ff17b8329ec1"}, {file = "flynt-1.0.1.tar.gz", hash = "sha256:988aac00672a5469726cc0a17cef7d1178c284a9fe8563458db2475d0aaed965"}, @@ -1801,7 +1713,6 @@ version = "0.18.0" description = "Fuzzy string matching in python" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "fuzzywuzzy-0.18.0-py2.py3-none-any.whl", hash = "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993"}, {file = "fuzzywuzzy-0.18.0.tar.gz", hash = "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8"}, @@ -1816,7 +1727,6 @@ version = "2.0.0" description = "Geonames data for continents, cities and US states." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "geonamescache-2.0.0-py3-none-any.whl", hash = "sha256:24fdaaeaf236f88786dec8c0ab55447f5f7f95ef6c094e79fa9ef74114ea1fe2"}, {file = "geonamescache-2.0.0.tar.gz", hash = "sha256:fa1eed0b5b591b478ad81979081ac15b37aa6a1c00bb02431a570688e5c2ecc9"}, @@ -1828,7 +1738,6 @@ version = "23.0.0" description = "WSGI HTTP Server for UNIX" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, @@ -1850,7 +1759,6 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -1862,7 +1770,6 @@ version = "4.1.0" description = "HTTP/2 State-Machine based protocol implementation" optional = false python-versions = ">=3.6.1" -groups = ["main"] files = [ {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, @@ -1878,7 +1785,6 @@ version = "4.0.0" description = "Pure-Python HPACK header compression" optional = false python-versions = ">=3.6.1" -groups = ["main"] files = [ {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, @@ -1890,7 +1796,6 @@ version = "1.1" description = "HTML parser based on the WHATWG HTML specification" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -groups = ["main"] files = [ {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, @@ -1912,7 +1817,6 @@ version = "1.0.6" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, @@ -1934,7 +1838,6 @@ version = "0.22.0" description = "A comprehensive HTTP client library." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main"] files = [ {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, @@ -1949,7 +1852,6 @@ version = "0.6.4" description = "A collection of framework independent HTTP protocol utils." optional = false python-versions = ">=3.8.0" -groups = ["main"] files = [ {file = "httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0"}, {file = "httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da"}, @@ -2005,7 +1907,6 @@ version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, @@ -2031,7 +1932,6 @@ version = "6.0.1" description = "HTTP/2 framing layer for Python" optional = false python-versions = ">=3.6.1" -groups = ["main"] files = [ {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, @@ -2043,7 +1943,6 @@ version = "21.0.0" description = "A featureful, immutable, and correct URL for Python." optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main"] files = [ {file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"}, {file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"}, @@ -2058,7 +1957,6 @@ version = "0.7.8" description = "Python bindings for Hyperscan." optional = false python-versions = "<4.0,>=3.9" -groups = ["main"] files = [ {file = "hyperscan-0.7.8-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:5a769dfb53f8e9417905be310d2d60d3c2deba021703da88716b506884e9a855"}, {file = "hyperscan-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8cd9d979f7d9f8a0b9c92fd6db950ec997aff5cc79121fd997ae44e53d80f2e4"}, @@ -2103,7 +2001,6 @@ version = "2.6.1" description = "File identification library for Python" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, @@ -2118,7 +2015,6 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" -groups = ["main", "dev"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -2133,7 +2029,6 @@ version = "24.7.2" description = "A small library that versions your Python projects." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe"}, {file = "incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9"}, @@ -2151,7 +2046,6 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" -groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -2163,7 +2057,6 @@ version = "4.1.0" description = "A Python interface to archive.org." optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "internetarchive-4.1.0-py3-none-any.whl", hash = "sha256:0a0e30ade737f7be971b31c38b8c856867a316c5b1d646f055b2b1946aa9cb00"}, {file = "internetarchive-4.1.0.tar.gz", hash = "sha256:467188386218d2c77815ca798a51dd18310b326841113bb462b24ea9a71beedc"}, @@ -2190,7 +2083,6 @@ version = "1.0.23" description = "IPv4/IPv6 manipulation library" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, {file = "ipaddress-1.0.23.tar.gz", hash = "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"}, @@ -2202,7 +2094,6 @@ version = "8.28.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" -groups = ["main"] files = [ {file = "ipython-8.28.0-py3-none-any.whl", hash = "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35"}, {file = "ipython-8.28.0.tar.gz", hash = "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a"}, @@ -2239,7 +2130,6 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" -groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -2254,7 +2144,6 @@ version = "1.2.0" description = "Simple immutable types for python." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, @@ -2266,7 +2155,6 @@ version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, @@ -2286,7 +2174,6 @@ version = "0.6.1" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "jiter-0.6.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d08510593cb57296851080018006dfc394070178d238b767b1879dc1013b106c"}, {file = "jiter-0.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adef59d5e2394ebbad13b7ed5e0306cceb1df92e2de688824232a91588e77aa7"}, @@ -2369,7 +2256,6 @@ version = "1.0.1" description = "JSON Matching Expressions" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, @@ -2381,7 +2267,6 @@ version = "1.4.2" description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, @@ -2393,7 +2278,6 @@ version = "1.33" description = "Apply JSON-Patches (RFC 6902)" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -groups = ["main"] files = [ {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, @@ -2408,7 +2292,6 @@ version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, @@ -2420,7 +2303,6 @@ version = "2.0.5" description = "Database of Judge Pictures" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "judge-pics-2.0.5.tar.gz", hash = "sha256:9c17c7b5f4eb7407a606a59b11ae18724252cf176eab6e674d7e214d090dcdcc"}, {file = "judge_pics-2.0.5-py2.py3-none-any.whl", hash = "sha256:f60f386f898daac3a067f0579daa33869be6d3923883bd9e626c759bbac631fa"}, @@ -2441,7 +2323,6 @@ version = "2.6.49" description = "An API to scrape American court websites for metadata." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "juriscraper-2.6.49-py27-none-any.whl", hash = "sha256:5954c15747ee5a922d8388db9bb1649100bf8376c39122dc2f4ede2b437b8d0b"}, {file = "juriscraper-2.6.49.tar.gz", hash = "sha256:28254a22584cfd92a47bb91f9f3bc9139514ffdddfdad1085eacdc70f79fa264"}, @@ -2474,7 +2355,6 @@ version = "0.16" description = "A Python implemntation of a kd-tree" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "kdtree-0.16-py2.py3-none-any.whl", hash = "sha256:083945db69bc3cf0d349d8d0efe66c056de28d1c2f1e81f762dc5ce46f0dcf0a"}, {file = "kdtree-0.16.tar.gz", hash = "sha256:386df6c7816a05e0fab974e3035df944f99ef68b5615f4a416771391e33d7534"}, @@ -2486,7 +2366,6 @@ version = "5.4.2" description = "Messaging library for Python." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "kombu-5.4.2-py3-none-any.whl", hash = "sha256:14212f5ccf022fc0a70453bb025a1dcc32782a588c49ea866884047d66e14763"}, {file = "kombu-5.4.2.tar.gz", hash = "sha256:eef572dd2fd9fc614b37580e3caeafdd5af46c1eff31e7fba89138cdb406f2cf"}, @@ -2520,7 +2399,6 @@ version = "0.26.0" description = "Python extension for computing string edit distances and similarities." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "levenshtein-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e5fb23bf35ef1094d00415bb2116dd862fb919adc4044436508029dafedfd687"}, {file = "levenshtein-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea97df5fecf4195ed24aa4c245e5b6cf42527a5818bd7d0d92ba8c7425828861"}, @@ -2614,7 +2492,6 @@ version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, @@ -2769,7 +2646,6 @@ version = "0.5.1" description = "Type annotations for the lxml package" optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "lxml-stubs-0.5.1.tar.gz", hash = "sha256:e0ec2aa1ce92d91278b719091ce4515c12adc1d564359dfaf81efa7d4feab79d"}, {file = "lxml_stubs-0.5.1-py3-none-any.whl", hash = "sha256:1f689e5dbc4b9247cb09ae820c7d34daeb1fdbd1db06123814b856dae7787272"}, @@ -2784,7 +2660,6 @@ version = "2.5.1" description = "A fast and complete Python implementation of Markdown" optional = false python-versions = "<4,>=3.8" -groups = ["main"] files = [ {file = "markdown2-2.5.1-py2.py3-none-any.whl", hash = "sha256:190ae60a4bd0425c60c863bede18a9f3d45b1cbf3fbc9f40b4fac336ff2c520b"}, {file = "markdown2-2.5.1.tar.gz", hash = "sha256:12fc04ea5a87f7bb4b65acf5bf3af1183b20838cc7d543b74c92ec7eea4bbc74"}, @@ -2802,7 +2677,6 @@ version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, @@ -2817,7 +2691,6 @@ version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" -groups = ["dev"] files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -2829,7 +2702,6 @@ version = "1.12.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801"}, {file = "mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5"}, @@ -2881,7 +2753,6 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" -groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -2893,7 +2764,6 @@ version = "1.1.3" description = "A simple Python module for parsing human names into their individual components." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "nameparser-1.1.3-py2.py3-none-any.whl", hash = "sha256:08ccda98681d59751c82052d52f185bc52f99d43e87d46b85c015a9096ecfa66"}, {file = "nameparser-1.1.3.tar.gz", hash = "sha256:aa2400ad71ccf8070675b40311a257c934659f91854b154e1ba6c264761c049d"}, @@ -2905,7 +2775,6 @@ version = "8.4.0" description = "Simple yet flexible natural sorting in Python." optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c"}, {file = "natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581"}, @@ -2921,7 +2790,6 @@ version = "0.5.1" description = "Provides enhanced HTTPS support for httplib and urllib2 using PyOpenSSL" optional = false python-versions = ">=2.7,<3.0.dev0 || >=3.4.dev0" -groups = ["main"] files = [ {file = "ndg_httpsclient-0.5.1-py2-none-any.whl", hash = "sha256:d2c7225f6a1c6cf698af4ebc962da70178a99bcde24ee6d1961c4f3338130d57"}, {file = "ndg_httpsclient-0.5.1-py3-none-any.whl", hash = "sha256:dd174c11d971b6244a891f7be2b32ca9853d3797a72edb34fa5d7b07d8fff7d4"}, @@ -2938,7 +2806,6 @@ version = "3.4.2" description = "Python package for creating and manipulating graphs and networks" optional = false python-versions = ">=3.10" -groups = ["main"] files = [ {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, @@ -2958,7 +2825,6 @@ version = "0.2.18" description = "Python bindings to the ammonia HTML sanitization library." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86"}, {file = "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811"}, @@ -2984,7 +2850,6 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -2996,7 +2861,6 @@ version = "1.3.7" description = "nose extends unittest to make testing easier" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "nose-1.3.7-py2-none-any.whl", hash = "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a"}, {file = "nose-1.3.7-py3-none-any.whl", hash = "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac"}, @@ -3009,7 +2873,6 @@ version = "2.1.2" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" -groups = ["main"] files = [ {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, @@ -3072,7 +2935,6 @@ version = "1.58.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "openai-1.58.1-py3-none-any.whl", hash = "sha256:e2910b1170a6b7f88ef491ac3a42c387f08bd3db533411f7ee391d166571d63c"}, {file = "openai-1.58.1.tar.gz", hash = "sha256:f5a035fd01e141fc743f4b0e02c41ca49be8fab0866d3b67f5f29b4f4d3c0973"}, @@ -3098,7 +2960,6 @@ version = "1.3.0.post0" description = "Capture the outcome of Python function calls." optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b"}, {file = "outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8"}, @@ -3113,7 +2974,6 @@ version = "24.1" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, @@ -3125,7 +2985,6 @@ version = "2.2.3" description = "Powerful data structures for data analysis, time series, and statistics" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, @@ -3208,7 +3067,6 @@ version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, @@ -3224,7 +3082,6 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -3236,8 +3093,6 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" -groups = ["main"] -markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -3252,7 +3107,6 @@ version = "11.0.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, @@ -3345,7 +3199,6 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -3362,7 +3215,6 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -3378,7 +3230,6 @@ version = "4.0.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" -groups = ["dev"] files = [ {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, @@ -3397,7 +3248,6 @@ version = "0.0.1" description = "Common methods for propbable parsers" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "probableparsing-0.0.1-py2.py3-none-any.whl", hash = "sha256:509df25fdda4fd7c0b2a100f58cc971bd23daf26f3b3320aebf2616d2e10c69e"}, {file = "probableparsing-0.0.1.tar.gz", hash = "sha256:8114bbf889e1f9456fe35946454c96e42a6ee2673a90d4f1f9c46a406f543767"}, @@ -3409,7 +3259,6 @@ version = "3.0.48" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" -groups = ["main"] files = [ {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, @@ -3424,7 +3273,6 @@ version = "3.2.3" description = "PostgreSQL database adapter for Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907"}, {file = "psycopg-3.2.3.tar.gz", hash = "sha256:a5764f67c27bec8bfac85764d23c534af2c27b893550377e37ce59c12aac47a2"}, @@ -3449,8 +3297,6 @@ version = "3.2.3" description = "PostgreSQL database adapter for Python -- C optimisation distribution" optional = false python-versions = ">=3.8" -groups = ["main"] -markers = "implementation_name != \"pypy\"" files = [ {file = "psycopg_binary-3.2.3-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:965455eac8547f32b3181d5ec9ad8b9be500c10fe06193543efaaebe3e4ce70c"}, {file = "psycopg_binary-3.2.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:71adcc8bc80a65b776510bc39992edf942ace35b153ed7a9c6c573a6849ce308"}, @@ -3524,7 +3370,6 @@ version = "3.2.3" description = "Connection Pool for Psycopg" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "psycopg_pool-3.2.3-py3-none-any.whl", hash = "sha256:53bd8e640625e01b2927b2ad96df8ed8e8f91caea4597d45e7673fc7bbb85eb1"}, {file = "psycopg_pool-3.2.3.tar.gz", hash = "sha256:bb942f123bef4b7fbe4d55421bd3fb01829903c95c0f33fd42b7e94e5ac9b52a"}, @@ -3539,8 +3384,6 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" -groups = ["main"] -markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -3552,7 +3395,6 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, @@ -3567,7 +3409,6 @@ version = "2.1.0" description = "pyahocorasick is a fast and memory efficient library for exact or approximate multi-pattern string search. With the ``ahocorasick.Automaton`` class, you can find multiple key string occurrences at once in some input text. You can use it as a plain dict-like Trie or convert a Trie to an automaton for efficient Aho-Corasick search. And pickle to disk for easy reuse of large automatons. Implemented in C and tested on Python 3.6+. Works on Linux, macOS and Windows. BSD-3-Cause license." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pyahocorasick-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c46288044c4f71392efb4f5da0cb8abd160787a8b027afc85079e9c3d7551eb"}, {file = "pyahocorasick-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f15529c83b8c6e0548d7d3c5631fefa23fba5190e67be49d6c9e24a6358ff9c"}, @@ -3606,7 +3447,6 @@ version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -3618,7 +3458,6 @@ version = "0.4.1" description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, @@ -3633,7 +3472,6 @@ version = "2.12.1" description = "Python style guide checker" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, @@ -3645,7 +3483,6 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -3657,7 +3494,6 @@ version = "2.9.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, @@ -3678,7 +3514,6 @@ version = "2.23.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, @@ -3780,7 +3615,6 @@ version = "3.2.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, @@ -3792,7 +3626,6 @@ version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, @@ -3807,7 +3640,6 @@ version = "3.3.1" description = "python code static checker" optional = false python-versions = ">=3.9.0" -groups = ["dev"] files = [ {file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"}, {file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"}, @@ -3832,7 +3664,6 @@ version = "24.3.0" description = "Python wrapper module around the OpenSSL library" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "pyOpenSSL-24.3.0-py3-none-any.whl", hash = "sha256:e474f5a473cd7f92221cc04976e48f4d11502804657a08a989fb3be5514c904a"}, {file = "pyopenssl-24.3.0.tar.gz", hash = "sha256:49f7a019577d834746bc55c5fce6ecbcec0f2b4ec5ce1cf43a9a173b8138bb36"}, @@ -3851,7 +3682,6 @@ version = "3.2.0" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"}, {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"}, @@ -3866,7 +3696,6 @@ version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main"] files = [ {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, @@ -3879,7 +3708,6 @@ version = "2.2.0.3" description = "Snowball stemming algorithms, for information retrieval" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "PyStemmer-2.2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2935aa78a89b04899de4a8b8b6339806e0d5cd93811de52e98829b5762cf913c"}, {file = "PyStemmer-2.2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:31c9d3c808647d4c569737b32b40ed23c67133d2b89033ebc8b5756cadf6f1c1"}, @@ -3971,7 +3799,6 @@ version = "8.3.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, @@ -3992,7 +3819,6 @@ version = "4.9.0" description = "A Django plugin for pytest." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pytest_django-4.9.0-py3-none-any.whl", hash = "sha256:1d83692cb39188682dbb419ff0393867e9904094a549a7d38a3154d5731b2b99"}, {file = "pytest_django-4.9.0.tar.gz", hash = "sha256:8bf7bc358c9ae6f6fc51b6cebb190fe20212196e6807121f11bd6a3b03428314"}, @@ -4011,7 +3837,6 @@ version = "0.9.11" description = "Python binding for CRFsuite" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "python_crfsuite-0.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f5ed569517e7b1fa3d32cf5d5cbe2fb6c85486195bf5cad03d52072fef7aa8a"}, {file = "python_crfsuite-0.9.11-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed10ee4334c99173940e88318d312a4f9e70ba653b8ac0e6f3ef816431af811"}, @@ -4079,7 +3904,6 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -4094,7 +3918,6 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -4109,7 +3932,6 @@ version = "0.26.0" description = "Python extension for computing string edit distances and similarities." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "python_Levenshtein-0.26.0-py3-none-any.whl", hash = "sha256:1d808ba2f9df04aaea5eceba6e73734f2ffeba99d98d2a91078f32276cd041f4"}, {file = "python_levenshtein-0.26.0.tar.gz", hash = "sha256:b454dd13708546649f1cba2a0f450dd98e7c1679a92e2d6f0a8b8c013c276e55"}, @@ -4124,7 +3946,6 @@ version = "0.4.27" description = "File type identification using libmagic" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -groups = ["main"] 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"}, @@ -4136,7 +3957,6 @@ version = "1.20" description = "Python module to handle standardized numbers and codes" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "python-stdnum-1.20.tar.gz", hash = "sha256:ad2a2cf2eb025de408210235f36b4ae31252de3186240ccaa8126e117cb82690"}, {file = "python_stdnum-1.20-py2.py3-none-any.whl", hash = "sha256:111008e10391d54fb2afad2a10df70d5cb0c6c0a7ec82fec6f022cb8712961d3"}, @@ -4153,7 +3973,6 @@ version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -4165,7 +3984,6 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -4228,7 +4046,6 @@ version = "3.10.0" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, @@ -4329,7 +4146,6 @@ version = "5.1.1" description = "Python client for Redis database and key-value store" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "redis-5.1.1-py3-none-any.whl", hash = "sha256:f8ea06b7482a668c6475ae202ed8d9bcaa409f6e87fb77ed1043d912afd62e24"}, {file = "redis-5.1.1.tar.gz", hash = "sha256:f6c997521fedbae53387307c5d0bf784d9acc28d9f1d058abeac566ec4dbed72"}, @@ -4345,7 +4161,6 @@ version = "2024.9.11" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, @@ -4449,7 +4264,6 @@ version = "3.2.46" description = "Database of Court Reporters" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "reporters_db-3.2.46-py2.py3-none-any.whl", hash = "sha256:a8c0b0212220af099714b92938d4ffe2f48e21cde6510a1141cc9dcd86f9047f"}, {file = "reporters_db-3.2.46.tar.gz", hash = "sha256:105bbab035912e3eea95059a9d7b1ee5d2941e19a07b9dd3856e9d80156d87a9"}, @@ -4464,7 +4278,6 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -4486,7 +4299,6 @@ version = "2.1.0" description = "File transport adapter for Requests" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c"}, {file = "requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658"}, @@ -4501,7 +4313,6 @@ version = "0.10.3" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, @@ -4519,7 +4330,6 @@ version = "0.7.7" description = "Simple data validation library" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "schema-0.7.7-py2.py3-none-any.whl", hash = "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde"}, {file = "schema-0.7.7.tar.gz", hash = "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807"}, @@ -4531,7 +4341,6 @@ version = "1.5.2" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "scikit_learn-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:299406827fb9a4f862626d0fe6c122f5f87f8910b86fe5daa4c32dcd742139b6"}, {file = "scikit_learn-1.5.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2d4cad1119c77930b235579ad0dc25e65c917e756fe80cab96aa3b9428bd3fb0"}, @@ -4582,7 +4391,6 @@ version = "1.14.1" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.10" -groups = ["main"] files = [ {file = "scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389"}, {file = "scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3"}, @@ -4633,7 +4441,6 @@ version = "2.2.5" description = "A collection of court seals that can be used in any project." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "seal_rookery-2.2.5-py2.py3-none-any.whl", hash = "sha256:a1bcca9c20540058ae2477b5d40e374037958e771437b1fca5338682bb8a6034"}, {file = "seal_rookery-2.2.5.tar.gz", hash = "sha256:16c8d68875f2105ff44354573be6ef098e631af97e9ac00fcd06d6614e6db17e"}, @@ -4645,7 +4452,6 @@ version = "4.25.0" description = "Official Python bindings for Selenium WebDriver" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "selenium-4.25.0-py3-none-any.whl", hash = "sha256:3798d2d12b4a570bc5790163ba57fef10b2afee958bf1d80f2a3cf07c4141f33"}, {file = "selenium-4.25.0.tar.gz", hash = "sha256:95d08d3b82fb353f3c474895154516604c7f0e6a9a565ae6498ef36c9bac6921"}, @@ -4665,7 +4471,6 @@ version = "2.19.2" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "sentry_sdk-2.19.2-py2.py3-none-any.whl", hash = "sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84"}, {file = "sentry_sdk-2.19.2.tar.gz", hash = "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d"}, @@ -4722,7 +4527,6 @@ version = "24.1.0" description = "Service identity verification for pyOpenSSL & cryptography." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"}, {file = "service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"}, @@ -4747,7 +4551,6 @@ version = "75.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, @@ -4768,7 +4571,6 @@ version = "1.0.0" description = "Py3k port of sgmllib." optional = false python-versions = "*" -groups = ["main"] files = [ {file = "sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"}, ] @@ -4779,7 +4581,6 @@ version = "3.19.3" description = "Simple, fast, extensible JSON encoder/decoder for Python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.5" -groups = ["main"] files = [ {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f39caec26007a2d0efab6b8b1d74873ede9351962707afab622cc2285dd26ed0"}, {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:83c87706265ae3028e8460d08b05f30254c569772e859e5ba61fe8af2c883468"}, @@ -4899,7 +4700,6 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -groups = ["main"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -4911,7 +4711,6 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -4923,7 +4722,6 @@ version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, @@ -4935,7 +4733,6 @@ version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, @@ -4947,7 +4744,6 @@ version = "0.5.1" description = "A non-validating SQL parser." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"}, {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"}, @@ -4963,7 +4759,6 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, @@ -4983,7 +4778,6 @@ version = "3.0.0" description = "Traceback serialization library." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "tblib-3.0.0-py3-none-any.whl", hash = "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129"}, {file = "tblib-3.0.0.tar.gz", hash = "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6"}, @@ -4995,7 +4789,6 @@ version = "3.5.0" description = "threadpoolctl" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, @@ -5007,7 +4800,6 @@ version = "0.8.0" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "tiktoken-0.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b07e33283463089c81ef1467180e3e00ab00d46c2c4bbcef0acab5f771d6695e"}, {file = "tiktoken-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9269348cb650726f44dd3bbb3f9110ac19a8dcc8f54949ad3ef652ca22a38e21"}, @@ -5055,7 +4847,6 @@ version = "2.16.0" description = "Travel through time in your tests." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "time_machine-2.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52"}, {file = "time_machine-2.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad"}, @@ -5124,7 +4915,6 @@ version = "0.5.0" description = "Timeout decorator" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "timeout-decorator-0.5.0.tar.gz", hash = "sha256:6a2f2f58db1c5b24a2cc79de6345760377ad8bdc13813f5265f6c3e63d16b3d7"}, ] @@ -5135,7 +4925,6 @@ version = "5.1.2" description = "Accurately separates a URL's subdomain, domain, and public suffix, using the Public Suffix List (PSL). By default, this includes the public ICANN TLDs and their exceptions. You can optionally support the Public Suffix List's private domains as well." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "tldextract-5.1.2-py3-none-any.whl", hash = "sha256:4dfc4c277b6b97fa053899fcdb892d2dc27295851ab5fac4e07797b6a21b2e46"}, {file = "tldextract-5.1.2.tar.gz", hash = "sha256:c9e17f756f05afb5abac04fe8f766e7e70f9fe387adb1859f0f52408ee060200"}, @@ -5157,7 +4946,6 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -5169,7 +4957,6 @@ version = "4.66.5" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, @@ -5190,7 +4977,6 @@ version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, @@ -5206,7 +4992,6 @@ version = "0.27.0" description = "A friendly Python library for async concurrency and I/O" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "trio-0.27.0-py3-none-any.whl", hash = "sha256:68eabbcf8f457d925df62da780eff15ff5dc68fd6b367e2dde59f7aaf2a0b884"}, {file = "trio-0.27.0.tar.gz", hash = "sha256:1dcc95ab1726b2da054afea8fd761af74bad79bd52381b84eae408e983c76831"}, @@ -5226,7 +5011,6 @@ version = "0.11.1" description = "WebSocket library for Trio" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f"}, {file = "trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638"}, @@ -5242,7 +5026,6 @@ version = "24.7.0" description = "An asynchronous networking framework written in Python" optional = false python-versions = ">=3.8.0" -groups = ["main"] files = [ {file = "twisted-24.7.0-py3-none-any.whl", hash = "sha256:734832ef98108136e222b5230075b1079dad8a3fc5637319615619a7725b0c81"}, {file = "twisted-24.7.0.tar.gz", hash = "sha256:5a60147f044187a127ec7da96d170d49bcce50c6fd36f594e60f4587eff4d394"}, @@ -5281,7 +5064,6 @@ version = "23.1.1" description = "Compatibility API between asyncio/Twisted/Trollius" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"}, {file = "txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"}, @@ -5298,7 +5080,6 @@ version = "1.16.0.20240331" description = "Typing stubs for cffi" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-cffi-1.16.0.20240331.tar.gz", hash = "sha256:b8b20d23a2b89cfed5f8c5bc53b0cb8677c3aac6d970dbc771e28b9c698f5dee"}, {file = "types_cffi-1.16.0.20240331-py3-none-any.whl", hash = "sha256:a363e5ea54a4eb6a4a105d800685fde596bc318089b025b27dee09849fe41ff0"}, @@ -5313,7 +5094,6 @@ version = "1.2.0.20240420" description = "Typing stubs for dateparser" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "types-dateparser-1.2.0.20240420.tar.gz", hash = "sha256:8f813ddf5ef41b32cabe6167138ae833ada10c22811e42220a1e38a0be7adbdc"}, {file = "types_dateparser-1.2.0.20240420-py3-none-any.whl", hash = "sha256:bf3695ddfbadfdfc875064895a51d926fd80b04da1a44364c6c1a9703db7b194"}, @@ -5325,7 +5105,6 @@ version = "24.1.0.20240722" description = "Typing stubs for pyOpenSSL" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-pyOpenSSL-24.1.0.20240722.tar.gz", hash = "sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39"}, {file = "types_pyOpenSSL-24.1.0.20240722-py3-none-any.whl", hash = "sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54"}, @@ -5341,7 +5120,6 @@ version = "2.9.0.20241003" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, @@ -5353,7 +5131,6 @@ version = "2024.2.0.20241003" description = "Typing stubs for pytz" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "types-pytz-2024.2.0.20241003.tar.gz", hash = "sha256:575dc38f385a922a212bac00a7d6d2e16e141132a3c955078f4a4fd13ed6cb44"}, {file = "types_pytz-2024.2.0.20241003-py3-none-any.whl", hash = "sha256:3e22df1336c0c6ad1d29163c8fda82736909eb977281cb823c57f8bae07118b7"}, @@ -5365,7 +5142,6 @@ version = "6.0.12.20240917" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, @@ -5377,7 +5153,6 @@ version = "4.6.0.20241004" description = "Typing stubs for redis" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-redis-4.6.0.20241004.tar.gz", hash = "sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e"}, {file = "types_redis-4.6.0.20241004-py3-none-any.whl", hash = "sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed"}, @@ -5393,7 +5168,6 @@ version = "2.32.0.20241016" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, @@ -5408,7 +5182,6 @@ version = "75.2.0.20241019" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-setuptools-75.2.0.20241019.tar.gz", hash = "sha256:86ea31b5f6df2c6b8f2dc8ae3f72b213607f62549b6fa2ed5866e5299f968694"}, {file = "types_setuptools-75.2.0.20241019-py3-none-any.whl", hash = "sha256:2e48ff3acd4919471e80d5e3f049cce5c177e108d5d36d2d4cee3fa4d4104258"}, @@ -5420,7 +5193,6 @@ version = "3.19.0.20240801" description = "Typing stubs for simplejson" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "types-simplejson-3.19.0.20240801.tar.gz", hash = "sha256:ef90cc81dd915f26c452fa2b5e0cbd3a36af81074ae63878fcf8a477e7594e4d"}, {file = "types_simplejson-3.19.0.20240801-py3-none-any.whl", hash = "sha256:37f1b33c8626d7f072ea87737629310674845d54d187f12387fe33d31c938288"}, @@ -5432,7 +5204,6 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -5444,12 +5215,10 @@ version = "2024.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" -groups = ["main", "dev"] files = [ {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] -markers = {dev = "sys_platform == \"win32\""} [[package]] name = "tzlocal" @@ -5457,7 +5226,6 @@ version = "5.2" description = "tzinfo object for the local timezone" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, @@ -5475,7 +5243,6 @@ version = "1.3.8" description = "ASCII transliterations of Unicode text" optional = false python-versions = ">=3.5" -groups = ["main"] files = [ {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, @@ -5487,7 +5254,6 @@ version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -5508,7 +5274,6 @@ version = "0.5.11" description = "Parse US addresses using conditional random fields" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "usaddress-0.5.11-py3-none-any.whl", hash = "sha256:a745be0ff0c525d64463f19f2ec798bb1679a9bb6864b0d9a8b9054023f683b5"}, {file = "usaddress-0.5.11.tar.gz", hash = "sha256:eec4c473b94e2a29350ee335f18bac7fe4fa698e08271211dad5fed63bdd3e60"}, @@ -5527,7 +5292,6 @@ version = "0.34.0" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4"}, {file = "uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9"}, @@ -5553,8 +5317,6 @@ version = "0.21.0" description = "Fast implementation of asyncio event loop on top of libuv" optional = false python-versions = ">=3.8.0" -groups = ["main"] -markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\"" files = [ {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"}, {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"}, @@ -5606,7 +5368,6 @@ version = "5.1.0" description = "Python promises." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, @@ -5618,7 +5379,6 @@ version = "20.27.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"}, {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"}, @@ -5639,7 +5399,6 @@ version = "0.24.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0"}, {file = "watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c"}, @@ -5735,7 +5494,6 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -5747,7 +5505,6 @@ version = "0.5.1" description = "Character encoding aliases for legacy web content" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, @@ -5759,7 +5516,6 @@ version = "1.8.0" description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, @@ -5776,7 +5532,6 @@ version = "13.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee"}, {file = "websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7"}, @@ -5872,7 +5627,6 @@ version = "1.2.0" description = "WebSockets state-machine based protocol implementation" optional = false python-versions = ">=3.7.0" -groups = ["main"] files = [ {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, @@ -5887,7 +5641,6 @@ version = "7.1.0" description = "Interfaces for Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "zope.interface-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a"}, {file = "zope.interface-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef"}, @@ -5937,6 +5690,6 @@ test = ["coverage[toml]", "zope.event", "zope.testing"] testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] -lock-version = "2.1" +lock-version = "2.0" python-versions = ">=3.13, <3.14" -content-hash = "8703160c5832be62299f5a926fa8670aed8715cb7c03dc7dd7be2d1a5c84fb2a" +content-hash = "49aab347be47355db92d0faabdfdb28120a588fb5694887e3e730cca312a0945" diff --git a/pyproject.toml b/pyproject.toml index ecff70afd5..c24ceec367 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ celery = "^5.4.0" certifi = "^2024.12.14" courts-db = "*" disposable-email-domains = "*" -Django = "^5.1.2" +Django = "^5.1.4" django-cache-memoize = "==0.*" django-cors-headers = "^4.6.0" django-csp = "^3.8" From 9f663a3ca0498e8fdec1140774988e5f21056b47 Mon Sep 17 00:00:00 2001 From: v_anne <69829523+v-anne@users.noreply.github.com> Date: Wed, 8 Jan 2025 17:34:41 -0500 Subject: [PATCH 18/21] allowing users to see how many prayers remaining --- cl/favorites/api_serializers.py | 2 +- cl/favorites/templates/user_prayers.html | 9 +-------- cl/favorites/tests.py | 8 ++++---- cl/favorites/utils.py | 6 +++--- cl/favorites/views.py | 5 +++-- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/cl/favorites/api_serializers.py b/cl/favorites/api_serializers.py index a12bb4c101..60b9efedbd 100644 --- a/cl/favorites/api_serializers.py +++ b/cl/favorites/api_serializers.py @@ -67,7 +67,7 @@ def validate(self, data): ) # Check if the user is eligible to create a new prayer - if not async_to_sync(prayer_eligible)(user): + if not async_to_sync(prayer_eligible)(user)[0]: raise ValidationError( f"You have reached the maximum number of prayers ({settings.ALLOWED_PRAYER_COUNT}) allowed in the last 24 hours." ) diff --git a/cl/favorites/templates/user_prayers.html b/cl/favorites/templates/user_prayers.html index 4ada025de6..f010632d16 100644 --- a/cl/favorites/templates/user_prayers.html +++ b/cl/favorites/templates/user_prayers.html @@ -14,7 +14,7 @@ {% block content %}

{% if is_page_owner %}Your PACER Document Prayers{% else %}PACER Document Requests for: {{ requested_user }}{% endif %}

- {% if is_page_owner %}

{{ count|intcomma }} prayers granted totaling ${{total_cost|floatformat:2 }}.

{% endif %} + {% if is_page_owner %}

{{ count|intcomma }} prayers granted totaling ${{total_cost|floatformat:2 }} ({{ num_remaining }} remaining today).

{% endif %}
{% if is_page_owner %}Your PACER Docume hx-trigger="prayersListChanged from:body" hx-swap="none" {%endif %} > -
- {% if is_page_owner %} -

- {% if is_eligible %}You are eligible to make document requests.{% else %}You have reached your daily limit; wait 24 hours to make new requests.{% endif %} -

- {% endif %} -
diff --git a/cl/favorites/tests.py b/cl/favorites/tests.py index 35c32652a2..e5ad413153 100644 --- a/cl/favorites/tests.py +++ b/cl/favorites/tests.py @@ -699,7 +699,7 @@ async def test_prayer_eligible(self) -> None: current_time = now() with time_machine.travel(current_time, tick=False): # No user prayers in the last 24 hours yet for this user. - user_is_eligible = await prayer_eligible(self.user) + user_is_eligible, _ = await prayer_eligible(self.user) self.assertTrue(user_is_eligible) # Add prays for this user. @@ -709,7 +709,7 @@ async def test_prayer_eligible(self) -> None: user_prays = Prayer.objects.filter(user=self.user) self.assertEqual(await user_prays.acount(), 1) - user_is_eligible = await prayer_eligible(self.user) + user_is_eligible, _ = await prayer_eligible(self.user) self.assertTrue(user_is_eligible) await sync_to_async(PrayerFactory)( @@ -719,7 +719,7 @@ async def test_prayer_eligible(self) -> None: # After two prays (ALLOWED_PRAYER_COUNT) in the last 24 hours. # The user is no longer eligible to create more prays - user_is_eligible = await prayer_eligible(self.user) + user_is_eligible, _ = await prayer_eligible(self.user) self.assertFalse(user_is_eligible) with time_machine.travel( @@ -730,7 +730,7 @@ async def test_prayer_eligible(self) -> None: user=self.user, recap_document=self.rd_3 ) self.assertEqual(await user_prays.acount(), 3) - user_is_eligible = await prayer_eligible(self.user) + user_is_eligible, _ = await prayer_eligible(self.user) self.assertTrue(user_is_eligible) async def test_create_prayer(self) -> None: diff --git a/cl/favorites/utils.py b/cl/favorites/utils.py index 9e87389890..85b09c7ad6 100644 --- a/cl/favorites/utils.py +++ b/cl/favorites/utils.py @@ -28,7 +28,7 @@ from cl.search.models import RECAPDocument -async def prayer_eligible(user: User) -> bool: +async def prayer_eligible(user: User) -> Tuple[bool, int]: allowed_prayer_count = settings.ALLOWED_PRAYER_COUNT now = timezone.now() @@ -39,13 +39,13 @@ async def prayer_eligible(user: User) -> bool: user=user, date_created__gte=last_24_hours ).acount() - return prayer_count < allowed_prayer_count + return prayer_count < allowed_prayer_count, (allowed_prayer_count - prayer_count) async def create_prayer( user: User, recap_document: RECAPDocument ) -> Prayer | None: - if await prayer_eligible(user) and not recap_document.is_available: + if await prayer_eligible(user)[0] and not recap_document.is_available: new_prayer, created = await Prayer.objects.aget_or_create( user=user, recap_document=recap_document ) diff --git a/cl/favorites/views.py b/cl/favorites/views.py index bd2c8ea5b5..6f72e652b4 100644 --- a/cl/favorites/views.py +++ b/cl/favorites/views.py @@ -212,7 +212,7 @@ async def create_prayer_view( user = request.user is_htmx_request = request.META.get("HTTP_HX_REQUEST", False) regular_size = bool(request.POST.get("regular_size")) - if not await prayer_eligible(request.user): + if not await prayer_eligible(request.user)[0]: if is_htmx_request: return TemplateResponse( request, @@ -291,7 +291,7 @@ async def user_prayers_view( count, total_cost = await get_user_prayer_history(requested_user) - is_eligible = await prayer_eligible(requested_user) + is_eligible, num_remaining = await prayer_eligible(requested_user) context = { "rd_with_prayers": rd_with_prayers, @@ -300,6 +300,7 @@ async def user_prayers_view( "count": count, "total_cost": total_cost, "is_eligible": is_eligible, + "num_remaining": num_remaining, "private": False, } From 923a21c7a196366bad94f28d92ca498e06ba3992 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:37:36 +0000 Subject: [PATCH 19/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cl/favorites/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl/favorites/utils.py b/cl/favorites/utils.py index 85b09c7ad6..798ac21c7e 100644 --- a/cl/favorites/utils.py +++ b/cl/favorites/utils.py @@ -39,7 +39,9 @@ async def prayer_eligible(user: User) -> Tuple[bool, int]: user=user, date_created__gte=last_24_hours ).acount() - return prayer_count < allowed_prayer_count, (allowed_prayer_count - prayer_count) + return prayer_count < allowed_prayer_count, ( + allowed_prayer_count - prayer_count + ) async def create_prayer( From 8349d764baea06083f7427adf59294443b198198 Mon Sep 17 00:00:00 2001 From: v_anne <69829523+v-anne@users.noreply.github.com> Date: Wed, 8 Jan 2025 17:39:53 -0500 Subject: [PATCH 20/21] fixing type hint --- cl/favorites/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/favorites/utils.py b/cl/favorites/utils.py index 798ac21c7e..88ecaf9834 100644 --- a/cl/favorites/utils.py +++ b/cl/favorites/utils.py @@ -28,7 +28,7 @@ from cl.search.models import RECAPDocument -async def prayer_eligible(user: User) -> Tuple[bool, int]: +async def prayer_eligible(user: User) -> tuple[bool, int]: allowed_prayer_count = settings.ALLOWED_PRAYER_COUNT now = timezone.now() From a0bccda4d8caa5bd45f52585535254a9320b5011 Mon Sep 17 00:00:00 2001 From: v_anne <69829523+v-anne@users.noreply.github.com> Date: Wed, 8 Jan 2025 17:57:18 -0500 Subject: [PATCH 21/21] fixing coroutines --- cl/favorites/utils.py | 2 +- cl/favorites/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/favorites/utils.py b/cl/favorites/utils.py index 88ecaf9834..7de09fbb7e 100644 --- a/cl/favorites/utils.py +++ b/cl/favorites/utils.py @@ -47,7 +47,7 @@ async def prayer_eligible(user: User) -> tuple[bool, int]: async def create_prayer( user: User, recap_document: RECAPDocument ) -> Prayer | None: - if await prayer_eligible(user)[0] and not recap_document.is_available: + if (await prayer_eligible(user))[0] and not recap_document.is_available: new_prayer, created = await Prayer.objects.aget_or_create( user=user, recap_document=recap_document ) diff --git a/cl/favorites/views.py b/cl/favorites/views.py index 6f72e652b4..7cd880e1af 100644 --- a/cl/favorites/views.py +++ b/cl/favorites/views.py @@ -212,7 +212,7 @@ async def create_prayer_view( user = request.user is_htmx_request = request.META.get("HTTP_HX_REQUEST", False) regular_size = bool(request.POST.get("regular_size")) - if not await prayer_eligible(request.user)[0]: + if not (await prayer_eligible(request.user))[0]: if is_htmx_request: return TemplateResponse( request,