diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 5bb4efa..5496b18 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -58,3 +58,20 @@ jobs: run: pnpm build working-directory: ui + - name: Set up Python + uses: pdm-project/setup-pdm@v3 + with: + python-version: '3.10' + cache: true + cache-dependency-path: 'llm-service/pdm.lock' + + - name: Install Python dependencies + run: | + pdm install + working-directory: llm-service + + - name: Test with pytest + run: | + pdm run pytest -sxvvra + working-directory: llm-service + diff --git a/.gitignore b/.gitignore index c01b019..f53cc9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .env .idea/* +.vscode/* !.idea/copyright/ !.idea/prettier.xml !.idea/google-java-format.xml diff --git a/RELEASING.md b/RELEASING.md index de6b785..c876836 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,7 +1,8 @@ # Release process for the RAG Studio AMP * Get `main` into the state to be released -* Publish a release from the `main` branch with the desired version to release +* Publish a release from the `main` branch with the desired version to release using [the **Publish a release** Github Action](https://github.com/cloudera/CML_AMP_RAG_Studio/actions/workflows/publish_release.yml) + * Use a version number incremented as appropriate from [the most recent release](https://github.com/cloudera/CML_AMP_RAG_Studio/releases) * Verify the release in a CML workspace, deploying from `main` * Merge main into the `release/1` branch via a pull request, keeping the version file contents from main * Let the PR build run, to verify no merge conflicts took place diff --git a/backend/src/main/java/com/cloudera/cai/rag/configuration/AppConfiguration.java b/backend/src/main/java/com/cloudera/cai/rag/configuration/AppConfiguration.java index 13049da..281ce4a 100644 --- a/backend/src/main/java/com/cloudera/cai/rag/configuration/AppConfiguration.java +++ b/backend/src/main/java/com/cloudera/cai/rag/configuration/AppConfiguration.java @@ -106,8 +106,6 @@ public HttpClient httpClient(OpenTelemetry openTelemetry) { } public static String getRagIndexUrl() { - String ragBackendBaseUrl = - Optional.ofNullable(System.getenv("LLM_SERVICE_URL")).orElse("http://rag-backend:8000"); - return ragBackendBaseUrl + "/index"; + return Optional.ofNullable(System.getenv("LLM_SERVICE_URL")).orElse("http://rag-backend:8000"); } } diff --git a/backend/src/main/java/com/cloudera/cai/rag/external/RagBackendClient.java b/backend/src/main/java/com/cloudera/cai/rag/external/RagBackendClient.java index daa20ba..cbdc33d 100644 --- a/backend/src/main/java/com/cloudera/cai/rag/external/RagBackendClient.java +++ b/backend/src/main/java/com/cloudera/cai/rag/external/RagBackendClient.java @@ -64,9 +64,11 @@ public void indexFile( Types.RagDocument ragDocument, String bucketName, IndexConfiguration configuration) { try { client.post( - indexUrl + "/download-and-index", - new IndexRequest( - bucketName, ragDocument.s3Path(), ragDocument.dataSourceId(), configuration)); + indexUrl + + "/data_sources/" + + ragDocument.dataSourceId() + + "/documents/download-and-index", + new IndexRequest(bucketName, ragDocument.s3Path(), configuration)); } catch (IOException e) { throw new RuntimeException(e); } @@ -97,7 +99,6 @@ public void deleteSession(Long sessionId) { record IndexRequest( @JsonProperty("s3_bucket_name") String s3BucketName, @JsonProperty("s3_document_key") String s3DocumentKey, - @JsonProperty("data_source_id") long dataSourceId, IndexConfiguration configuration) {} public record SummaryRequest( @@ -114,8 +115,12 @@ public static RagBackendClient createNull() { return createNull(new Tracker<>()); } - public static RagBackendClient createNull(Tracker> tracker) { + public static RagBackendClient createNull( + Tracker> tracker, RuntimeException... t) { return new RagBackendClient(SimpleHttpClient.createNull()) { + private final RuntimeException[] exceptions = t; + private int exceptionIndex = 0; + @Override public void indexFile( Types.RagDocument ragDocument, String bucketName, IndexConfiguration configuration) { @@ -124,18 +129,27 @@ public void indexFile( new TrackedRequest<>( new TrackedIndexRequest( bucketName, ragDocument.s3Path(), ragDocument.dataSourceId(), configuration))); + checkForException(); + } + + private void checkForException() { + if (exceptionIndex < exceptions.length) { + throw exceptions[exceptionIndex++]; + } } @Override public void deleteDataSource(Long dataSourceId) { super.deleteDataSource(dataSourceId); tracker.track(new TrackedRequest<>(new TrackedDeleteDataSourceRequest(dataSourceId))); + checkForException(); } @Override public String createSummary(Types.RagDocument ragDocument, String bucketName) { String result = super.createSummary(ragDocument, bucketName); tracker.track(new TrackedRequest<>(new SummaryRequest(bucketName, ragDocument.s3Path()))); + checkForException(); return result; } @@ -143,6 +157,7 @@ public String createSummary(Types.RagDocument ragDocument, String bucketName) { public void deleteSession(Long sessionId) { super.deleteSession(sessionId); tracker.track(new TrackedRequest<>(new TrackedDeleteSessionRequest(sessionId))); + checkForException(); } @Override @@ -150,6 +165,7 @@ public void deleteDocument(long dataSourceId, String documentId) { super.deleteDocument(dataSourceId, documentId); tracker.track( new TrackedRequest<>(new TrackedDeleteDocumentRequest(dataSourceId, documentId))); + checkForException(); } }; } diff --git a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileDeleteReconciler.java b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileDeleteReconciler.java index e376b9f..66da9e8 100644 --- a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileDeleteReconciler.java +++ b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileDeleteReconciler.java @@ -3,6 +3,7 @@ import com.cloudera.cai.rag.Types; import com.cloudera.cai.rag.configuration.JdbiConfiguration; import com.cloudera.cai.rag.external.RagBackendClient; +import com.cloudera.cai.util.exceptions.NotFound; import com.cloudera.cai.util.reconcilers.BaseReconciler; import com.cloudera.cai.util.reconcilers.ReconcileResult; import com.cloudera.cai.util.reconcilers.ReconcilerConfig; @@ -47,8 +48,12 @@ public void resync() throws Exception { public ReconcileResult reconcile(Set documents) throws Exception { for (Types.RagDocument document : documents) { log.info("starting deletion of document: {}", document); - ragBackendClient.deleteDocument(document.dataSourceId(), document.documentId()); - log.info("finished requesting deletion of document {}", document); + try { + ragBackendClient.deleteDocument(document.dataSourceId(), document.documentId()); + log.info("finished requesting deletion of document {}", document); + } catch (NotFound e) { + log.info("got a not found exception from the rag backend: {}", e.getMessage()); + } jdbi.useHandle( handle -> handle.execute("DELETE from rag_data_source_document WHERE id = ?", document.id())); diff --git a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileIndexReconciler.java b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileIndexReconciler.java index 6a7d575..f5cc9fb 100644 --- a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileIndexReconciler.java +++ b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileIndexReconciler.java @@ -44,6 +44,7 @@ import com.cloudera.cai.rag.configuration.JdbiConfiguration; import com.cloudera.cai.rag.datasources.RagDataSourceRepository; import com.cloudera.cai.rag.external.RagBackendClient; +import com.cloudera.cai.util.exceptions.NotFound; import com.cloudera.cai.util.reconcilers.*; import io.opentelemetry.api.OpenTelemetry; import java.time.Instant; @@ -106,8 +107,7 @@ public ReconcileResult reconcile(Set documents) { for (RagDocument document : documents) { log.info("starting indexing document: {}", document); IndexConfiguration indexConfiguration = fetchIndexConfiguration(document.dataSourceId()); - ragBackendClient.indexFile(document, bucketName, indexConfiguration); - log.info("finished requesting indexing of file {}", document); + Instant updateTimestamp = indexFile(document, indexConfiguration); String updateSql = """ UPDATE rag_data_source_document @@ -117,13 +117,26 @@ public ReconcileResult reconcile(Set documents) { jdbi.useHandle( handle -> { try (Update update = handle.createUpdate(updateSql)) { - update.bind("id", document.id()).bind("now", Instant.now()).execute(); + update.bind("id", document.id()).bind("now", updateTimestamp).execute(); } }); } return new ReconcileResult(); } + private Instant indexFile(RagDocument document, IndexConfiguration indexConfiguration) { + Instant updateTimestamp; + try { + ragBackendClient.indexFile(document, bucketName, indexConfiguration); + updateTimestamp = Instant.now(); + log.info("finished requesting indexing of file {}", document); + } catch (NotFound e) { + updateTimestamp = Instant.EPOCH; + log.info("not found exception from RAG Backend: {}", e.getMessage()); + } + return updateTimestamp; + } + private IndexConfiguration fetchIndexConfiguration(Long dataSourceId) { RagDataSource dataSource = ragDataSourceRepository.getRagDataSourceById(dataSourceId); return new IndexConfiguration(dataSource.chunkSize(), dataSource.chunkOverlapPercent()); diff --git a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileSummaryReconciler.java b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileSummaryReconciler.java index 8706945..f44395a 100644 --- a/backend/src/main/java/com/cloudera/cai/rag/files/RagFileSummaryReconciler.java +++ b/backend/src/main/java/com/cloudera/cai/rag/files/RagFileSummaryReconciler.java @@ -42,6 +42,7 @@ import com.cloudera.cai.rag.configuration.JdbiConfiguration; import com.cloudera.cai.rag.external.RagBackendClient; +import com.cloudera.cai.util.exceptions.NotFound; import com.cloudera.cai.util.reconcilers.*; import io.opentelemetry.api.OpenTelemetry; import java.time.Instant; @@ -108,8 +109,7 @@ public ReconcileResult reconcile(Set documents) { log.info("Document already summarized: {}", document.filename()); continue; } - String summary = ragBackendClient.createSummary(document, bucketName); - log.info("Doc summary: {}", summary); + var updateTimestamp = generateSummary(document); log.info("finished requesting summarization of file {}", document); String updateSql = """ @@ -120,13 +120,25 @@ public ReconcileResult reconcile(Set documents) { jdbi.useHandle( handle -> { try (Update update = handle.createUpdate(updateSql)) { - update.bind("id", document.id()).bind("now", Instant.now()).execute(); + update.bind("id", document.id()).bind("now", updateTimestamp).execute(); } }); } return new ReconcileResult(); } + private Instant generateSummary(RagDocument document) { + var updateTimestamp = Instant.now(); + try { + String summary = ragBackendClient.createSummary(document, bucketName); + log.info("Doc summary: {}", summary); + } catch (NotFound e) { + updateTimestamp = Instant.EPOCH; + log.info("got a not found exception from the rag backend: {}", e.getMessage()); + } + return updateTimestamp; + } + // nullables stuff below here... public static RagFileSummaryReconciler createNull() { return new RagFileSummaryReconciler( diff --git a/backend/src/main/java/com/cloudera/cai/util/SimpleHttpClient.java b/backend/src/main/java/com/cloudera/cai/util/SimpleHttpClient.java index 53ebcbb..ede0a37 100644 --- a/backend/src/main/java/com/cloudera/cai/util/SimpleHttpClient.java +++ b/backend/src/main/java/com/cloudera/cai/util/SimpleHttpClient.java @@ -38,6 +38,7 @@ package com.cloudera.cai.util; +import com.cloudera.cai.util.exceptions.NotFound; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; @@ -73,6 +74,10 @@ public String post(String url, T bodyObject) throws IOException { HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); + if (statusCode == 404) { + throw new NotFound("Failed to post to " + url + " code: " + statusCode); + } + if (statusCode >= 400) { throw new RuntimeException( "Failed to post to " + url + " code: " + statusCode + ", body : " + response.body()); diff --git a/backend/src/test/java/com/cloudera/cai/rag/external/RagBackendClientTest.java b/backend/src/test/java/com/cloudera/cai/rag/external/RagBackendClientTest.java index 0340cb7..60f6393 100644 --- a/backend/src/test/java/com/cloudera/cai/rag/external/RagBackendClientTest.java +++ b/backend/src/test/java/com/cloudera/cai/rag/external/RagBackendClientTest.java @@ -39,12 +39,14 @@ package com.cloudera.cai.rag.external; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.cloudera.cai.rag.Types.RagDocument; import com.cloudera.cai.rag.external.RagBackendClient.IndexConfiguration; import com.cloudera.cai.util.SimpleHttpClient; import com.cloudera.cai.util.SimpleHttpClient.TrackedHttpRequest; import com.cloudera.cai.util.Tracker; +import com.cloudera.cai.util.exceptions.NotFound; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; @@ -65,9 +67,8 @@ void indexFile() { .contains( new TrackedHttpRequest<>( HttpMethod.POST, - "http://rag-backend:8000/index/download-and-index", - new RagBackendClient.IndexRequest( - "bucketName", "s3Path", 1234L, indexConfiguration))); + "http://rag-backend:8000/data_sources/" + 1234L + "/documents/download-and-index", + new RagBackendClient.IndexRequest("bucketName", "s3Path", indexConfiguration))); } @Test @@ -84,7 +85,7 @@ void createSummary() { .contains( new TrackedHttpRequest<>( HttpMethod.POST, - "http://rag-backend:8000/index/data_sources/1234/summarize-document", + "http://rag-backend:8000/data_sources/1234/summarize-document", new RagBackendClient.SummaryRequest("bucketName", "s3Path"))); } @@ -98,7 +99,7 @@ void deleteDataSource() { .hasSize(1) .contains( new TrackedHttpRequest<>( - HttpMethod.DELETE, "http://rag-backend:8000/index/data_sources/1234", null)); + HttpMethod.DELETE, "http://rag-backend:8000/data_sources/1234", null)); } @Test @@ -112,7 +113,7 @@ void deleteDocument() { .contains( new TrackedHttpRequest<>( HttpMethod.DELETE, - "http://rag-backend:8000/index/data_sources/1234/documents/documentId", + "http://rag-backend:8000/data_sources/1234/documents/documentId", null)); } @@ -126,7 +127,16 @@ void deleteSession() { .hasSize(1) .contains( new TrackedHttpRequest<>( - HttpMethod.DELETE, "http://rag-backend:8000/index/sessions/1234", null)); + HttpMethod.DELETE, "http://rag-backend:8000/sessions/1234", null)); + } + + @Test + void null_handlesThrowable() { + RagBackendClient client = + RagBackendClient.createNull(new Tracker<>(), new NotFound("not found")); + RagDocument document = indexRequest("s3Path", 1234L); + assertThatThrownBy(() -> client.indexFile(document, "fakeit", null)) + .isInstanceOf(NotFound.class); } private static RagDocument indexRequest(String s3Path, Long dataSourceId) { diff --git a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileDeleteReconcilerTest.java b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileDeleteReconcilerTest.java index 959dd8f..8048576 100644 --- a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileDeleteReconcilerTest.java +++ b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileDeleteReconcilerTest.java @@ -81,13 +81,40 @@ void reconciler() throws Exception { }); } - private static RagFileDeleteReconciler createTestReconciler(Tracker> tracker) { + @Test + void reconcile_notFound() throws Exception { + Tracker> tracker = new Tracker<>(); + RagFileDeleteReconciler reconciler = + createTestReconciler(tracker, new NotFound("data source not found")); + + RagFileRepository ragFileRepository = RagFileRepository.createNull(); + var dataSourceId = TestData.createTestDataSource(RagDataSourceRepository.createNull()); + String documentId = UUID.randomUUID().toString(); + var id = TestData.createTestDocument(dataSourceId, documentId, ragFileRepository); + + ragFileRepository.deleteById(id); + reconciler.resync(); + + await() + .untilAsserted( + () -> { + assertThat(tracker.getValues()) + .contains( + new TrackedRequest<>( + new TrackedDeleteDocumentRequest(dataSourceId, documentId))); + assertThatThrownBy(() -> ragFileRepository.getRagDocumentById(id)) + .isInstanceOf(NotFound.class); + }); + } + + private static RagFileDeleteReconciler createTestReconciler( + Tracker> tracker, RuntimeException... exceptions) { RagFileDeleteReconciler reconciler = new RagFileDeleteReconciler( ReconcilerConfig.createTestConfig(), OpenTelemetry.noop(), JdbiConfiguration.createNull(), - RagBackendClient.createNull(tracker)); + RagBackendClient.createNull(tracker, exceptions)); reconciler.init(); return reconciler; } diff --git a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileIndexReconcilerTest.java b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileIndexReconcilerTest.java index d23da01..14d0bec 100644 --- a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileIndexReconcilerTest.java +++ b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileIndexReconcilerTest.java @@ -50,6 +50,7 @@ import com.cloudera.cai.rag.external.RagBackendClient.IndexConfiguration; import com.cloudera.cai.rag.external.RagBackendClient.TrackedIndexRequest; import com.cloudera.cai.util.Tracker; +import com.cloudera.cai.util.exceptions.NotFound; import com.cloudera.cai.util.reconcilers.ReconcilerConfig; import io.opentelemetry.api.OpenTelemetry; import java.time.Instant; @@ -113,8 +114,59 @@ void reconcile() { "rag-files", "path_in_s3", dataSourceId, new IndexConfiguration(1024, 20)))); } + @Test + void reconcile_notFound() { + var requestTracker = new Tracker>(); + RagFileIndexReconciler reconciler = + createTestInstance(requestTracker, new NotFound("datasource not found in the rag backend")); + String documentId = UUID.randomUUID().toString(); + long dataSourceId = + ragDataSourceRepository.createRagDataSource( + new RagDataSource( + null, + "test_datasource", + 1024, + 20, + null, + null, + "test-id", + "test-id", + Types.ConnectionType.API, + null, + null)); + RagDocument document = + RagDocument.builder() + .documentId(documentId) + .dataSourceId(dataSourceId) + .s3Path("path_in_s3") + .extension("pdf") + .filename("myfile.pdf") + .timeCreated(Instant.now()) + .timeUpdated(Instant.now()) + .createdById("test-id") + .build(); + Long id = ragFileRepository.saveDocumentMetadata(document); + assertThat(ragFileRepository.findDocumentByDocumentId(documentId).vectorUploadTimestamp()) + .isNull(); + + reconciler.submit(document.withId(id)); + await().until(reconciler::isEmpty); + await() + .untilAsserted( + () -> { + assertThat(reconciler.isEmpty()).isTrue(); + RagDocument updatedDocument = ragFileRepository.findDocumentByDocumentId(documentId); + assertThat(updatedDocument.vectorUploadTimestamp()).isEqualTo(Instant.EPOCH); + }); + assertThat(requestTracker.getValues()) + .contains( + new RagBackendClient.TrackedRequest<>( + new TrackedIndexRequest( + "rag-files", "path_in_s3", dataSourceId, new IndexConfiguration(1024, 20)))); + } + private RagFileIndexReconciler createTestInstance( - Tracker> tracker) { + Tracker> tracker, RuntimeException... exceptions) { Jdbi jdbi = new JdbiConfiguration().jdbi(); var reconcilerConfig = ReconcilerConfig.builder().isTestReconciler(true).workerCount(1).build(); @@ -122,7 +174,7 @@ private RagFileIndexReconciler createTestInstance( new RagFileIndexReconciler( "rag-files", jdbi, - RagBackendClient.createNull(tracker), + RagBackendClient.createNull(tracker, exceptions), RagDataSourceRepository.createNull(), reconcilerConfig, OpenTelemetry.noop()); diff --git a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileSummaryReconcilerTest.java b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileSummaryReconcilerTest.java index da9deff..10c0c77 100644 --- a/backend/src/test/java/com/cloudera/cai/rag/files/RagFileSummaryReconcilerTest.java +++ b/backend/src/test/java/com/cloudera/cai/rag/files/RagFileSummaryReconcilerTest.java @@ -48,6 +48,7 @@ import com.cloudera.cai.rag.datasources.RagDataSourceRepository; import com.cloudera.cai.rag.external.RagBackendClient; import com.cloudera.cai.util.Tracker; +import com.cloudera.cai.util.exceptions.NotFound; import com.cloudera.cai.util.reconcilers.ReconcilerConfig; import io.opentelemetry.api.OpenTelemetry; import java.time.Instant; @@ -114,15 +115,67 @@ void reconcile() { }); } + @Test + void reconcile_notFound() { + Tracker> requestTracker = new Tracker<>(); + RagFileSummaryReconciler reconciler = + createTestInstance(requestTracker, new NotFound("not found")); + + String documentId = UUID.randomUUID().toString(); + long dataSourceId = + ragDataSourceRepository.createRagDataSource( + new RagDataSource( + null, + "test_datasource", + 1024, + 20, + null, + null, + "test-id", + "test-id", + Types.ConnectionType.API, + null, + null)); + RagDocument document = + RagDocument.builder() + .documentId(documentId) + .dataSourceId(dataSourceId) + .s3Path("path_in_s3") + .extension("pdf") + .filename("myfile.pdf") + .timeCreated(Instant.now()) + .timeUpdated(Instant.now()) + .createdById("test-id") + .build(); + Long id = ragFileRepository.saveDocumentMetadata(document); + assertThat(ragFileRepository.findDocumentByDocumentId(documentId).vectorUploadTimestamp()) + .isNull(); + + reconciler.submit(document.withId(id)); + await().until(reconciler::isEmpty); + await() + .untilAsserted( + () -> { + assertThat(reconciler.isEmpty()).isTrue(); + RagDocument updatedDocument = ragFileRepository.findDocumentByDocumentId(documentId); + assertThat(updatedDocument.summaryCreationTimestamp()).isEqualTo(Instant.EPOCH); + assertThat(requestTracker.getValues()) + .hasSize(1) + .contains( + new RagBackendClient.TrackedRequest<>( + new RagBackendClient.SummaryRequest("rag-files", "path_in_s3"))); + }); + } + private RagFileSummaryReconciler createTestInstance( - Tracker> tracker) { + Tracker> tracker, RuntimeException... exceptions) { Jdbi jdbi = new JdbiConfiguration().jdbi(); var reconcilerConfig = ReconcilerConfig.builder().isTestReconciler(true).workerCount(1).build(); RagFileSummaryReconciler reconciler = new RagFileSummaryReconciler( "rag-files", jdbi, - RagBackendClient.createNull(tracker), + RagBackendClient.createNull(tracker, exceptions), ragFileRepository, reconcilerConfig, OpenTelemetry.noop()); diff --git a/llm-service/Dockerfile b/llm-service/Dockerfile index 5f825b7..e4192ac 100644 --- a/llm-service/Dockerfile +++ b/llm-service/Dockerfile @@ -1,9 +1,11 @@ FROM docker-private.infra.cloudera.com/cloudera_base/hardened/cloudera-python:3.10 -COPY ./app/requirements.txt /app/ +RUN pip install pdm +COPY ./pyproject.toml /app/ +COPY ./pdm.lock /app/ WORKDIR /app -RUN pip install -r requirements.txt +RUN pdm install COPY ./app /app WORKDIR /app -CMD [ "fastapi", "run", "--host", "0.0.0.0" ] +CMD [ "pdm", "run", "fastapi", "run", "--host", "0.0.0.0" ] diff --git a/llm-service/app/rag_types.py b/llm-service/app/rag_types.py index c7a6b9a..19e47ee 100644 --- a/llm-service/app/rag_types.py +++ b/llm-service/app/rag_types.py @@ -36,14 +36,13 @@ # DATA. # ############################################################################## -from typing import List, Optional +from typing import Optional from pydantic import BaseModel -from .services.chat_store import RagContext, RagPredictSourceNode - class RagPredictConfiguration(BaseModel): top_k: int = 5 chunk_size: int = 512 model_name: str = "meta.llama3-1-8b-instruct-v1:0" + exclude_knowledge_base: Optional[bool] = False diff --git a/llm-service/app/requirements.txt b/llm-service/app/requirements.txt deleted file mode 100644 index f03a9ac..0000000 --- a/llm-service/app/requirements.txt +++ /dev/null @@ -1,17 +0,0 @@ -llama-index-core == 0.10.68 -llama-index-readers-file == 0.1.33 -fastapi == 0.111.0 -pydantic == 2.8.2 -pydantic-settings == 2.3.4 -boto3 == 1.34.26 -llama-index-embeddings-bedrock == 0.2.1 -llama-index-llms-bedrock == 0.1.13 -llama-index-llms-openai == 0.1.31 -llama-index-llms-mistralai == 0.1.20 -llama-index-embeddings-openai == 0.1.11 -llama-index-vector-stores-qdrant == 0.2.17 - - -# test deps -moto[s3] -pytest diff --git a/llm-service/app/routers/index/__init__.py b/llm-service/app/routers/index/__init__.py index de4e794..35607c7 100644 --- a/llm-service/app/routers/index/__init__.py +++ b/llm-service/app/routers/index/__init__.py @@ -36,17 +36,10 @@ # DATA. # ############################################################################## -import http import logging -import tempfile from fastapi import APIRouter -from pydantic import BaseModel -from ... import exceptions -from ...services import qdrant, s3 -from ...services.chat import (generate_suggested_questions, v2_chat) -from ...services.chat_store import RagContext, RagStudioChatMessage from . import data_source from . import sessions from . import amp_update @@ -55,74 +48,14 @@ logger = logging.getLogger(__name__) -router = APIRouter( - prefix="/index", -) +router = APIRouter() router.include_router(data_source.router) router.include_router(sessions.router) router.include_router(amp_update.router) +# include this for legacy UI calls +router.include_router(amp_update.router, prefix="/index", deprecated=True) router.include_router(models.router) -class SuggestQuestionsRequest(BaseModel): - data_source_id: int - chat_history: list[RagContext] - configuration: qdrant.RagPredictConfiguration = qdrant.RagPredictConfiguration() -class RagSuggestedQuestionsResponse(BaseModel): - suggested_questions: list[str] -class RagIndexDocumentRequest(BaseModel): - data_source_id: int - s3_bucket_name: str - s3_document_key: str - configuration: qdrant.RagIndexDocumentConfiguration = ( - qdrant.RagIndexDocumentConfiguration() - ) - - -@router.post( - "/download-and-index", - summary="Download and index document", - description="Download document from S3 and index in Pinecone", -) -@exceptions.propagates -def download_and_index( - request: RagIndexDocumentRequest, -) -> str: - with tempfile.TemporaryDirectory() as tmpdirname: - logger.debug("created temporary directory %s", tmpdirname) - s3.download(tmpdirname, request.s3_bucket_name, request.s3_document_key) - qdrant.download_and_index( - tmpdirname, - request.data_source_id, - request.configuration, - request.s3_document_key - ) - return http.HTTPStatus.OK.phrase - -@router.post("/suggest-questions", summary="Suggest questions with context") -@exceptions.propagates -def suggest_questions( - request: SuggestQuestionsRequest, -) -> RagSuggestedQuestionsResponse: - data_source_size = qdrant.size_of(request.data_source_id) - qdrant.check_data_source_exists(data_source_size) - suggested_questions = generate_suggested_questions( - request.configuration, request.data_source_id, request.chat_history, data_source_size - ) - return RagSuggestedQuestionsResponse(suggested_questions=suggested_questions) - -class RagStudioChatRequest(BaseModel): - data_source_id: int - session_id: int - query: str - configuration: qdrant.RagPredictConfiguration - - -@router.post("/chat", summary="Chat with your documents in the requested datasource") -@exceptions.propagates -def chat( - request: RagStudioChatRequest, -) -> RagStudioChatMessage: - return v2_chat(request.session_id, request.data_source_id, request.query, request.configuration) diff --git a/llm-service/app/routers/index/data_source/__init__.py b/llm-service/app/routers/index/data_source/__init__.py index ba8a5aa..aa7e133 100644 --- a/llm-service/app/routers/index/data_source/__init__.py +++ b/llm-service/app/routers/index/data_source/__init__.py @@ -28,11 +28,17 @@ # DATA. # ############################################################################## +import http +import logging +import tempfile + from fastapi import APIRouter from pydantic import BaseModel from .... import exceptions -from ....services import doc_summaries, qdrant +from ....services import doc_summaries, qdrant, s3 + +logger = logging.getLogger(__name__) router = APIRouter(prefix="/data_sources/{data_source_id}", tags=["Data Sources"]) @@ -92,3 +98,35 @@ def summarize_document( def delete_document(data_source_id: int, doc_id: str) -> None: qdrant.delete_document(data_source_id, doc_id) doc_summaries.delete_document(data_source_id, doc_id) + + + +class RagIndexDocumentRequest(BaseModel): + s3_bucket_name: str + s3_document_key: str + configuration: qdrant.RagIndexDocumentConfiguration = ( + qdrant.RagIndexDocumentConfiguration() + ) + + +@router.post( + "/documents/download-and-index", + summary="Download and index document", + description="Download document from S3 and index in Pinecone", +) +@exceptions.propagates +def download_and_index( + data_source_id: int, + request: RagIndexDocumentRequest, +) -> str: + with tempfile.TemporaryDirectory() as tmpdirname: + logger.debug("created temporary directory %s", tmpdirname) + s3.download(tmpdirname, request.s3_bucket_name, request.s3_document_key) + qdrant.download_and_index( + tmpdirname, + data_source_id, + request.configuration, + request.s3_document_key + ) + return http.HTTPStatus.OK.phrase + diff --git a/llm-service/app/routers/index/sessions/__init__.py b/llm-service/app/routers/index/sessions/__init__.py index 05b1707..ca514f8 100644 --- a/llm-service/app/routers/index/sessions/__init__.py +++ b/llm-service/app/routers/index/sessions/__init__.py @@ -35,11 +35,17 @@ # BUSINESS ADVANTAGE OR UNAVAILABILITY, OR LOSS OR CORRUPTION OF # DATA. # ############################################################################## +import time +import uuid from fastapi import APIRouter +from pydantic import BaseModel + from .... import exceptions from ....services.chat_store import RagStudioChatMessage, chat_store +from ....services import qdrant, llm_completion +from ....services.chat import (v2_chat, generate_suggested_questions) router = APIRouter(prefix="/sessions/{session_id}", tags=["Sessions"]) @@ -60,3 +66,58 @@ def delete_chat_history(session_id: int) -> str: chat_store.delete_chat_history(session_id=session_id) return "Chat history deleted." + +class RagStudioChatRequest(BaseModel): + data_source_id: int + query: str + configuration: qdrant.RagPredictConfiguration + + +@router.post("/chat", summary="Chat with your documents in the requested datasource") +@exceptions.propagates +def chat( + session_id: int, + request: RagStudioChatRequest, +) -> RagStudioChatMessage: + if request.configuration.exclude_knowledge_base: + return llm_talk(session_id, request) + return v2_chat(session_id, request.data_source_id, request.query, request.configuration) + +def llm_talk( + session_id: int, + request: RagStudioChatRequest, +) -> RagStudioChatMessage: + chat_response = llm_completion.completion(session_id, request.query, request.configuration) + new_chat_message = RagStudioChatMessage( + id=str(uuid.uuid4()), + source_nodes=[], + evaluations=[], + rag_message={ + "user": request.query, + "assistant": chat_response.message.content, + }, + timestamp=time.time() + ) + chat_store.append_to_history(session_id, [new_chat_message]) + return new_chat_message + + +class SuggestQuestionsRequest(BaseModel): + data_source_id: int + configuration: qdrant.RagPredictConfiguration = qdrant.RagPredictConfiguration() + +class RagSuggestedQuestionsResponse(BaseModel): + suggested_questions: list[str] + +@router.post("/suggest-questions", summary="Suggest questions with context") +@exceptions.propagates +def suggest_questions( + session_id: int, + request: SuggestQuestionsRequest, +) -> RagSuggestedQuestionsResponse: + data_source_size = qdrant.size_of(request.data_source_id) + qdrant.check_data_source_exists(data_source_size) + suggested_questions = generate_suggested_questions( + request.configuration, request.data_source_id, data_source_size, session_id + ) + return RagSuggestedQuestionsResponse(suggested_questions=suggested_questions) \ No newline at end of file diff --git a/llm-service/app/services/CaiiEmbeddingModel.py b/llm-service/app/services/CaiiEmbeddingModel.py index 36c976f..d0ed2ba 100644 --- a/llm-service/app/services/CaiiEmbeddingModel.py +++ b/llm-service/app/services/CaiiEmbeddingModel.py @@ -35,8 +35,10 @@ # BUSINESS ADVANTAGE OR UNAVAILABILITY, OR LOSS OR CORRUPTION OF # DATA. # - +import http.client as http_client import json +import os +from typing import List from llama_index.core.base.embeddings.base import BaseEmbedding, Embedding from openai import OpenAI @@ -60,19 +62,33 @@ def _get_query_embedding(self, query: str) -> Embedding: return self._get_embedding(query, "query") def _get_embedding(self, query: str, input_type: str) -> Embedding: - client, model = self._get_client() - query = query.replace("\n", " ") - return ( - client.embeddings.create(input=[query], extra_body={ "input_type": input_type, "truncate": "END"}, model=model).data[0].embedding - ) + model = self.endpoint["endpointmetadata"]["model_name"] + domain = os.environ['CAII_DOMAIN'] + + connection = http_client.HTTPSConnection(domain, 443) + headers = self.build_auth_headers() + headers["Content-Type"] = "application/json" + body = json.dumps({ + "input": query, + "input_type": input_type, + "truncate": "END", + "model": model + }) + connection.request("POST", self.endpoint["url"], body=body, headers=headers) + res = connection.getresponse() + data = res.read() + json_response = data.decode("utf-8") + structured_response = json.loads(json_response) + embedding = structured_response["data"][0]["embedding"] + + return embedding - def _get_client(self) -> (OpenAI, any): - api_base = self.endpoint["url"].removesuffix("/embeddings") + def build_auth_headers(self) -> dict: with open('/tmp/jwt', 'r') as file: jwt_contents = json.load(file) access_token = jwt_contents['access_token'] headers = { "Authorization": f"Bearer {access_token}" } - return OpenAI(base_url=api_base, default_headers=headers, api_key="api_key"), self.endpoint["endpointmetadata"]["model_name"] + return headers diff --git a/llm-service/app/services/CaiiModel.py b/llm-service/app/services/CaiiModel.py index f1897ed..b457621 100644 --- a/llm-service/app/services/CaiiModel.py +++ b/llm-service/app/services/CaiiModel.py @@ -35,7 +35,6 @@ # BUSINESS ADVANTAGE OR UNAVAILABILITY, OR LOSS OR CORRUPTION OF # DATA. # -from llama_index.core.base.llms import generic_utils from llama_index.core.base.llms.types import LLMMetadata from llama_index.core.bridge.pydantic import Field from llama_index.llms.mistralai.base import MistralAI @@ -60,7 +59,8 @@ def __init__( api_base=api_base, messages_to_prompt=messages_to_prompt, completion_to_prompt=completion_to_prompt, - default_headers=default_headers) + default_headers=default_headers, + context=context) self.context = context @property diff --git a/llm-service/app/services/chat.py b/llm-service/app/services/chat.py index fcc1cde..6f6a1d3 100644 --- a/llm-service/app/services/chat.py +++ b/llm-service/app/services/chat.py @@ -96,7 +96,7 @@ def v2_chat( return new_chat_message -def retrieve_chat_history(session_id): +def retrieve_chat_history(session_id) -> list[RagContext]: chat_history = chat_store.retrieve_chat_history(session_id)[:10] history: [RagContext] = list() for message in chat_history: @@ -130,8 +130,9 @@ def format_source_nodes(response): def generate_suggested_questions( - configuration, data_source_id, chat_history, data_source_size + configuration, data_source_id, data_source_size, session_id ): + chat_history = retrieve_chat_history(session_id) if data_source_size == 0: suggested_questions = [] else: diff --git a/llm-service/app/services/llm_completion.py b/llm-service/app/services/llm_completion.py new file mode 100644 index 0000000..16f9904 --- /dev/null +++ b/llm-service/app/services/llm_completion.py @@ -0,0 +1,59 @@ +# +# CLOUDERA APPLIED MACHINE LEARNING PROTOTYPE (AMP) +# (C) Cloudera, Inc. 2024 +# All rights reserved. +# +# Applicable Open Source License: Apache 2.0 +# +# NOTE: Cloudera open source products are modular software products +# made up of hundreds of individual components, each of which was +# individually copyrighted. Each Cloudera open source product is a +# collective work under U.S. Copyright Law. Your license to use the +# collective work is as provided in your written agreement with +# Cloudera. Used apart from the collective work, this file is +# licensed for your use pursuant to the open source license +# identified above. +# +# This code is provided to you pursuant a written agreement with +# (i) Cloudera, Inc. or (ii) a third-party authorized to distribute +# this code. If you do not have a written agreement with Cloudera nor +# with an authorized and properly licensed third party, you do not +# have any rights to access nor to use this code. +# +# Absent a written agreement with Cloudera, Inc. ("Cloudera") to the +# contrary, A) CLOUDERA PROVIDES THIS CODE TO YOU WITHOUT WARRANTIES OF ANY +# KIND; (B) CLOUDERA DISCLAIMS ANY AND ALL EXPRESS AND IMPLIED +# WARRANTIES WITH RESPECT TO THIS CODE, INCLUDING BUT NOT LIMITED TO +# IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE; (C) CLOUDERA IS NOT LIABLE TO YOU, +# AND WILL NOT DEFEND, INDEMNIFY, NOR HOLD YOU HARMLESS FOR ANY CLAIMS +# ARISING FROM OR RELATED TO THE CODE; AND (D)WITH RESPECT TO YOUR EXERCISE +# OF ANY RIGHTS GRANTED TO YOU FOR THE CODE, CLOUDERA IS NOT LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR +# CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, DAMAGES +# RELATED TO LOST REVENUE, LOST PROFITS, LOSS OF INCOME, LOSS OF +# BUSINESS ADVANTAGE OR UNAVAILABILITY, OR LOSS OR CORRUPTION OF +# DATA. +# +import itertools + +from llama_index.core.base.llms.types import ChatMessage, ChatResponse + +from .chat_store import chat_store, RagStudioChatMessage +from .qdrant import RagPredictConfiguration +from .models import get_llm + + +def make_chat_messages(x: RagStudioChatMessage) -> list[ChatMessage]: + user = ChatMessage.from_str(x.rag_message['user'], role="user") + assistant = ChatMessage.from_str(x.rag_message['assistant'], role="assistant") + return [user, assistant] + + +def completion(session_id: int, question: str, configuration: RagPredictConfiguration) -> ChatResponse: + model = get_llm(configuration.model_name) + chat_history = chat_store.retrieve_chat_history(session_id)[:10] + messages = list(itertools.chain.from_iterable(map(lambda x: make_chat_messages(x), chat_history))) + messages.append(ChatMessage.from_str(question, role="user")) + return model.chat(messages) + diff --git a/llm-service/app/services/models.py b/llm-service/app/services/models.py index 9ec94a2..bae197a 100644 --- a/llm-service/app/services/models.py +++ b/llm-service/app/services/models.py @@ -85,8 +85,9 @@ def get_available_llm_models(): return _get_bedrock_llm_models() -def is_caii_enabled(): - return "CAII_DOMAIN" in os.environ +def is_caii_enabled() -> bool: + domain: str = os.environ.get("CAII_DOMAIN", "") + return len(domain) > 0 def _get_bedrock_llm_models(): @@ -130,7 +131,7 @@ def test_llm_model(model_name: str) -> Literal["ok"]: models = get_available_llm_models() for model in models: if model["model_id"] == model_name: - if not is_caii_enabled() or model['available']: + if not is_caii_enabled() or model["available"]: get_llm(model_name).complete("Are you available to answer questions?") return "ok" else: @@ -138,14 +139,15 @@ def test_llm_model(model_name: str) -> Literal["ok"]: raise HTTPException(status_code=404, detail="Model not found") + def test_embedding_model(model_name: str) -> str: models = get_available_embedding_models() for model in models: if model["model_id"] == model_name: - if not is_caii_enabled() or model['available']: + if not is_caii_enabled() or model["available"]: # TODO: Update to pass embedding model in the future when multiple are supported - get_embedding_model().get_text_embedding('test') - return 'ok' + get_embedding_model().get_text_embedding("test") + return "ok" else: raise HTTPException(status_code=503, detail="Model not ready") diff --git a/llm-service/app/services/qdrant.py b/llm-service/app/services/qdrant.py index 11b3c05..ffc1cca 100644 --- a/llm-service/app/services/qdrant.py +++ b/llm-service/app/services/qdrant.py @@ -168,8 +168,7 @@ def query( response_synthesizer = get_response_synthesizer(llm=llm) query_engine = RetrieverQueryEngine( - retriever=retriever, response_synthesizer=response_synthesizer - ) + retriever=retriever, response_synthesizer=response_synthesizer) chat_engine = CondenseQuestionChatEngine.from_defaults( query_engine=query_engine, llm=llm, diff --git a/llm-service/app/tests/routers/index/test_data_source.py b/llm-service/app/tests/routers/index/test_data_source.py index 27aa588..51cdbef 100644 --- a/llm-service/app/tests/routers/index/test_data_source.py +++ b/llm-service/app/tests/routers/index/test_data_source.py @@ -62,9 +62,9 @@ def test_create_document( document_id: str, data_source_id: int, ) -> None: - """Test POST /index/download-and-index.""" + """Test POST /download-and-index.""" response = client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) @@ -81,9 +81,9 @@ def test_delete_data_source( document_id: str, index_document_request_body: dict[str, Any], ) -> None: - """Test DELETE /index/data_sources/{data_source_id}.""" + """Test DELETE /data_sources/{data_source_id}.""" client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) @@ -91,12 +91,12 @@ def test_delete_data_source( vectors = index.vector_store.query(VectorStoreQuery(query_embedding=[0.66] * 1024, doc_ids=[document_id])) assert len(vectors.nodes) == 1 - response = client.delete(f"/index/data_sources/{data_source_id}") + response = client.delete(f"/data_sources/{data_source_id}") assert response.status_code == 200 vector_store = rag_vector_store.create_rag_vector_store(data_source_id) assert vector_store.exists() is False - get_summary_response = client.get(f'/index/data_sources/{data_source_id}/documents/{document_id}/summary') + get_summary_response = client.get(f'/data_sources/{data_source_id}/documents/{document_id}/summary') assert get_summary_response.status_code == 404 @staticmethod @@ -106,9 +106,9 @@ def test_delete_document( document_id: str, index_document_request_body: dict[str, Any], ) -> None: - """Test DELETE /index/data_sources/{data_source_id}/documents/{document_id}.""" + """Test DELETE /data_sources/{data_source_id}/documents/{document_id}.""" client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) @@ -116,7 +116,7 @@ def test_delete_document( vectors = index.vector_store.query(VectorStoreQuery(query_embedding=[.2] * 1024, doc_ids=[document_id])) assert len(vectors.nodes) == 1 - response = client.delete(f"/index/data_sources/{data_source_id}/documents/{document_id}") + response = client.delete(f"/data_sources/{data_source_id}/documents/{document_id}") assert response.status_code == 200 index = get_vector_store_index(data_source_id) @@ -129,12 +129,12 @@ def test_get_size( data_source_id: int, index_document_request_body: dict[str, Any], ) -> None: - """Test GET /index/data_sources/{data_source_id}/size.""" + """Test GET /data_sources/{data_source_id}/size.""" client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) - response = client.get(f"/index/data_sources/{data_source_id}/size") + response = client.get(f"/data_sources/{data_source_id}/size") assert response.status_code == 200 assert response.json() == 1 diff --git a/llm-service/app/tests/routers/index/test_doc_summaries.py b/llm-service/app/tests/routers/index/test_doc_summaries.py index daafaed..8095121 100644 --- a/llm-service/app/tests/routers/index/test_doc_summaries.py +++ b/llm-service/app/tests/routers/index/test_doc_summaries.py @@ -43,25 +43,25 @@ class TestDocumentSummaries: @staticmethod def test_generate_summary(client, index_document_request_body: dict[str, Any], data_source_id, document_id, s3_object) -> None: response = client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) assert response.status_code == 200 post_summarization_response = client.post( - f'/index/data_sources/{data_source_id}/summarize-document', + f'/data_sources/{data_source_id}/summarize-document', json={ "s3_bucket_name": s3_object.bucket_name, "s3_document_key": s3_object.key }) assert post_summarization_response.status_code == 200 assert post_summarization_response.text == '"this is a completion response"' - get_summary_response = client.get(f'/index/data_sources/{data_source_id}/documents/{document_id}/summary') + get_summary_response = client.get(f'/data_sources/{data_source_id}/documents/{document_id}/summary') assert get_summary_response.status_code == 200 assert get_summary_response.text == '"this is a completion response"' - get_data_source_response = client.get(f'/index/data_sources/{data_source_id}/summary') + get_data_source_response = client.get(f'/data_sources/{data_source_id}/summary') assert get_data_source_response.status_code == 200 # our monkeypatched model always returns this. # todo: Figure out how to parameterize the monkey patch @@ -70,23 +70,23 @@ def test_generate_summary(client, index_document_request_body: dict[str, Any], d @staticmethod def test_delete_document(client, index_document_request_body: dict[str, Any], data_source_id, document_id, s3_object) -> None: response = client.post( - "/index/download-and-index", + f"/data_sources/{data_source_id}/documents/download-and-index", json=index_document_request_body, ) assert response.status_code == 200 post_summarization_response = client.post( - f'/index/data_sources/{data_source_id}/summarize-document', + f'/data_sources/{data_source_id}/summarize-document', json={ "s3_bucket_name": s3_object.bucket_name, "s3_document_key": s3_object.key }) assert post_summarization_response.status_code == 200 - delete_document_response = client.delete(f'/index/data_sources/{data_source_id}/documents/{document_id}') + delete_document_response = client.delete(f'/data_sources/{data_source_id}/documents/{document_id}') assert delete_document_response.status_code == 200 - get_summary_response = client.get(f'/index/data_sources/{data_source_id}/documents/{document_id}/summary') + get_summary_response = client.get(f'/data_sources/{data_source_id}/documents/{document_id}/summary') assert get_summary_response.text == '"No summary found for this document."' assert get_summary_response.status_code == 200 diff --git a/llm-service/pdm.lock b/llm-service/pdm.lock new file mode 100644 index 0000000..167a254 --- /dev/null +++ b/llm-service/pdm.lock @@ -0,0 +1,2149 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "dev"] +strategy = ["inherit_metadata"] +lock_version = "4.5.0" +content_hash = "sha256:1b447e8bd4e21937a21505e71d488e708db69dc5fec8cdeed5608fae5dfbfeb5" + +[[metadata.targets]] +requires_python = "==3.10.*" + +[[package]] +name = "aiohappyeyeballs" +version = "2.4.3" +requires_python = ">=3.8" +summary = "Happy Eyeballs for asyncio" +groups = ["default"] +files = [ + {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, + {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, +] + +[[package]] +name = "aiohttp" +version = "3.11.6" +requires_python = ">=3.9" +summary = "Async http client/server framework (asyncio)" +groups = ["default"] +dependencies = [ + "aiohappyeyeballs>=2.3.0", + "aiosignal>=1.1.2", + "async-timeout<6.0,>=4.0; python_version < \"3.11\"", + "attrs>=17.3.0", + "frozenlist>=1.1.1", + "multidict<7.0,>=4.5", + "propcache>=0.2.0", + "yarl<2.0,>=1.17.0", +] +files = [ + {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7510b3ca2275691875ddf072a5b6cd129278d11fe09301add7d292fc8d3432de"}, + {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfab0d2c3380c588fc925168533edb21d3448ad76c3eadc360ff963019161724"}, + {file = "aiohttp-3.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf02dba0f342f3a8228f43fae256aafc21c4bc85bffcf537ce4582e2b1565188"}, + {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92daedf7221392e7a7984915ca1b0481a94c71457c2f82548414a41d65555e70"}, + {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2274a7876e03429e3218589a6d3611a194bdce08c3f1e19962e23370b47c0313"}, + {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a2e1eae2d2f62f3660a1591e16e543b2498358593a73b193006fb89ee37abc6"}, + {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978ec3fb0a42efcd98aae608f58c6cfcececaf0a50b4e86ee3ea0d0a574ab73b"}, + {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51f87b27d9219ed4e202ed8d6f1bb96f829e5eeff18db0d52f592af6de6bdbf"}, + {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:04d1a02a669d26e833c8099992c17f557e3b2fdb7960a0c455d7b1cbcb05121d"}, + {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3679d5fcbc7f1ab518ab4993f12f80afb63933f6afb21b9b272793d398303b98"}, + {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a4b24e03d04893b5c8ec9cd5f2f11dc9c8695c4e2416d2ac2ce6c782e4e5ffa5"}, + {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d9abdfd35ecff1c95f270b7606819a0e2de9e06fa86b15d9080de26594cf4c23"}, + {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b5c3e7928a0ad80887a5eba1c1da1830512ddfe7394d805badda45c03db3109"}, + {file = "aiohttp-3.11.6-cp310-cp310-win32.whl", hash = "sha256:913dd9e9378f3c38aeb5c4fb2b8383d6490bc43f3b427ae79f2870651ae08f22"}, + {file = "aiohttp-3.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:4ac26d482c2000c3a59bf757a77adc972828c9d4177b4bd432a46ba682ca7271"}, + {file = "aiohttp-3.11.6.tar.gz", hash = "sha256:fd9f55c1b51ae1c20a1afe7216a64a88d38afee063baa23c7fce03757023c999"}, +] + +[[package]] +name = "aiosignal" +version = "1.3.1" +requires_python = ">=3.7" +summary = "aiosignal: a list of registered asynchronous callbacks" +groups = ["default"] +dependencies = [ + "frozenlist>=1.1.0", +] +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +requires_python = ">=3.8" +summary = "Reusable constraint types to use with typing.Annotated" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0.0; python_version < \"3.9\"", +] +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"}, +] + +[[package]] +name = "anthropic" +version = "0.28.1" +requires_python = ">=3.7" +summary = "The official Python library for the anthropic API" +groups = ["default"] +dependencies = [ + "anyio<5,>=3.5.0", + "cached-property; python_version < \"3.8\"", + "distro<2,>=1.7.0", + "httpx<1,>=0.23.0", + "jiter<1,>=0.4.0", + "pydantic<3,>=1.9.0", + "sniffio", + "tokenizers>=0.13.0", + "typing-extensions<5,>=4.7", +] +files = [ + {file = "anthropic-0.28.1-py3-none-any.whl", hash = "sha256:c4773ae2b42951a6b747bed328b0d03fa412938c95c3a8b9dce70d69badb710b"}, + {file = "anthropic-0.28.1.tar.gz", hash = "sha256:e3a6d595bde241141bdc685edc393903ec95c7fa378013a71186cfb8f32b1793"}, +] + +[[package]] +name = "anyio" +version = "4.6.2.post1" +requires_python = ">=3.9" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +groups = ["default"] +dependencies = [ + "exceptiongroup>=1.0.2; python_version < \"3.11\"", + "idna>=2.8", + "sniffio>=1.1", + "typing-extensions>=4.1; python_version < \"3.11\"", +] +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"}, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +requires_python = ">=3.8" +summary = "Timeout context manager for asyncio programs" +groups = ["default"] +marker = "python_version < \"3.11\"" +files = [ + {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, + {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, +] + +[[package]] +name = "attrs" +version = "24.2.0" +requires_python = ">=3.7" +summary = "Classes Without Boilerplate" +groups = ["default"] +dependencies = [ + "importlib-metadata; python_version < \"3.8\"", +] +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +requires_python = ">=3.6.0" +summary = "Screen-scraping library" +groups = ["default"] +dependencies = [ + "soupsieve>1.2", +] +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[[package]] +name = "boto3" +version = "1.34.26" +requires_python = ">= 3.8" +summary = "The AWS SDK for Python" +groups = ["default", "dev"] +dependencies = [ + "botocore<1.35.0,>=1.34.26", + "jmespath<2.0.0,>=0.7.1", + "s3transfer<0.11.0,>=0.10.0", +] +files = [ + {file = "boto3-1.34.26-py3-none-any.whl", hash = "sha256:881b07d0d55e5d85b62e6c965efcb2820bdfbd8f23a73a7bc9dac3a4997a1343"}, + {file = "boto3-1.34.26.tar.gz", hash = "sha256:0491a65e55de999d07f42bb28ff6a38bad493934154b6304fcdfb4699a612d6c"}, +] + +[[package]] +name = "botocore" +version = "1.34.162" +requires_python = ">=3.8" +summary = "Low-level, data-driven core of boto 3." +groups = ["default", "dev"] +dependencies = [ + "jmespath<2.0.0,>=0.7.1", + "python-dateutil<3.0.0,>=2.1", + "urllib3!=2.2.0,<3,>=1.25.4; python_version >= \"3.10\"", + "urllib3<1.27,>=1.25.4; python_version < \"3.10\"", +] +files = [ + {file = "botocore-1.34.162-py3-none-any.whl", hash = "sha256:2d918b02db88d27a75b48275e6fb2506e9adaaddbec1ffa6a8a0898b34e769be"}, + {file = "botocore-1.34.162.tar.gz", hash = "sha256:adc23be4fb99ad31961236342b7cbf3c0bfc62532cd02852196032e8c0d682f3"}, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default", "dev"] +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +requires_python = ">=3.8" +summary = "Foreign Function Interface for Python calling C code." +groups = ["dev"] +marker = "platform_python_implementation != \"PyPy\"" +dependencies = [ + "pycparser", +] +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"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +requires_python = ">=3.7.0" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +groups = ["default", "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"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +requires_python = ">=3.7" +summary = "Composable command line interface toolkit" +groups = ["default"] +dependencies = [ + "colorama; platform_system == \"Windows\"", + "importlib-metadata; python_version < \"3.8\"", +] +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["default", "dev"] +marker = "sys_platform == \"win32\" or platform_system == \"Windows\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "cryptography" +version = "43.0.3" +requires_python = ">=3.7" +summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +groups = ["dev"] +dependencies = [ + "cffi>=1.12; platform_python_implementation != \"PyPy\"", +] +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"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +] + +[[package]] +name = "dataclasses-json" +version = "0.6.7" +requires_python = "<4.0,>=3.7" +summary = "Easily serialize dataclasses to and from JSON." +groups = ["default"] +dependencies = [ + "marshmallow<4.0.0,>=3.18.0", + "typing-inspect<1,>=0.4.0", +] +files = [ + {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, + {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, +] + +[[package]] +name = "deprecated" +version = "1.2.15" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +summary = "Python @deprecated decorator to deprecate old python classes, functions or methods." +groups = ["default"] +dependencies = [ + "wrapt<2,>=1.10", +] +files = [ + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, +] + +[[package]] +name = "dirtyjson" +version = "1.0.8" +summary = "JSON decoder for Python that can extract data from the muck" +groups = ["default"] +files = [ + {file = "dirtyjson-1.0.8-py3-none-any.whl", hash = "sha256:125e27248435a58acace26d5c2c4c11a1c0de0a9c5124c5a94ba78e517d74f53"}, + {file = "dirtyjson-1.0.8.tar.gz", hash = "sha256:90ca4a18f3ff30ce849d100dcf4a003953c79d3a2348ef056f1d9c22231a25fd"}, +] + +[[package]] +name = "distro" +version = "1.9.0" +requires_python = ">=3.6" +summary = "Distro - an OS platform information API" +groups = ["default"] +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "dnspython" +version = "2.7.0" +requires_python = ">=3.9" +summary = "DNS toolkit" +groups = ["default"] +files = [ + {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, + {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, +] + +[[package]] +name = "email-validator" +version = "2.2.0" +requires_python = ">=3.8" +summary = "A robust email address syntax and deliverability validation library." +groups = ["default"] +dependencies = [ + "dnspython>=2.0.0", + "idna>=2.0.0", +] +files = [ + {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, + {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" +groups = ["default", "dev"] +marker = "python_version < \"3.11\"" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[[package]] +name = "fastapi" +version = "0.111.0" +requires_python = ">=3.8" +summary = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +groups = ["default"] +dependencies = [ + "email-validator>=2.0.0", + "fastapi-cli>=0.0.2", + "httpx>=0.23.0", + "jinja2>=2.11.2", + "orjson>=3.2.1", + "pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4", + "python-multipart>=0.0.7", + "starlette<0.38.0,>=0.37.2", + "typing-extensions>=4.8.0", + "ujson!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,>=4.0.1", + "uvicorn[standard]>=0.12.0", +] +files = [ + {file = "fastapi-0.111.0-py3-none-any.whl", hash = "sha256:97ecbf994be0bcbdadedf88c3150252bed7b2087075ac99735403b1b76cc8fc0"}, + {file = "fastapi-0.111.0.tar.gz", hash = "sha256:b9db9dd147c91cb8b769f7183535773d8741dd46f9dc6676cd82eab510228cd7"}, +] + +[[package]] +name = "fastapi-cli" +version = "0.0.5" +requires_python = ">=3.8" +summary = "Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀" +groups = ["default"] +dependencies = [ + "typer>=0.12.3", + "uvicorn[standard]>=0.15.0", +] +files = [ + {file = "fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46"}, + {file = "fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f"}, +] + +[[package]] +name = "filelock" +version = "3.16.1" +requires_python = ">=3.8" +summary = "A platform independent file lock." +groups = ["default"] +files = [ + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, +] + +[[package]] +name = "frozenlist" +version = "1.5.0" +requires_python = ">=3.8" +summary = "A list-like structure which implements collections.abc.MutableSequence" +groups = ["default"] +files = [ + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, + {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, + {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, +] + +[[package]] +name = "fsspec" +version = "2024.10.0" +requires_python = ">=3.8" +summary = "File-system specification" +groups = ["default"] +files = [ + {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, + {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, +] + +[[package]] +name = "greenlet" +version = "3.1.1" +requires_python = ">=3.7" +summary = "Lightweight in-process concurrent programming" +groups = ["default"] +files = [ + {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, + {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, + {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, +] + +[[package]] +name = "grpcio" +version = "1.68.0" +requires_python = ">=3.8" +summary = "HTTP/2-based RPC framework" +groups = ["default"] +files = [ + {file = "grpcio-1.68.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:619b5d0f29f4f5351440e9343224c3e19912c21aeda44e0c49d0d147a8d01544"}, + {file = "grpcio-1.68.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a59f5822f9459bed098ffbceb2713abbf7c6fd13f2b9243461da5c338d0cd6c3"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:c03d89df516128febc5a7e760d675b478ba25802447624edf7aa13b1e7b11e2a"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44bcbebb24363d587472089b89e2ea0ab2e2b4df0e4856ba4c0b087c82412121"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79f81b7fbfb136247b70465bd836fa1733043fdee539cd6031cb499e9608a110"}, + {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:88fb2925789cfe6daa20900260ef0a1d0a61283dfb2d2fffe6194396a354c618"}, + {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:99f06232b5c9138593ae6f2e355054318717d32a9c09cdc5a2885540835067a1"}, + {file = "grpcio-1.68.0-cp310-cp310-win32.whl", hash = "sha256:a6213d2f7a22c3c30a479fb5e249b6b7e648e17f364598ff64d08a5136fe488b"}, + {file = "grpcio-1.68.0-cp310-cp310-win_amd64.whl", hash = "sha256:15327ab81131ef9b94cb9f45b5bd98803a179c7c61205c8c0ac9aff9d6c4e82a"}, + {file = "grpcio-1.68.0.tar.gz", hash = "sha256:7e7483d39b4a4fddb9906671e9ea21aaad4f031cdfc349fec76bdfa1e404543a"}, +] + +[[package]] +name = "grpcio-tools" +version = "1.68.0" +requires_python = ">=3.8" +summary = "Protobuf code generator for gRPC" +groups = ["default"] +dependencies = [ + "grpcio>=1.68.0", + "protobuf<6.0dev,>=5.26.1", + "setuptools", +] +files = [ + {file = "grpcio_tools-1.68.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:9509a5c3ed3d54fa7ac20748d501cb86668f764605a0a68f275339ee0f1dc1a6"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:59a885091bf29700ba0e14a954d156a18714caaa2006a7f328b18e1ac4b1e721"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:d3e678162e1d7a8720dc05fdd537fc8df082a50831791f7bb1c6f90095f8368b"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10d03e3ad4af6284fd27cb14f5a3d52045913c1253e3e24a384ed91bc8adbfcd"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1769d7f529de1cc102f7fb900611e3c0b69bdb244fca1075b24d6e5b49024586"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:88640d95ee41921ac7352fa5fadca52a06d7e21fbe53e6a706a9a494f756be7d"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e903d07bc65232aa9e7704c829aec263e1e139442608e473d7912417a9908e29"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-win32.whl", hash = "sha256:66b70b37184d40806844f51c2757c6b852511d4ea46a3bf2c7e931a47b455bc6"}, + {file = "grpcio_tools-1.68.0-cp310-cp310-win_amd64.whl", hash = "sha256:b47ae076ffb29a68e517bc03552bef0d9c973f8e18adadff180b123e973a26ea"}, + {file = "grpcio_tools-1.68.0.tar.gz", hash = "sha256:737804ec2225dd4cc27e633b4ca0e963b0795161bf678285fab6586e917fd867"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +requires_python = ">=3.7" +summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.8\"", +] +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "h2" +version = "4.1.0" +requires_python = ">=3.6.1" +summary = "HTTP/2 State-Machine based protocol implementation" +groups = ["default"] +dependencies = [ + "hpack<5,>=4.0", + "hyperframe<7,>=6.0", +] +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] + +[[package]] +name = "hpack" +version = "4.0.0" +requires_python = ">=3.6.1" +summary = "Pure-Python HPACK header compression" +groups = ["default"] +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +requires_python = ">=3.8" +summary = "A minimal low-level HTTP client." +groups = ["default"] +dependencies = [ + "certifi", + "h11<0.15,>=0.13", +] +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[[package]] +name = "httptools" +version = "0.6.4" +requires_python = ">=3.8.0" +summary = "A collection of framework independent HTTP protocol utils." +groups = ["default"] +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"}, + {file = "httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1"}, + {file = "httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50"}, + {file = "httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959"}, + {file = "httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4"}, + {file = "httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c"}, + {file = "httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c"}, +] + +[[package]] +name = "httpx" +version = "0.27.2" +requires_python = ">=3.8" +summary = "The next generation HTTP client." +groups = ["default"] +dependencies = [ + "anyio", + "certifi", + "httpcore==1.*", + "idna", + "sniffio", +] +files = [ + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, +] + +[[package]] +name = "httpx" +version = "0.27.2" +extras = ["http2"] +requires_python = ">=3.8" +summary = "The next generation HTTP client." +groups = ["default"] +dependencies = [ + "h2<5,>=3", + "httpx==0.27.2", +] +files = [ + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, +] + +[[package]] +name = "huggingface-hub" +version = "0.26.2" +requires_python = ">=3.8.0" +summary = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" +groups = ["default"] +dependencies = [ + "filelock", + "fsspec>=2023.5.0", + "packaging>=20.9", + "pyyaml>=5.1", + "requests", + "tqdm>=4.42.1", + "typing-extensions>=3.7.4.3", +] +files = [ + {file = "huggingface_hub-0.26.2-py3-none-any.whl", hash = "sha256:98c2a5a8e786c7b2cb6fdeb2740893cba4d53e312572ed3d8afafda65b128c46"}, + {file = "huggingface_hub-0.26.2.tar.gz", hash = "sha256:b100d853465d965733964d123939ba287da60a547087783ddff8a323f340332b"}, +] + +[[package]] +name = "hyperframe" +version = "6.0.1" +requires_python = ">=3.6.1" +summary = "HTTP/2 framing layer for Python" +groups = ["default"] +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] + +[[package]] +name = "idna" +version = "3.10" +requires_python = ">=3.6" +summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default", "dev"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" +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"}, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +requires_python = ">=3.7" +summary = "A very fast and expressive template engine." +groups = ["default", "dev"] +dependencies = [ + "MarkupSafe>=2.0", +] +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[[package]] +name = "jiter" +version = "0.7.1" +requires_python = ">=3.8" +summary = "Fast iterable JSON parser." +groups = ["default"] +files = [ + {file = "jiter-0.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:262e96d06696b673fad6f257e6a0abb6e873dc22818ca0e0600f4a1189eb334f"}, + {file = "jiter-0.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be6de02939aac5be97eb437f45cfd279b1dc9de358b13ea6e040e63a3221c40d"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935f10b802bc1ce2b2f61843e498c7720aa7f4e4bb7797aa8121eab017293c3d"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9cd3cccccabf5064e4bb3099c87bf67db94f805c1e62d1aefd2b7476e90e0ee2"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4aa919ebfc5f7b027cc368fe3964c0015e1963b92e1db382419dadb098a05192"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ae2d01e82c94491ce4d6f461a837f63b6c4e6dd5bb082553a70c509034ff3d4"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f9568cd66dbbdab67ae1b4c99f3f7da1228c5682d65913e3f5f95586b3cb9a9"}, + {file = "jiter-0.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ecbf4e20ec2c26512736284dc1a3f8ed79b6ca7188e3b99032757ad48db97dc"}, + {file = "jiter-0.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1a0508fddc70ce00b872e463b387d49308ef02b0787992ca471c8d4ba1c0fa1"}, + {file = "jiter-0.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f84c9996664c460f24213ff1e5881530abd8fafd82058d39af3682d5fd2d6316"}, + {file = "jiter-0.7.1-cp310-none-win32.whl", hash = "sha256:c915e1a1960976ba4dfe06551ea87063b2d5b4d30759012210099e712a414d9f"}, + {file = "jiter-0.7.1-cp310-none-win_amd64.whl", hash = "sha256:75bf3b7fdc5c0faa6ffffcf8028a1f974d126bac86d96490d1b51b3210aa0f3f"}, + {file = "jiter-0.7.1.tar.gz", hash = "sha256:448cf4f74f7363c34cdef26214da527e8eeffd88ba06d0b80b485ad0667baf5d"}, +] + +[[package]] +name = "jmespath" +version = "1.0.1" +requires_python = ">=3.7" +summary = "JSON Matching Expressions" +groups = ["default", "dev"] +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "joblib" +version = "1.4.2" +requires_python = ">=3.8" +summary = "Lightweight pipelining with Python functions" +groups = ["default"] +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "jsonpath-python" +version = "1.0.6" +requires_python = ">=3.6" +summary = "A more powerful JSONPath implementation in modern python" +groups = ["default"] +files = [ + {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, + {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, +] + +[[package]] +name = "llama-index-core" +version = "0.10.68" +requires_python = "<4.0,>=3.8.1" +summary = "Interface between LLMs and your data" +groups = ["default"] +dependencies = [ + "PyYAML>=6.0.1", + "SQLAlchemy[asyncio]>=1.4.49", + "aiohttp<4.0.0,>=3.8.6", + "dataclasses-json", + "deprecated>=1.2.9.3", + "dirtyjson<2.0.0,>=1.0.8", + "fsspec>=2023.5.0", + "httpx", + "nest-asyncio<2.0.0,>=1.5.8", + "networkx>=3.0", + "nltk!=3.9,>=3.8.1", + "numpy<2.0.0", + "pandas", + "pillow>=9.0.0", + "requests>=2.31.0", + "tenacity!=8.4.0,<9.0.0,>=8.2.0", + "tiktoken>=0.3.3", + "tqdm<5.0.0,>=4.66.1", + "typing-extensions>=4.5.0", + "typing-inspect>=0.8.0", + "wrapt", +] +files = [ + {file = "llama_index_core-0.10.68-py3-none-any.whl", hash = "sha256:b579128e2a59e3543e5c2aa7f8c9107e8095c48cf9a1be27c28bcc7e96e5f718"}, + {file = "llama_index_core-0.10.68.tar.gz", hash = "sha256:82004709011f3d6a6543cc9f1a7797678c53349d6d17e25d443d4962c59a1efc"}, +] + +[[package]] +name = "llama-index-embeddings-bedrock" +version = "0.2.1" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index embeddings bedrock integration" +groups = ["default"] +dependencies = [ + "boto3<2.0.0,>=1.34.23", + "llama-index-core<0.11.0,>=0.10.1", +] +files = [ + {file = "llama_index_embeddings_bedrock-0.2.1-py3-none-any.whl", hash = "sha256:94f5ea8135a754ecb61dcab8b5f5d01ea0c4bfe0d923d35c230a3ae7cf442272"}, + {file = "llama_index_embeddings_bedrock-0.2.1.tar.gz", hash = "sha256:51430522637cfb06034b99a104752a20e660632b7792356b5a6126a239f78505"}, +] + +[[package]] +name = "llama-index-embeddings-openai" +version = "0.1.11" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index embeddings openai integration" +groups = ["default"] +dependencies = [ + "llama-index-core<0.11.0,>=0.10.1", +] +files = [ + {file = "llama_index_embeddings_openai-0.1.11-py3-none-any.whl", hash = "sha256:e20806fc4baff6b8f5274decf2c1ca7c5c737648e01865475ffada164e32e173"}, + {file = "llama_index_embeddings_openai-0.1.11.tar.gz", hash = "sha256:6025e229e375201788a9b14d6ebe470329907576cba5f6b7b832c3d68f39db30"}, +] + +[[package]] +name = "llama-index-llms-anthropic" +version = "0.1.17" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index llms anthropic integration" +groups = ["default"] +dependencies = [ + "anthropic<0.29.0,>=0.26.2", + "llama-index-core<0.11.0,>=0.10.57", +] +files = [ + {file = "llama_index_llms_anthropic-0.1.17-py3-none-any.whl", hash = "sha256:e4c2b07a890d0d6f51707379c535df82b2575e187e98ac5e0eb71ab20e3fec26"}, + {file = "llama_index_llms_anthropic-0.1.17.tar.gz", hash = "sha256:436cb69505839af953ab00113e758011774b466bb819b7f3785a306c043a36f2"}, +] + +[[package]] +name = "llama-index-llms-bedrock" +version = "0.1.13" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index llms bedrock integration" +groups = ["default"] +dependencies = [ + "boto3<2.0.0,>=1.34.26", + "llama-index-core<0.11.0,>=0.10.1", + "llama-index-llms-anthropic<0.2.0,>=0.1.7", +] +files = [ + {file = "llama_index_llms_bedrock-0.1.13-py3-none-any.whl", hash = "sha256:ac66932dc08b9ba83ad5914bee74975488bcdf1be143af7aa31289c120c76d3e"}, + {file = "llama_index_llms_bedrock-0.1.13.tar.gz", hash = "sha256:9a7a2e257302a7692dab23b42cf97eec5c6209c2afa7a865a42f9c1e29e689c7"}, +] + +[[package]] +name = "llama-index-llms-mistralai" +version = "0.1.20" +requires_python = "<4.0,>=3.9" +summary = "llama-index llms mistral ai integration" +groups = ["default"] +dependencies = [ + "llama-index-core<0.11.0,>=0.10.57", + "mistralai>=1.0.0", +] +files = [ + {file = "llama_index_llms_mistralai-0.1.20-py3-none-any.whl", hash = "sha256:5f1b67743735accddd6e64c7f128567419cd22b6a49fb07ca77aa205760030b1"}, + {file = "llama_index_llms_mistralai-0.1.20.tar.gz", hash = "sha256:37c0ae872f3d4c0c7822dcbd000a61ea41491c19a089ebc7baf2edd8ed1530d7"}, +] + +[[package]] +name = "llama-index-llms-openai" +version = "0.1.31" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index llms openai integration" +groups = ["default"] +dependencies = [ + "llama-index-core<0.11.0,>=0.10.57", + "openai<2.0.0,>=1.40.0", +] +files = [ + {file = "llama_index_llms_openai-0.1.31-py3-none-any.whl", hash = "sha256:800815b1b964b7d8dddd0e02a09fb57ac5f2ec6f80db92cd704dae718846023f"}, + {file = "llama_index_llms_openai-0.1.31.tar.gz", hash = "sha256:c235493f453b92903722054a8dfb1452ea850eac47a68a38bab3b823988d56fe"}, +] + +[[package]] +name = "llama-index-readers-file" +version = "0.1.33" +requires_python = "<4.0,>=3.8.1" +summary = "llama-index readers file integration" +groups = ["default"] +dependencies = [ + "beautifulsoup4<5.0.0,>=4.12.3", + "llama-index-core<0.11.0,>=0.10.37.post1", + "pypdf<5.0.0,>=4.0.1", + "striprtf<0.0.27,>=0.0.26", +] +files = [ + {file = "llama_index_readers_file-0.1.33-py3-none-any.whl", hash = "sha256:c968308497c1355acf61fe7e3f05ad8e308bb6487dddd3bd2a60e102225d0b38"}, + {file = "llama_index_readers_file-0.1.33.tar.gz", hash = "sha256:247a4d5bfabc7d1022027adf58064bc16c224d006db142abb0d182ac5574a887"}, +] + +[[package]] +name = "llama-index-vector-stores-qdrant" +version = "0.2.17" +requires_python = "<3.13,>=3.9" +summary = "llama-index vector_stores qdrant integration" +groups = ["default"] +dependencies = [ + "grpcio<2.0.0,>=1.60.0", + "llama-index-core<0.11.0,>=0.10.1", + "qdrant-client>=1.7.1", +] +files = [ + {file = "llama_index_vector_stores_qdrant-0.2.17-py3-none-any.whl", hash = "sha256:ac0a81c8a24e52b292e972a923be356ff7bb933a88b2a49b1172c193c7524cae"}, + {file = "llama_index_vector_stores_qdrant-0.2.17.tar.gz", hash = "sha256:a898da1929fec298bcd6827823aacdc0a18e6bd553770141069575ae8454bcc3"}, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +requires_python = ">=3.8" +summary = "Python port of markdown-it. Markdown parsing, done right!" +groups = ["default"] +dependencies = [ + "mdurl~=0.1", +] +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +requires_python = ">=3.9" +summary = "Safely add untrusted strings to HTML/XML markup." +groups = ["default", "dev"] +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "marshmallow" +version = "3.23.1" +requires_python = ">=3.9" +summary = "A lightweight library for converting complex datatypes to and from native Python datatypes." +groups = ["default"] +dependencies = [ + "packaging>=17.0", +] +files = [ + {file = "marshmallow-3.23.1-py3-none-any.whl", hash = "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"}, + {file = "marshmallow-3.23.1.tar.gz", hash = "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468"}, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +requires_python = ">=3.7" +summary = "Markdown URL utilities" +groups = ["default"] +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mistralai" +version = "1.0.3" +requires_python = "<4.0,>=3.8" +summary = "Python Client SDK for the Mistral AI API." +groups = ["default"] +dependencies = [ + "httpx<0.28.0,>=0.27.0", + "jsonpath-python<2.0.0,>=1.0.6", + "pydantic<2.9.0,>=2.8.2", + "python-dateutil<3.0.0,>=2.9.0.post0", + "typing-inspect<0.10.0,>=0.9.0", +] +files = [ + {file = "mistralai-1.0.3-py3-none-any.whl", hash = "sha256:64af7c9192e64dc66b2da6d1c4d54a1324a881c21665a2f93d6b35d9de9f87c8"}, + {file = "mistralai-1.0.3.tar.gz", hash = "sha256:84f1a217666c76fec9d477ae266399b813c3ac32a4a348d2ecd5fe1c039b0667"}, +] + +[[package]] +name = "moto" +version = "5.0.21" +requires_python = ">=3.8" +summary = "" +groups = ["dev"] +dependencies = [ + "Jinja2>=2.10.1", + "boto3>=1.9.201", + "botocore!=1.35.45,!=1.35.46,>=1.14.0", + "cryptography>=3.3.1", + "python-dateutil<3.0.0,>=2.1", + "requests>=2.5", + "responses>=0.15.0", + "werkzeug!=2.2.0,!=2.2.1,>=0.5", + "xmltodict", +] +files = [ + {file = "moto-5.0.21-py3-none-any.whl", hash = "sha256:1235b2ae3666459c9cc44504a5e73d35f4959b45e5876b2f6df2e5f4889dfb4f"}, + {file = "moto-5.0.21.tar.gz", hash = "sha256:52f63291daeff9444ef5eb14fbf69b24264567b79f184ae6aee4945d09845f06"}, +] + +[[package]] +name = "moto" +version = "5.0.21" +extras = ["s3"] +requires_python = ">=3.8" +summary = "" +groups = ["dev"] +dependencies = [ + "PyYAML>=5.1", + "moto==5.0.21", + "py-partiql-parser==0.5.6", +] +files = [ + {file = "moto-5.0.21-py3-none-any.whl", hash = "sha256:1235b2ae3666459c9cc44504a5e73d35f4959b45e5876b2f6df2e5f4889dfb4f"}, + {file = "moto-5.0.21.tar.gz", hash = "sha256:52f63291daeff9444ef5eb14fbf69b24264567b79f184ae6aee4945d09845f06"}, +] + +[[package]] +name = "multidict" +version = "6.1.0" +requires_python = ">=3.8" +summary = "multidict implementation" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.1.0; python_version < \"3.11\"", +] +files = [ + {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, + {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, + {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, + {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, + {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, + {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, + {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +requires_python = ">=3.5" +summary = "Type system extensions for programs checked with the mypy type checker." +groups = ["default"] +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"}, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +requires_python = ">=3.5" +summary = "Patch asyncio to allow nested event loops" +groups = ["default"] +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "networkx" +version = "3.4.2" +requires_python = ">=3.10" +summary = "Python package for creating and manipulating graphs and networks" +groups = ["default"] +files = [ + {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, + {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, +] + +[[package]] +name = "nltk" +version = "3.9.1" +requires_python = ">=3.8" +summary = "Natural Language Toolkit" +groups = ["default"] +dependencies = [ + "click", + "joblib", + "regex>=2021.8.3", + "tqdm", +] +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[[package]] +name = "numpy" +version = "1.26.4" +requires_python = ">=3.9" +summary = "Fundamental package for array computing in Python" +groups = ["default"] +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "openai" +version = "1.54.5" +requires_python = ">=3.8" +summary = "The official Python library for the openai API" +groups = ["default"] +dependencies = [ + "anyio<5,>=3.5.0", + "cached-property; python_version < \"3.8\"", + "distro<2,>=1.7.0", + "httpx<1,>=0.23.0", + "jiter<1,>=0.4.0", + "pydantic<3,>=1.9.0", + "sniffio", + "tqdm>4", + "typing-extensions<5,>=4.11", +] +files = [ + {file = "openai-1.54.5-py3-none-any.whl", hash = "sha256:f55a4450f38501814b53e76311ed7845a6f7f35bab46d0fb2a3728035d7a72d8"}, + {file = "openai-1.54.5.tar.gz", hash = "sha256:2aab4f9755a3e1e04d8a45ac1f4ce7b6948bab76646020c6386256d7e5cbb7e0"}, +] + +[[package]] +name = "orjson" +version = "3.10.11" +requires_python = ">=3.8" +summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +groups = ["default"] +files = [ + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, +] + +[[package]] +name = "packaging" +version = "24.2" +requires_python = ">=3.8" +summary = "Core utilities for Python packages" +groups = ["default", "dev"] +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] + +[[package]] +name = "pandas" +version = "2.2.3" +requires_python = ">=3.9" +summary = "Powerful data structures for data analysis, time series, and statistics" +groups = ["default"] +dependencies = [ + "numpy>=1.22.4; python_version < \"3.11\"", + "numpy>=1.23.2; python_version == \"3.11\"", + "numpy>=1.26.0; python_version >= \"3.12\"", + "python-dateutil>=2.8.2", + "pytz>=2020.1", + "tzdata>=2022.7", +] +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"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, + {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, + {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, +] + +[[package]] +name = "pillow" +version = "11.0.0" +requires_python = ">=3.9" +summary = "Python Imaging Library (Fork)" +groups = ["default"] +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"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, + {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, + {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, + {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, + {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +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"}, +] + +[[package]] +name = "portalocker" +version = "2.10.1" +requires_python = ">=3.8" +summary = "Wraps the portalocker recipe for easy usage" +groups = ["default"] +dependencies = [ + "pywin32>=226; platform_system == \"Windows\"", +] +files = [ + {file = "portalocker-2.10.1-py3-none-any.whl", hash = "sha256:53a5984ebc86a025552264b459b46a2086e269b21823cb572f8f28ee759e45bf"}, + {file = "portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f"}, +] + +[[package]] +name = "propcache" +version = "0.2.0" +requires_python = ">=3.8" +summary = "Accelerated property cache" +groups = ["default"] +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + +[[package]] +name = "protobuf" +version = "5.28.3" +requires_python = ">=3.8" +summary = "" +groups = ["default"] +files = [ + {file = "protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24"}, + {file = "protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868"}, + {file = "protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687"}, + {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584"}, + {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135"}, + {file = "protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"}, + {file = "protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b"}, +] + +[[package]] +name = "py-partiql-parser" +version = "0.5.6" +summary = "Pure Python PartiQL Parser" +groups = ["dev"] +files = [ + {file = "py_partiql_parser-0.5.6-py2.py3-none-any.whl", hash = "sha256:622d7b0444becd08c1f4e9e73b31690f4b1c309ab6e5ed45bf607fe71319309f"}, + {file = "py_partiql_parser-0.5.6.tar.gz", hash = "sha256:6339f6bf85573a35686529fc3f491302e71dd091711dfe8df3be89a93767f97b"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +requires_python = ">=3.8" +summary = "C parser in Python" +groups = ["dev"] +marker = "platform_python_implementation != \"PyPy\"" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.8.2" +requires_python = ">=3.8" +summary = "Data validation using Python type hints" +groups = ["default"] +dependencies = [ + "annotated-types>=0.4.0", + "pydantic-core==2.20.1", + "typing-extensions>=4.12.2; python_version >= \"3.13\"", + "typing-extensions>=4.6.1; python_version < \"3.13\"", +] +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +requires_python = ">=3.8" +summary = "Core functionality for Pydantic validation and serialization" +groups = ["default"] +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[[package]] +name = "pydantic-settings" +version = "2.3.4" +requires_python = ">=3.8" +summary = "Settings management using Pydantic" +groups = ["default"] +dependencies = [ + "pydantic>=2.7.0", + "python-dotenv>=0.21.0", +] +files = [ + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +requires_python = ">=3.8" +summary = "Pygments is a syntax highlighting package written in Python." +groups = ["default"] +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[[package]] +name = "pypdf" +version = "4.3.1" +requires_python = ">=3.6" +summary = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +groups = ["default"] +dependencies = [ + "dataclasses; python_version < \"3.7\"", + "typing-extensions>=4.0; python_version < \"3.11\"", +] +files = [ + {file = "pypdf-4.3.1-py3-none-any.whl", hash = "sha256:64b31da97eda0771ef22edb1bfecd5deee4b72c3d1736b7df2689805076d6418"}, + {file = "pypdf-4.3.1.tar.gz", hash = "sha256:b2f37fe9a3030aa97ca86067a56ba3f9d3565f9a791b305c7355d8392c30d91b"}, +] + +[[package]] +name = "pytest" +version = "8.3.3" +requires_python = ">=3.8" +summary = "pytest: simple powerful testing with Python" +groups = ["dev"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2,>=1.5", + "tomli>=1; python_version < \"3.11\"", +] +files = [ + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Extensions to the standard Python datetime module" +groups = ["default", "dev"] +dependencies = [ + "six>=1.5", +] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +requires_python = ">=3.8" +summary = "Read key-value pairs from a .env file and set them as environment variables" +groups = ["default"] +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"}, +] + +[[package]] +name = "python-multipart" +version = "0.0.17" +requires_python = ">=3.8" +summary = "A streaming multipart parser for Python" +groups = ["default"] +files = [ + {file = "python_multipart-0.0.17-py3-none-any.whl", hash = "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d"}, + {file = "python_multipart-0.0.17.tar.gz", hash = "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538"}, +] + +[[package]] +name = "pytz" +version = "2024.2" +summary = "World timezone definitions, modern and historical" +groups = ["default"] +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + +[[package]] +name = "pywin32" +version = "308" +summary = "Python for Window Extensions" +groups = ["default"] +marker = "platform_system == \"Windows\"" +files = [ + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +requires_python = ">=3.8" +summary = "YAML parser and emitter for Python" +groups = ["default", "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"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "qdrant-client" +version = "1.12.1" +requires_python = ">=3.8" +summary = "Client library for the Qdrant vector search engine" +groups = ["default"] +dependencies = [ + "grpcio-tools>=1.41.0", + "grpcio>=1.41.0", + "httpx[http2]>=0.20.0", + "numpy<1.21; python_version < \"3.8\"", + "numpy>=1.21; python_version >= \"3.8\" and python_version < \"3.12\"", + "numpy>=1.26; python_version >= \"3.12\"", + "portalocker<3.0.0,>=2.7.0", + "pydantic>=1.10.8", + "urllib3<3,>=1.26.14", +] +files = [ + {file = "qdrant_client-1.12.1-py3-none-any.whl", hash = "sha256:b2d17ce18e9e767471368380dd3bbc4a0e3a0e2061fedc9af3542084b48451e0"}, + {file = "qdrant_client-1.12.1.tar.gz", hash = "sha256:35e8e646f75b7b883b3d2d0ee4c69c5301000bba41c82aa546e985db0f1aeb72"}, +] + +[[package]] +name = "regex" +version = "2024.11.6" +requires_python = ">=3.8" +summary = "Alternative regular expression module, to replace re." +groups = ["default"] +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +requires_python = ">=3.8" +summary = "Python HTTP for Humans." +groups = ["default", "dev"] +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", +] +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[[package]] +name = "responses" +version = "0.25.3" +requires_python = ">=3.8" +summary = "A utility library for mocking out the `requests` Python library." +groups = ["dev"] +dependencies = [ + "pyyaml", + "requests<3.0,>=2.30.0", + "urllib3<3.0,>=1.25.10", +] +files = [ + {file = "responses-0.25.3-py3-none-any.whl", hash = "sha256:521efcbc82081ab8daa588e08f7e8a64ce79b91c39f6e62199b19159bea7dbcb"}, + {file = "responses-0.25.3.tar.gz", hash = "sha256:617b9247abd9ae28313d57a75880422d55ec63c29d33d629697590a034358dba"}, +] + +[[package]] +name = "rich" +version = "13.9.4" +requires_python = ">=3.8.0" +summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +groups = ["default"] +dependencies = [ + "markdown-it-py>=2.2.0", + "pygments<3.0.0,>=2.13.0", + "typing-extensions<5.0,>=4.0.0; python_version < \"3.11\"", +] +files = [ + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, +] + +[[package]] +name = "s3transfer" +version = "0.10.3" +requires_python = ">=3.8" +summary = "An Amazon S3 Transfer Manager" +groups = ["default", "dev"] +dependencies = [ + "botocore<2.0a.0,>=1.33.2", +] +files = [ + {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, + {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, +] + +[[package]] +name = "setuptools" +version = "75.5.0" +requires_python = ">=3.9" +summary = "Easily download, build, install, upgrade, and uninstall Python packages" +groups = ["default"] +files = [ + {file = "setuptools-75.5.0-py3-none-any.whl", hash = "sha256:87cb777c3b96d638ca02031192d40390e0ad97737e27b6b4fa831bea86f2f829"}, + {file = "setuptools-75.5.0.tar.gz", hash = "sha256:5c4ccb41111392671f02bb5f8436dfc5a9a7185e80500531b133f5775c4163ef"}, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +requires_python = ">=3.7" +summary = "Tool to Detect Surrounding Shell" +groups = ["default"] +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "six" +version = "1.16.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" +groups = ["default", "dev"] +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" +groups = ["default"] +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "soupsieve" +version = "2.6" +requires_python = ">=3.8" +summary = "A modern CSS selector implementation for Beautiful Soup." +groups = ["default"] +files = [ + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.36" +requires_python = ">=3.7" +summary = "Database Abstraction Library" +groups = ["default"] +dependencies = [ + "greenlet!=0.4.17; (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\") and python_version < \"3.13\"", + "importlib-metadata; python_version < \"3.8\"", + "typing-extensions>=4.6.0", +] +files = [ + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5"}, + {file = "SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e"}, + {file = "sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.36" +extras = ["asyncio"] +requires_python = ">=3.7" +summary = "Database Abstraction Library" +groups = ["default"] +dependencies = [ + "SQLAlchemy==2.0.36", + "greenlet!=0.4.17", +] +files = [ + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5"}, + {file = "SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e"}, + {file = "sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5"}, +] + +[[package]] +name = "starlette" +version = "0.37.2" +requires_python = ">=3.8" +summary = "The little ASGI library that shines." +groups = ["default"] +dependencies = [ + "anyio<5,>=3.4.0", + "typing-extensions>=3.10.0; python_version < \"3.10\"", +] +files = [ + {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, + {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, +] + +[[package]] +name = "striprtf" +version = "0.0.26" +summary = "A simple library to convert rtf to text" +groups = ["default"] +files = [ + {file = "striprtf-0.0.26-py3-none-any.whl", hash = "sha256:8c8f9d32083cdc2e8bfb149455aa1cc5a4e0a035893bedc75db8b73becb3a1bb"}, + {file = "striprtf-0.0.26.tar.gz", hash = "sha256:fdb2bba7ac440072d1c41eab50d8d74ae88f60a8b6575c6e2c7805dc462093aa"}, +] + +[[package]] +name = "tenacity" +version = "8.5.0" +requires_python = ">=3.8" +summary = "Retry code until it succeeds" +groups = ["default"] +files = [ + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, +] + +[[package]] +name = "tiktoken" +version = "0.8.0" +requires_python = ">=3.9" +summary = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +groups = ["default"] +dependencies = [ + "regex>=2022.1.18", + "requests>=2.26.0", +] +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"}, + {file = "tiktoken-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e13f37bc4ef2d012731e93e0fef21dc3b7aea5bb9009618de9a4026844e560"}, + {file = "tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f13d13c981511331eac0d01a59b5df7c0d4060a8be1e378672822213da51e0a2"}, + {file = "tiktoken-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6b2ddbc79a22621ce8b1166afa9f9a888a664a579350dc7c09346a3b5de837d9"}, + {file = "tiktoken-0.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d8c2d0e5ba6453a290b86cd65fc51fedf247e1ba170191715b049dac1f628005"}, + {file = "tiktoken-0.8.0.tar.gz", hash = "sha256:9ccbb2740f24542534369c5635cfd9b2b3c2490754a78ac8831d99f89f94eeb2"}, +] + +[[package]] +name = "tokenizers" +version = "0.20.3" +requires_python = ">=3.7" +summary = "" +groups = ["default"] +dependencies = [ + "huggingface-hub<1.0,>=0.16.4", +] +files = [ + {file = "tokenizers-0.20.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:31ccab28dbb1a9fe539787210b0026e22debeab1662970f61c2d921f7557f7e4"}, + {file = "tokenizers-0.20.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6361191f762bda98c773da418cf511cbaa0cb8d0a1196f16f8c0119bde68ff8"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f128d5da1202b78fa0a10d8d938610472487da01b57098d48f7e944384362514"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79c4121a2e9433ad7ef0769b9ca1f7dd7fa4c0cd501763d0a030afcbc6384481"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7850fde24197fe5cd6556e2fdba53a6d3bae67c531ea33a3d7c420b90904141"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b357970c095dc134978a68c67d845a1e3803ab7c4fbb39195bde914e7e13cf8b"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a333d878c4970b72d6c07848b90c05f6b045cf9273fc2bc04a27211721ad6118"}, + {file = "tokenizers-0.20.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd9fee817f655a8f50049f685e224828abfadd436b8ff67979fc1d054b435f1"}, + {file = "tokenizers-0.20.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e7816808b402129393a435ea2a509679b41246175d6e5e9f25b8692bfaa272b"}, + {file = "tokenizers-0.20.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba96367db9d8a730d3a1d5996b4b7babb846c3994b8ef14008cd8660f55db59d"}, + {file = "tokenizers-0.20.3-cp310-none-win32.whl", hash = "sha256:ee31ba9d7df6a98619426283e80c6359f167e2e9882d9ce1b0254937dbd32f3f"}, + {file = "tokenizers-0.20.3-cp310-none-win_amd64.whl", hash = "sha256:a845c08fdad554fe0871d1255df85772f91236e5fd6b9287ef8b64f5807dbd0c"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e919f2e3e68bb51dc31de4fcbbeff3bdf9c1cad489044c75e2b982a91059bd3c"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b8e9608f2773996cc272156e305bd79066163a66b0390fe21750aff62df1ac07"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39270a7050deaf50f7caff4c532c01b3c48f6608d42b3eacdebdc6795478c8df"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e005466632b1c5d2d2120f6de8aa768cc9d36cd1ab7d51d0c27a114c91a1e6ee"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a07962340b36189b6c8feda552ea1bfeee6cf067ff922a1d7760662c2ee229e5"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:55046ad3dd5f2b3c67501fcc8c9cbe3e901d8355f08a3b745e9b57894855f85b"}, + {file = "tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:efcf0eb939988b627558aaf2b9dc3e56d759cad2e0cfa04fcab378e4b48fc4fd"}, + {file = "tokenizers-0.20.3.tar.gz", hash = "sha256:2278b34c5d0dd78e087e1ca7f9b1dcbf129d80211afa645f214bd6e051037539"}, +] + +[[package]] +name = "tomli" +version = "2.1.0" +requires_python = ">=3.8" +summary = "A lil' TOML parser" +groups = ["dev"] +marker = "python_version < \"3.11\"" +files = [ + {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, + {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, +] + +[[package]] +name = "tqdm" +version = "4.67.0" +requires_python = ">=3.7" +summary = "Fast, Extensible Progress Meter" +groups = ["default"] +dependencies = [ + "colorama; platform_system == \"Windows\"", +] +files = [ + {file = "tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be"}, + {file = "tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a"}, +] + +[[package]] +name = "typer" +version = "0.13.1" +requires_python = ">=3.7" +summary = "Typer, build great CLIs. Easy to code. Based on Python type hints." +groups = ["default"] +dependencies = [ + "click>=8.0.0", + "rich>=10.11.0", + "shellingham>=1.3.0", + "typing-extensions>=3.7.4.3", +] +files = [ + {file = "typer-0.13.1-py3-none-any.whl", hash = "sha256:5b59580fd925e89463a29d363e0a43245ec02765bde9fb77d39e5d0f29dd7157"}, + {file = "typer-0.13.1.tar.gz", hash = "sha256:9d444cb96cc268ce6f8b94e13b4335084cef4c079998a9f4851a90229a3bd25c"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +groups = ["default"] +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"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +summary = "Runtime inspection utilities for typing module." +groups = ["default"] +dependencies = [ + "mypy-extensions>=0.3.0", + "typing-extensions>=3.7.4", + "typing>=3.7.4; python_version < \"3.5\"", +] +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +requires_python = ">=2" +summary = "Provider of IANA time zone data" +groups = ["default"] +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "ujson" +version = "5.10.0" +requires_python = ">=3.8" +summary = "Ultra fast JSON encoder and decoder for Python" +groups = ["default"] +files = [ + {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, + {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51"}, + {file = "ujson-5.10.0-cp310-cp310-win32.whl", hash = "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518"}, + {file = "ujson-5.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b"}, + {file = "ujson-5.10.0.tar.gz", hash = "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1"}, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +requires_python = ">=3.8" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default", "dev"] +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[[package]] +name = "uvicorn" +version = "0.32.0" +requires_python = ">=3.8" +summary = "The lightning-fast ASGI server." +groups = ["default"] +dependencies = [ + "click>=7.0", + "h11>=0.8", + "typing-extensions>=4.0; python_version < \"3.11\"", +] +files = [ + {file = "uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82"}, + {file = "uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e"}, +] + +[[package]] +name = "uvicorn" +version = "0.32.0" +extras = ["standard"] +requires_python = ">=3.8" +summary = "The lightning-fast ASGI server." +groups = ["default"] +dependencies = [ + "colorama>=0.4; sys_platform == \"win32\"", + "httptools>=0.5.0", + "python-dotenv>=0.13", + "pyyaml>=5.1", + "uvicorn==0.32.0", + "uvloop!=0.15.0,!=0.15.1,>=0.14.0; (sys_platform != \"cygwin\" and sys_platform != \"win32\") and platform_python_implementation != \"PyPy\"", + "watchfiles>=0.13", + "websockets>=10.4", +] +files = [ + {file = "uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82"}, + {file = "uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e"}, +] + +[[package]] +name = "uvloop" +version = "0.21.0" +requires_python = ">=3.8.0" +summary = "Fast implementation of asyncio event loop on top of libuv" +groups = ["default"] +marker = "(sys_platform != \"cygwin\" and sys_platform != \"win32\") 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"}, + {file = "uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26"}, + {file = "uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb"}, + {file = "uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f"}, + {file = "uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c"}, + {file = "uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3"}, +] + +[[package]] +name = "watchfiles" +version = "0.24.0" +requires_python = ">=3.8" +summary = "Simple, modern and high performance file watching and code reload in python." +groups = ["default"] +dependencies = [ + "anyio>=3.0.0", +] +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"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e"}, + {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c"}, + {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188"}, + {file = "watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735"}, + {file = "watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a"}, + {file = "watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1"}, +] + +[[package]] +name = "websockets" +version = "14.1" +requires_python = ">=3.9" +summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +groups = ["default"] +files = [ + {file = "websockets-14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29"}, + {file = "websockets-14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179"}, + {file = "websockets-14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250"}, + {file = "websockets-14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0"}, + {file = "websockets-14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0"}, + {file = "websockets-14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199"}, + {file = "websockets-14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58"}, + {file = "websockets-14.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078"}, + {file = "websockets-14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434"}, + {file = "websockets-14.1-cp310-cp310-win32.whl", hash = "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10"}, + {file = "websockets-14.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e"}, + {file = "websockets-14.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8"}, + {file = "websockets-14.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e"}, + {file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098"}, + {file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb"}, + {file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7"}, + {file = "websockets-14.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d"}, + {file = "websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e"}, + {file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"}, +] + +[[package]] +name = "werkzeug" +version = "3.1.3" +requires_python = ">=3.9" +summary = "The comprehensive WSGI web application library." +groups = ["dev"] +dependencies = [ + "MarkupSafe>=2.1.1", +] +files = [ + {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, + {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, +] + +[[package]] +name = "wrapt" +version = "1.16.0" +requires_python = ">=3.6" +summary = "Module for decorators, wrappers and monkey patching." +groups = ["default"] +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "xmltodict" +version = "0.14.2" +requires_python = ">=3.6" +summary = "Makes working with XML feel like you are working with JSON" +groups = ["dev"] +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] + +[[package]] +name = "yarl" +version = "1.17.2" +requires_python = ">=3.9" +summary = "Yet another URL library" +groups = ["default"] +dependencies = [ + "idna>=2.0", + "multidict>=4.0", + "propcache>=0.2.0", +] +files = [ + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"}, + {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"}, + {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"}, + {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"}, + {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"}, +] diff --git a/llm-service/pyproject.toml b/llm-service/pyproject.toml index 2c70d6c..b6c2e69 100644 --- a/llm-service/pyproject.toml +++ b/llm-service/pyproject.toml @@ -2,3 +2,21 @@ addopts = [ "--import-mode=importlib", ] + +[tool.pdm] +distribution = false + +[project] +name = "llm-service" +version = "0.1.0" +description = "Default template for PDM package" +authors = [ + {name = "Conrado Silva Miranda", email = "csilvamiranda@cloudera.com"}, +] +dependencies = ["llama-index-core==0.10.68", "llama-index-readers-file==0.1.33", "fastapi==0.111.0", "pydantic==2.8.2", "pydantic-settings==2.3.4", "boto3==1.34.26", "llama-index-embeddings-bedrock==0.2.1", "llama-index-llms-bedrock==0.1.13", "llama-index-llms-openai==0.1.31", "llama-index-llms-mistralai==0.1.20", "llama-index-embeddings-openai==0.1.11", "llama-index-vector-stores-qdrant==0.2.17"] +requires-python = "==3.10.*" +readme = "README.md" +license = {text = "APACHE"} + +[dependency-groups] +dev = ["moto[s3]>=5.0.21", "pytest>=8.3.3"] diff --git a/local-dev.sh b/local-dev.sh index b689402..a3cca71 100755 --- a/local-dev.sh +++ b/local-dev.sh @@ -65,10 +65,11 @@ docker run --name qdrant_dev --rm -d -p 6333:6333 -p 6334:6334 -v $(pwd)/databas cd llm-service python3.10 -m venv venv source venv/bin/activate -python -m pip install -r app/requirements.txt -python -m pytest -sxvvra +python -m pip install pdm +pdm install +pdm run pytest -sxvvra -fastapi dev & +pdm run fastapi dev & # start up the jarva cd ../backend diff --git a/scripts/refresh_project.sh b/scripts/refresh_project.sh index 1966b83..0ff8a26 100644 --- a/scripts/refresh_project.sh +++ b/scripts/refresh_project.sh @@ -46,7 +46,8 @@ cd ui/express npm install cd ../../llm-service -pip install -r app/requirements.txt +pip install pdm +pdm install -v cd .. mkdir -p artifacts diff --git a/scripts/release_version.txt b/scripts/release_version.txt index bf197f0..986fcc2 100644 --- a/scripts/release_version.txt +++ b/scripts/release_version.txt @@ -1 +1 @@ -export RELEASE_TAG=1.1.0 +export RELEASE_TAG=1.2.0 diff --git a/scripts/startup_app.sh b/scripts/startup_app.sh index eef266c..f919650 100755 --- a/scripts/startup_app.sh +++ b/scripts/startup_app.sh @@ -61,7 +61,7 @@ qdrant/qdrant & # start Python backend cd llm-service -fastapi run --host 127.0.0.1 --port 8081 & +pdm run fastapi run --host 127.0.0.1 --port 8081 & # start up the jarva cd .. diff --git a/ui/src/api/ampUpdateApi.ts b/ui/src/api/ampUpdateApi.ts index 1f099ce..9a2d9e0 100644 --- a/ui/src/api/ampUpdateApi.ts +++ b/ui/src/api/ampUpdateApi.ts @@ -55,7 +55,7 @@ export const useGetAmpUpdateStatus = () => { }; const getAmpUpdateStatus = async (): Promise => { - return getRequest(`${llmServicePath}/index/amp-update`); + return getRequest(`${llmServicePath}/amp-update`); }; export enum JobStatus { @@ -83,7 +83,7 @@ export const useGetAmpUpdateJobStatus = (enabled: boolean) => { }; const getAmpUpdateJobStatus = async (): Promise => { - return getRequestJobStatus(`${llmServicePath}/index/amp-update/job-status`); + return getRequestJobStatus(`${llmServicePath}/amp-update/job-status`); }; const getRequestJobStatus = async (url: string): Promise => { @@ -112,5 +112,5 @@ export const useUpdateAmpMutation = ({ }; const updateAmpMutation = async (): Promise => { - return await postRequest(`${llmServicePath}/index/amp-update`, {}); + return await postRequest(`${llmServicePath}/amp-update`, {}); }; diff --git a/ui/src/api/chatApi.ts b/ui/src/api/chatApi.ts index 0195644..80c5f16 100644 --- a/ui/src/api/chatApi.ts +++ b/ui/src/api/chatApi.ts @@ -67,6 +67,7 @@ export interface RagMessageV2 { export interface QueryConfiguration { top_k: number; model_name: string; + exclude_knowledge_base: boolean; } export interface ChatMutationRequest { @@ -124,7 +125,7 @@ export const chatHistoryQuery = async ( request: ChatHistoryRequestType, ): Promise => { return await getRequest( - `${llmServicePath}/index/sessions/${request.session_id}/chat-history`, + `${llmServicePath}/sessions/${request.session_id}/chat-history`, ); }; @@ -185,5 +186,8 @@ export const useChatMutation = ({ const chatMutation = async ( request: ChatMutationRequest, ): Promise => { - return await postRequest(`${llmServicePath}/index/chat`, request); + return await postRequest( + `${llmServicePath}/sessions/${request.session_id}/chat`, + request, + ); }; diff --git a/ui/src/api/modelsApi.ts b/ui/src/api/modelsApi.ts index ad362c3..94b9aab 100644 --- a/ui/src/api/modelsApi.ts +++ b/ui/src/api/modelsApi.ts @@ -70,7 +70,7 @@ export const getLlmModelsQueryOptions = queryOptions({ }); const getLlmModels = async (): Promise => { - return await getRequest(`${llmServicePath}/index/models/llm`); + return await getRequest(`${llmServicePath}/models/llm`); }; export const useGetEmbeddingModels = () => { @@ -83,7 +83,7 @@ export const useGetEmbeddingModels = () => { }; const getEmbeddingModels = async (): Promise => { - return await getRequest(`${llmServicePath}/index/models/embeddings`); + return await getRequest(`${llmServicePath}/models/embeddings`); }; type ModelSource = "CAII" | "Bedrock"; @@ -96,7 +96,7 @@ export const getModelSourceQueryOptions = queryOptions({ }); const getModelSource = async (): Promise => { - return await getRequest(`${llmServicePath}/index/models/model_source`); + return await getRequest(`${llmServicePath}/models/model_source`); }; export const useTestLlmModel = ({ @@ -112,16 +112,16 @@ export const useTestLlmModel = ({ }; const testLlmModel = async (model_id: string): Promise => { - return await fetch( - `${llmServicePath}/index/models/llm/${model_id}/test`, - ).then(async (res) => { - if (!res.ok) { - const detail = (await res.json()) as CustomError; - throw new ApiError(detail.message ?? detail.detail, res.status); - } + return await fetch(`${llmServicePath}/models/llm/${model_id}/test`).then( + async (res) => { + if (!res.ok) { + const detail = (await res.json()) as CustomError; + throw new ApiError(detail.message ?? detail.detail, res.status); + } - return (await res.json()) as Promise; - }); + return (await res.json()) as Promise; + }, + ); }; export const useTestEmbeddingModel = ({ @@ -138,7 +138,7 @@ export const useTestEmbeddingModel = ({ const testEmbeddingModel = async (model_id: string): Promise => { return await fetch( - `${llmServicePath}/index/models/embedding/${model_id}/test`, + `${llmServicePath}/models/embedding/${model_id}/test`, ).then(async (res) => { if (!res.ok) { const detail = (await res.json()) as CustomError; diff --git a/ui/src/api/ragQueryApi.ts b/ui/src/api/ragQueryApi.ts index da13e8f..ed7c9ca 100644 --- a/ui/src/api/ragQueryApi.ts +++ b/ui/src/api/ragQueryApi.ts @@ -54,7 +54,7 @@ export interface RagMessage { export interface SuggestQuestionsRequest { data_source_id: string; configuration: QueryConfiguration; - chat_history: RagMessage[]; + session_id: string; } export interface SuggestQuestionsResponse { @@ -78,7 +78,9 @@ export const useSuggestQuestions = (request: SuggestQuestionsRequest) => { // eslint-disable-next-line @tanstack/query/exhaustive-deps queryKey: suggestedQuestionKey(request.data_source_id), queryFn: () => suggestQuestionsQuery(request), - enabled: !!request.data_source_id, + enabled: + Boolean(request.data_source_id) && + Boolean(request.configuration.model_name), gcTime: 0, }); }; @@ -87,7 +89,7 @@ const suggestQuestionsQuery = async ( request: SuggestQuestionsRequest, ): Promise => { return await postRequest( - `${llmServicePath}/index/suggest-questions`, + `${llmServicePath}/sessions/${request.session_id}/suggest-questions`, request, ); }; @@ -110,6 +112,6 @@ const getChunkContents = async ( request: ChunkContentsRequest, ): Promise => { return getRequest( - `${llmServicePath}/index/data_sources/${request.data_source_id}/chunks/${request.chunk_id}`, + `${llmServicePath}/data_sources/${request.data_source_id}/chunks/${request.chunk_id}`, ); }; diff --git a/ui/src/api/sessionApi.ts b/ui/src/api/sessionApi.ts index d84a9c3..91a1a08 100644 --- a/ui/src/api/sessionApi.ts +++ b/ui/src/api/sessionApi.ts @@ -125,5 +125,5 @@ export const useDeleteChatHistoryMutation = ({ export const deleteChatHistoryMutation = async ( sessionId: string, ): Promise => { - await deleteRequest(`${llmServicePath}/index/${paths.sessions}/${sessionId}`); + await deleteRequest(`${llmServicePath}/${paths.sessions}/${sessionId}`); }; diff --git a/ui/src/api/summaryApi.ts b/ui/src/api/summaryApi.ts index c52b198..e4746f3 100644 --- a/ui/src/api/summaryApi.ts +++ b/ui/src/api/summaryApi.ts @@ -66,7 +66,7 @@ const getDocumentSummary = async ( doc_id: DocumentSummaryRequest["doc_id"], ): Promise => { return getRequest( - `${llmServicePath}/index/data_sources/${data_source_id}/documents/${doc_id}/summary`, + `${llmServicePath}/data_sources/${data_source_id}/documents/${doc_id}/summary`, ); }; @@ -82,7 +82,5 @@ export const useGetDataSourceSummary = (request: DataSourceSummaryRequest) => { const getDataSourceSummary = async ( data_source_id: DataSourceSummaryRequest["data_source_id"], ): Promise => { - return getRequest( - `${llmServicePath}/index/data_sources/${data_source_id}/summary`, - ); + return getRequest(`${llmServicePath}/data_sources/${data_source_id}/summary`); }; diff --git a/ui/src/components/AmpUpdate/JobStatusTracker.test.tsx b/ui/src/components/AmpUpdate/JobStatusTracker.test.tsx index 672fd0d..b77cc3f 100644 --- a/ui/src/components/AmpUpdate/JobStatusTracker.test.tsx +++ b/ui/src/components/AmpUpdate/JobStatusTracker.test.tsx @@ -53,12 +53,12 @@ describe("JobStatusTracker", () => { it("displays Starting status correctly", () => { render(); - expect(screen.getByText("Starting")).toBeTruthy(); + expect(screen.getByText("Update Starting")).toBeTruthy(); }); it("displays Running status correctly", () => { render(); - expect(screen.getByText("Running")).toBeTruthy(); + expect(screen.getByText("Update Running")).toBeTruthy(); }); it("displays Stopping status correctly", () => { diff --git a/ui/src/components/AmpUpdate/JobStatusTracker.tsx b/ui/src/components/AmpUpdate/JobStatusTracker.tsx index 10d8e30..20df3f8 100644 --- a/ui/src/components/AmpUpdate/JobStatusTracker.tsx +++ b/ui/src/components/AmpUpdate/JobStatusTracker.tsx @@ -49,8 +49,8 @@ import { const jobStatusDisplayValue = (jobStatus?: JobStatus): string => { const statusMap: Record = { [JobStatus.SCHEDULING]: "Scheduling", - [JobStatus.STARTING]: "Starting", - [JobStatus.RUNNING]: "Running", + [JobStatus.STARTING]: "Update Starting", + [JobStatus.RUNNING]: "Update Running", [JobStatus.STOPPING]: "Stopping", [JobStatus.STOPPED]: "Stopped", [JobStatus.UNKNOWN]: "Unknown", @@ -115,7 +115,7 @@ const JobStatusTracker = ({ jobStatus }: { jobStatus?: JobStatus }) => { strokeWidth={10} format={() => ( - + {jobStatusDisplayValue(jobStatus)} diff --git a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatBodyController.test.tsx b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatBodyController.test.tsx index 0b81b04..b8b743f 100644 --- a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatBodyController.test.tsx +++ b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatBodyController.test.tsx @@ -96,7 +96,11 @@ describe("ChatBodyController", () => { chatHistory: [], dataSourceId: undefined, dataSourcesStatus: undefined, - queryConfiguration: { top_k: 5, model_name: "" }, + queryConfiguration: { + top_k: 5, + model_name: "", + exclude_knowledge_base: false, + }, setQueryConfiguration: () => null, setCurrentQuestion: () => null, dataSourceSize: null, diff --git a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatMessage.tsx b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatMessage.tsx index 18f6ec8..785efff 100644 --- a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatMessage.tsx +++ b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/ChatMessage.tsx @@ -81,7 +81,7 @@ const ChatMessage = ({ - + {data.rag_message.assistant} diff --git a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/UserQuestion.tsx b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/UserQuestion.tsx index 16102bf..bfa1ad1 100644 --- a/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/UserQuestion.tsx +++ b/ui/src/pages/RagChatTab/ChatOutput/ChatMessages/UserQuestion.tsx @@ -42,7 +42,9 @@ import Images from "src/components/images/Images.ts"; const UserQuestion = (props: { question: string }) => ( - {props.question} + + {props.question} + { } = useSuggestQuestions({ data_source_id: dataSourceId?.toString() ?? "", configuration: queryConfiguration, - chat_history: [], + session_id: sessionId ?? "", }); const { mutate: chatMutation, isPending: askRagIsPending } = useChatMutation({ diff --git a/ui/src/pages/RagChatTab/ChatOutput/Sources/SourceCard.tsx b/ui/src/pages/RagChatTab/ChatOutput/Sources/SourceCard.tsx index 037e5fc..621d9d5 100644 --- a/ui/src/pages/RagChatTab/ChatOutput/Sources/SourceCard.tsx +++ b/ui/src/pages/RagChatTab/ChatOutput/Sources/SourceCard.tsx @@ -44,6 +44,7 @@ import { SourceNode } from "src/api/chatApi.ts"; import { useGetDocumentSummary } from "src/api/summaryApi.ts"; import DocumentationIcon from "src/cuix/icons/DocumentationIcon"; import Icon from "@ant-design/icons"; +import { cdlGray600 } from "src/cuix/variables.ts"; export const SourceCard = ({ source }: { source: SourceNode }) => { const { dataSourceId } = useContext(RagChatContext); @@ -71,7 +72,14 @@ export const SourceCard = ({ source }: { source: SourceNode }) => { onOpenChange={handleGetChunkContents} content={ + {source.source_file_name} + + Score: {source.score} + + + } bordered={false} style={{ width: 600, height: 300, overflowY: "auto" }} > @@ -105,7 +113,9 @@ export const SourceCard = ({ source }: { source: SourceNode }) => { Extracted reference content - + {chunkContents.data} diff --git a/ui/src/pages/RagChatTab/FooterComponents/RagChatQueryInput.tsx b/ui/src/pages/RagChatTab/FooterComponents/RagChatQueryInput.tsx index 9e8cb92..d2e6cb1 100644 --- a/ui/src/pages/RagChatTab/FooterComponents/RagChatQueryInput.tsx +++ b/ui/src/pages/RagChatTab/FooterComponents/RagChatQueryInput.tsx @@ -36,31 +36,18 @@ * DATA. ******************************************************************************/ -import { Button, Flex, Input } from "antd"; +import { Button, Flex, Input, Switch, Tooltip } from "antd"; import SuggestedQuestionsFooter from "pages/RagChatTab/FooterComponents/SuggestedQuestionsFooter.tsx"; -import { SendOutlined } from "@ant-design/icons"; +import { DatabaseFilled, SendOutlined } from "@ant-design/icons"; import { useContext, useState } from "react"; import { RagChatContext } from "pages/RagChatTab/State/RagChatContext.tsx"; import messageQueue from "src/utils/messageQueue.ts"; -import { ChatMessageType, useChatMutation } from "src/api/chatApi.ts"; -import { RagMessage, useSuggestQuestions } from "src/api/ragQueryApi.ts"; +import { useChatMutation } from "src/api/chatApi.ts"; +import { useSuggestQuestions } from "src/api/ragQueryApi.ts"; import { useParams } from "@tanstack/react-router"; import { cdlBlue600 } from "src/cuix/variables.ts"; -const convertedChatHistory = (chatHistory: ChatMessageType[]): RagMessage[] => { - return chatHistory.flatMap((message) => { - return [ - { - role: "user", - content: message.rag_message.user, - }, - { - role: "assistant", - content: message.rag_message.assistant, - }, - ]; - }); -}; +import type { SwitchChangeEventHandler } from "antd/lib/switch"; const RagChatQueryInput = () => { const { @@ -70,6 +57,7 @@ const RagChatQueryInput = () => { chatHistory, dataSourceSize, dataSourcesStatus, + setQueryConfiguration, } = useContext(RagChatContext); const [userInput, setUserInput] = useState(""); @@ -82,7 +70,7 @@ const RagChatQueryInput = () => { } = useSuggestQuestions({ data_source_id: dataSourceId?.toString() ?? "", configuration: queryConfiguration, - chat_history: convertedChatHistory(chatHistory), + session_id: sessionId ?? "", }); const chatMutation = useChatMutation({ @@ -107,6 +95,13 @@ const RagChatQueryInput = () => { } }; + const handleExcludeKnowledgeBase: SwitchChangeEventHandler = (checked) => { + setQueryConfiguration((prev) => ({ + ...prev, + exclude_knowledge_base: !checked, + })); + }; + return (
@@ -134,6 +129,16 @@ const RagChatQueryInput = () => { handleChat(userInput); } }} + suffix={ + + } + value={!queryConfiguration.exclude_knowledge_base} + onChange={handleExcludeKnowledgeBase} + style={{ display: "none" }} // note: disabled for now, until UX is ready + /> + + } disabled={!dataSourceSize || chatMutation.isPending} />