From 1f7cfe9665b68bd9e40851d8a16cbca618d16040 Mon Sep 17 00:00:00 2001 From: Skylar Saveland Date: Sat, 23 Nov 2024 16:51:25 -0800 Subject: [PATCH] refactor(py): use ruff instead of black (#62) --- .devcontainer/devcontainer.json | 24 +- .github/workflows/ci-python.yml | 5 +- docker-compose.yaml | 1 + py/README.md | 2 +- py/genall.sh | 2 +- py/packages/corpora/admin.py | 3 + py/packages/corpora/auth.py | 2 +- py/packages/corpora/lib/dj/decorators.py | 1 + py/packages/corpora/lib/dj/test_decorators.py | 3 +- py/packages/corpora/lib/files.py | 4 +- py/packages/corpora/lib/test_files.py | 4 +- .../corpora/migrations/0002_initial.py | 9 +- py/packages/corpora/models.py | 69 ++- py/packages/corpora/router.py | 3 +- py/packages/corpora/routers/corpus.py | 28 +- py/packages/corpora/routers/corpustextfile.py | 13 +- py/packages/corpora/routers/plan.py | 9 +- py/packages/corpora/routers/split.py | 12 +- py/packages/corpora/routers/test_corpus.py | 21 +- .../corpora/routers/test_corpustextfile.py | 21 +- py/packages/corpora/routers/test_lib.py | 4 +- py/packages/corpora/routers/test_split.py | 15 +- py/packages/corpora/routers/workon.py | 8 +- py/packages/corpora/schema/chat.py | 3 +- py/packages/corpora/schema/core.py | 2 - py/packages/corpora/tasks/test_sync.py | 6 +- py/packages/corpora/test_models.py | 20 +- py/packages/corpora/test_models_corpus.py | 14 +- py/packages/corpora/views.py | 2 +- py/packages/corpora_ai/count_tokens.py | 4 +- py/packages/corpora_ai/llm_interface.py | 35 +- py/packages/corpora_ai/provider_loader.py | 5 +- py/packages/corpora_ai/split.py | 11 +- .../corpora_ai/test_provider_loader.py | 23 +- py/packages/corpora_ai_openai/llm_client.py | 15 +- .../corpora_ai_openai/test_llm_client.py | 24 +- .../corpora_cli/{__init__py => __init__.py} | 0 py/packages/corpora_cli/auth.py | 32 +- py/packages/corpora_cli/commands/corpus.py | 25 +- py/packages/corpora_cli/commands/file.py | 5 +- py/packages/corpora_cli/commands/plan.py | 86 +-- py/packages/corpora_cli/commands/split.py | 4 +- .../corpora_cli/commands/test_corpus.py | 16 +- py/packages/corpora_cli/commands/test_file.py | 5 +- .../corpora_cli/commands/test_split.py | 7 +- py/packages/corpora_cli/commands/workon.py | 40 +- py/packages/corpora_cli/config.py | 24 +- py/packages/corpora_cli/constants.py | 4 +- py/packages/corpora_cli/context.py | 6 +- py/packages/corpora_cli/main.py | 16 +- py/packages/corpora_cli/test_auth.py | 12 +- py/packages/corpora_cli/test_config.py | 24 +- py/packages/corpora_cli/test_main.py | 17 +- py/packages/corpora_cli/utils/__init__.py | 0 py/packages/corpora_cli/utils/collectors.py | 20 +- py/packages/corpora_cli/utils/git.py | 13 +- .../corpora_cli/utils/test_collectors.py | 31 +- py/packages/corpora_client/api/__init__.py | 1 + py/packages/corpora_client/api/corpus_api.py | 581 +++++++++++------- py/packages/corpora_client/api/file_api.py | 240 +++++--- py/packages/corpora_client/api/plan_api.py | 82 ++- py/packages/corpora_client/api/split_api.py | 228 ++++--- py/packages/corpora_client/api/workon_api.py | 82 ++- py/packages/corpora_client/api_client.py | 254 ++++---- py/packages/corpora_client/api_response.py | 5 +- py/packages/corpora_client/configuration.py | 117 ++-- py/packages/corpora_client/exceptions.py | 30 +- .../models/corpus_chat_schema.py | 55 +- .../models/corpus_file_chat_schema.py | 58 +- .../models/corpus_response_schema.py | 36 +- .../corpora_client/models/corpus_schema.py | 17 +- .../models/corpus_update_files_schema.py | 16 +- .../models/file_response_schema.py | 40 +- .../corpora_client/models/file_schema.py | 22 +- .../corpora_client/models/issue_schema.py | 15 +- .../corpora_client/models/message_schema.py | 15 +- .../models/split_response_schema.py | 24 +- .../models/split_vector_search_schema.py | 22 +- py/packages/corpora_client/rest.py | 71 ++- py/packages/corpora_client/setup.py | 2 +- .../corpora_client/test/test_corpus_api.py | 2 +- .../test/test_corpus_chat_schema.py | 10 +- .../test/test_corpus_file_chat_schema.py | 10 +- .../test/test_corpus_response_schema.py | 10 +- .../corpora_client/test/test_corpus_schema.py | 10 +- .../test/test_corpus_update_files_schema.py | 10 +- .../corpora_client/test/test_file_api.py | 2 +- .../test/test_file_response_schema.py | 10 +- .../corpora_client/test/test_file_schema.py | 10 +- .../corpora_client/test/test_issue_schema.py | 10 +- .../test/test_message_schema.py | 10 +- .../corpora_client/test/test_plan_api.py | 2 +- .../corpora_client/test/test_split_api.py | 2 +- .../test/test_split_response_schema.py | 10 +- .../test/test_split_vector_search_schema.py | 10 +- .../corpora_client/test/test_workon_api.py | 2 +- py/packages/corpora_pm/abstract.py | 33 +- py/packages/corpora_pm/providers/github/pm.py | 46 +- .../corpora_pm/providers/github/test_pm.py | 14 +- .../corpora_pm/providers/provider_loader.py | 7 +- py/packages/corpora_proj/__init__.py | 2 +- py/packages/corpora_proj/asgi.py | 3 +- py/packages/corpora_proj/celery_app.py | 2 +- py/packages/corpora_proj/manage.py | 2 +- py/packages/corpora_proj/settings.py | 7 +- py/packages/corpora_proj/urls.py | 11 +- py/packages/corpora_proj/wsgi.py | 3 +- py/pyproject.toml | 46 +- py/requirements-dev.txt | 2 +- rs/core/corpora_cli/src/commands/sync.rs | 49 +- rs/core/corpora_cli/src/context/config.rs | 4 +- rs/core/corpora_cli/src/context/mod.rs | 10 + 112 files changed, 1799 insertions(+), 1389 deletions(-) rename py/packages/corpora_cli/{__init__py => __init__.py} (100%) create mode 100644 py/packages/corpora_cli/utils/__init__.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5f249ec..2879c89 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,21 +6,13 @@ "customizations": { "vscode": { "settings": { - "python.formatting.provider": "black", - "python.formatting.formatOnSave": true, - "python.formatting.blackArgs": [ - "--line-length", - "88", - "--config", - "/workspace/py/pyproject.toml" - ], - // TODO: you have to uninstall autopep8 in devcontainer - // because of Microsoft defaults. - // ... if the editor is formatting wrongly - // then uninstall autopep8 extension. - // some day Microsoft will fix this? - "python.formatting.autopep8Path": "", - "editor.formatOnSave": true, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll": "always" + } + }, "python.linting.enabled": true, "python.pythonPath": "/usr/local/bin/python", "python.analysis.autoImportCompletions": true, @@ -29,7 +21,7 @@ "extensions": [ // py "ms-python.python", - "ms-python.black-formatter", + "charliermarsh.ruff", // github "GitHub.copilot", "GitHub.copilot-chat", diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index d684a4a..c67649c 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -46,8 +46,9 @@ jobs: python -m pip install --upgrade pip pip install -r py/requirements.txt - - name: Black - run: black --check py/ + - name: Ruff + working-directory: py/ + run: ruff check - name: Run tests with pytest env: diff --git a/docker-compose.yaml b/docker-compose.yaml index 83d3b33..46c305c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -77,6 +77,7 @@ services: CORPORA_CLIENT_ID: "${CORPORA_CLIENT_ID}" CORPORA_CLIENT_SECRET: "${CORPORA_CLIENT_SECRET}" GITHUB_TOKEN: "${GITHUB_TOKEN}" + # OPENAI_API_KEY: "${OPENAI_API_KEY}" command: sleep infinity working_dir: /workspace networks: diff --git a/py/README.md b/py/README.md index 1adb252..7e102c8 100644 --- a/py/README.md +++ b/py/README.md @@ -34,4 +34,4 @@ Each package serves a distinct purpose: ## Development Workflow - **API Development**: Add endpoints in `corpora`. Use `./genall.sh` to update `corpora_client` and `corpora_cli`. -- **Testing and Formatting**: Use `black` for code formatting and `pytest` for tests. +- **Testing and Formatting**: Use `ruff` for code formatting and `pytest` for tests. diff --git a/py/genall.sh b/py/genall.sh index 7856740..1936335 100755 --- a/py/genall.sh +++ b/py/genall.sh @@ -20,5 +20,5 @@ cp gen/corpora_client/setup.py packages/corpora_client/setup.py cp gen/corpora_client/requirements.txt packages/corpora_client/requirements.txt cp gen/corpora_client/test-requirements.txt packages/corpora_client/test-requirements.txt rm -rf gen/corpora_client -black . +ruff check --fix pytest diff --git a/py/packages/corpora/admin.py b/py/packages/corpora/admin.py index 0d93e98..6c48dcd 100644 --- a/py/packages/corpora/admin.py +++ b/py/packages/corpora/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from .models import Corpus, CorpusTextFile, Split @@ -8,9 +9,11 @@ class CorpusAdmin(admin.ModelAdmin): search_fields = ("name", "id", "url") ordering = ("-updated_at",) readonly_fields = ("id", "created_at", "updated_at") + autocomplete_fields = ("owner",) fieldsets = ( (None, {"fields": ("name", "id", "url")}), ("Timestamps", {"fields": ("created_at", "updated_at")}), + ("Owner", {"fields": ("owner",)}), ) diff --git a/py/packages/corpora/auth.py b/py/packages/corpora/auth.py index c690be8..3c8170a 100644 --- a/py/packages/corpora/auth.py +++ b/py/packages/corpora/auth.py @@ -1,7 +1,7 @@ from asgiref.sync import sync_to_async +from django.utils import timezone from ninja.security import HttpBearer from oauth2_provider.models import AccessToken -from django.utils import timezone class BearerAuth(HttpBearer): diff --git a/py/packages/corpora/lib/dj/decorators.py b/py/packages/corpora/lib/dj/decorators.py index 55f86ea..b93e7c2 100644 --- a/py/packages/corpora/lib/dj/decorators.py +++ b/py/packages/corpora/lib/dj/decorators.py @@ -1,4 +1,5 @@ from functools import wraps + from django.core.exceptions import ObjectDoesNotExist from django.http import Http404 diff --git a/py/packages/corpora/lib/dj/test_decorators.py b/py/packages/corpora/lib/dj/test_decorators.py index ad6a2fd..348dac5 100644 --- a/py/packages/corpora/lib/dj/test_decorators.py +++ b/py/packages/corpora/lib/dj/test_decorators.py @@ -1,7 +1,8 @@ import pytest +from django.core.exceptions import ObjectDoesNotExist from django.http import Http404 + from corpora.lib.dj.decorators import async_raise_not_found -from django.core.exceptions import ObjectDoesNotExist # A sample async function to simulate normal and failing behavior diff --git a/py/packages/corpora/lib/files.py b/py/packages/corpora/lib/files.py index d92c4fe..50652d8 100644 --- a/py/packages/corpora/lib/files.py +++ b/py/packages/corpora/lib/files.py @@ -1,5 +1,5 @@ -from typing import Union import hashlib +from typing import Union def compute_checksum(content: Union[bytes, str]) -> str: @@ -13,5 +13,5 @@ def compute_checksum(content: Union[bytes, str]) -> str: content = content.encode("utf-8") size = str(len(content)) - sha = hashlib.sha1(f"blob {size}\0".encode("utf-8") + content).hexdigest() + sha = hashlib.sha1(f"blob {size}\0".encode() + content).hexdigest() return sha diff --git a/py/packages/corpora/lib/test_files.py b/py/packages/corpora/lib/test_files.py index 5ce83e9..ddfbf59 100644 --- a/py/packages/corpora/lib/test_files.py +++ b/py/packages/corpora/lib/test_files.py @@ -1,5 +1,7 @@ -import pytest import hashlib + +import pytest + from corpora.lib.files import compute_checksum diff --git a/py/packages/corpora/migrations/0002_initial.py b/py/packages/corpora/migrations/0002_initial.py index 4eae51a..50bcf6a 100644 --- a/py/packages/corpora/migrations/0002_initial.py +++ b/py/packages/corpora/migrations/0002_initial.py @@ -1,9 +1,10 @@ # Generated by Django 5.1.2 on 2024-10-27 17:12 +import uuid + import django.db.models.deletion import django.utils.timezone import pgvector.django.vector -import uuid from django.db import migrations, models @@ -75,14 +76,14 @@ class Migration(migrations.Migration): ( "vector_of_summary", pgvector.django.vector.VectorField( - blank=True, dimensions=300, null=True + blank=True, dimensions=300, null=True, ), ), ("checksum", models.CharField(editable=False, max_length=32)), ( "created_at", models.DateTimeField( - default=django.utils.timezone.now, editable=False + default=django.utils.timezone.now, editable=False, ), ), ("updated_at", models.DateTimeField(auto_now=True)), @@ -117,7 +118,7 @@ class Migration(migrations.Migration): ( "vector", pgvector.django.vector.VectorField( - blank=True, dimensions=300, null=True + blank=True, dimensions=300, null=True, ), ), ("metadata", models.JSONField(blank=True, default=dict)), diff --git a/py/packages/corpora/models.py b/py/packages/corpora/models.py index 8449eb9..362705d 100644 --- a/py/packages/corpora/models.py +++ b/py/packages/corpora/models.py @@ -1,22 +1,26 @@ +import logging import os import uuid +from corpora_ai.split import get_text_splitter +from django.contrib.auth import get_user_model from django.db import models +from django.db.models.manager import BaseManager from django.utils import timezone -from django.contrib.auth import get_user_model # from django.contrib.postgres.fields import ArrayField -from pgvector.django import VectorField, CosineDistance +from pgvector.django import CosineDistance, VectorField - -from corpora_ai.split import get_text_splitter +# TODO: This loads too early and makes it hard to mock +# from corpora_ai.provider_loader import load_llm_provider User = get_user_model() +logger = logging.getLogger(__name__) + class Corpus(models.Model): - """ - Represents a unique corpus, often corresponding to a specific repository + """Represents a unique corpus, often corresponding to a specific repository or collection of documents. A corpus can have an associated URL for tracking its origin, such as a GitHub repository. """ @@ -30,7 +34,6 @@ class Corpus(models.Model): help_text="User who owns the corpus.", ) url = models.URLField( - null=True, blank=True, help_text="Optional URL associated with the corpus, e.g., a GitHub repository.", ) @@ -40,7 +43,8 @@ class Corpus(models.Model): help_text="Timestamp indicating when the corpus was created.", ) updated_at = models.DateTimeField( - auto_now=True, help_text="Timestamp indicating the last update of the corpus." + auto_now=True, + help_text="Timestamp indicating the last update of the corpus.", ) class Meta: @@ -50,10 +54,12 @@ class Meta: def __str__(self): return self.name - def get_relevant_splits(self, text: str, limit: int = 10): - """ - Given a text query, return the most relevant splits from this corpus. - """ + def get_relevant_splits( + self, + text: str, + limit: int = 10, + ) -> BaseManager["Split"]: + """Given a text query, return the most relevant splits from this corpus.""" from corpora_ai.provider_loader import load_llm_provider llm = load_llm_provider() @@ -70,38 +76,37 @@ def get_relevant_splits(self, text: str, limit: int = 10): .order_by("similarity")[:limit] ) - def get_relevant_splits_context(self, text: str, limit: int = 10): - """ - Given a text query, return the most relevant splits from this corpus + def get_relevant_splits_context(self, text: str, limit: int = 10) -> str: + """Given a text query, return the most relevant splits from this corpus along with the context of the split. """ splits = self.get_relevant_splits(text, limit) split_context = "" for split in splits: - split_context += f"\n\n{split.file.path}:\n```\n{split.content}\n```\n\n" + split_context += ( + f"\n\n{split.file.path}:\n```\n{split.content}\n```\n\n" + ) return split_context def get_file_hashes(self) -> dict: - """ - Retrieve a map of file paths to their hashes for this Corpus. - """ + """Retrieve a map of file paths to their hashes for this Corpus.""" # TODO: types? return {file.path: file.checksum for file in self.files.all()} - def delete_files(self, files: list): - """ - Delete files from this Corpus by path. - """ + def delete_files(self, files: list) -> None: + """Delete files from this Corpus by path.""" self.files.filter(path__in=files).delete() class CorpusTextFile(models.Model): - """ - A file with UTF-8 text content associated with a Corpus. - """ + """A file with UTF-8 text content associated with a Corpus.""" id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - corpus = models.ForeignKey(Corpus, on_delete=models.CASCADE, related_name="files") + corpus = models.ForeignKey( + Corpus, + on_delete=models.CASCADE, + related_name="files", + ) path = models.CharField(max_length=1024) content = models.TextField(blank=True) ai_summary = models.TextField(blank=True) @@ -147,8 +152,7 @@ def get_and_save_vector_of_summary(self): self.save(update_fields=["vector_of_summary"]) def split_content(self): - """ - Splits the content of the file into smaller parts using an appropriate text splitter. + """Splits the content of the file into smaller parts using an appropriate text splitter. Returns a list of Split instances. """ file_name = os.path.basename(self.path) @@ -169,7 +173,9 @@ def split_content(self): class Split(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) file = models.ForeignKey( - CorpusTextFile, on_delete=models.CASCADE, related_name="splits" + CorpusTextFile, + on_delete=models.CASCADE, + related_name="splits", ) order = models.PositiveIntegerField() content = models.TextField(blank=True) @@ -197,6 +203,9 @@ def __str__(self): return f"{self.file.corpus.name}:{self.file.path}:{self.order}" def get_and_save_vector(self): + logger.info( + f"{self.file.path}: {self.content[:10]} ... {self.content[-10:]}", + ) from corpora_ai.provider_loader import load_llm_provider llm = load_llm_provider() diff --git a/py/packages/corpora/router.py b/py/packages/corpora/router.py index e50e1da..5f4659a 100644 --- a/py/packages/corpora/router.py +++ b/py/packages/corpora/router.py @@ -3,11 +3,10 @@ from .auth import BearerAuth from .routers.corpus import corpus_router from .routers.corpustextfile import file_router -from .routers.split import split_router from .routers.plan import plan_router +from .routers.split import split_router from .routers.workon import workon_router - api = Router(tags=["corpora"], auth=BearerAuth()) api.add_router("corpus", corpus_router) diff --git a/py/packages/corpora/routers/corpus.py b/py/packages/corpora/routers/corpus.py index ab4e95c..b8ba94f 100644 --- a/py/packages/corpora/routers/corpus.py +++ b/py/packages/corpora/routers/corpus.py @@ -1,25 +1,24 @@ import uuid from typing import Dict, List, Optional -from django.db import IntegrityError +from asgiref.sync import sync_to_async +from corpora_ai.llm_interface import ChatCompletionTextMessage +from corpora_ai.prompts import CHAT_SYSTEM_MESSAGE +from corpora_ai.provider_loader import load_llm_provider from django.core.exceptions import ValidationError +from django.db import IntegrityError from django.http import HttpRequest - -from ninja import Router, Form, File -from ninja.files import UploadedFile +from ninja import File, Form, Router from ninja.errors import HttpError -from asgiref.sync import sync_to_async +from ninja.files import UploadedFile from pydantic import BaseModel from corpora.schema.chat import CorpusChatSchema, get_additional_context -from corpora_ai.llm_interface import ChatCompletionTextMessage -from corpora_ai.provider_loader import load_llm_provider -from corpora_ai.prompts import CHAT_SYSTEM_MESSAGE from ..auth import BearerAuth from ..lib.dj.decorators import async_raise_not_found from ..models import Corpus -from ..schema.core import CorpusSchema, CorpusResponseSchema +from ..schema.core import CorpusResponseSchema, CorpusSchema from ..tasks.sync import process_tarball corpus_router = Router(tags=["corpus"], auth=BearerAuth()) @@ -71,7 +70,7 @@ async def chat(request, payload: CorpusChatSchema): # But, in the current design, we let the client decide the messages. # A separate endpoint could be used by the client to "compress conversation" split_context = await sync_to_async(corpus.get_relevant_splits_context)( - "\n".join(message.text for message in payload.messages[-2:]) + "\n".join(message.text for message in payload.messages[-2:]), ) print(payload.messages[-1].text) @@ -120,8 +119,7 @@ async def update_files( update: CorpusUpdateFilesSchema = Form(...), tarball: UploadedFile = File(...), ): - """ - Update a Corpus with an uploaded tarball for additions/updates + """Update a Corpus with an uploaded tarball for additions/updates and a list of files to delete """ corpus = await Corpus.objects.aget(id=corpus_id) @@ -138,7 +136,7 @@ async def update_files( # get_file_hashes will return a map of file paths to their hashes from the database @corpus_router.get( - "/{corpus_id}/files", response=Dict[str, str], operation_id="get_file_hashes" + "/{corpus_id}/files", response=Dict[str, str], operation_id="get_file_hashes", ) async def get_file_hashes(request, corpus_id: uuid.UUID): """Retrieve a map of file paths to their hashes for a Corpus.""" @@ -156,7 +154,7 @@ async def delete_corpus(request, corpus_name: str): @corpus_router.get( - "", response={200: List[CorpusResponseSchema]}, operation_id="list_corpora" + "", response={200: List[CorpusResponseSchema]}, operation_id="list_corpora", ) async def list_corpora(request): """List all Corpora.""" @@ -165,7 +163,7 @@ async def list_corpora(request): @corpus_router.get( - "/{corpus_id}", response=CorpusResponseSchema, operation_id="get_corpus" + "/{corpus_id}", response=CorpusResponseSchema, operation_id="get_corpus", ) @async_raise_not_found async def get_corpus(request, corpus_id: uuid.UUID): diff --git a/py/packages/corpora/routers/corpustextfile.py b/py/packages/corpora/routers/corpustextfile.py index 537372d..ce9cc81 100644 --- a/py/packages/corpora/routers/corpustextfile.py +++ b/py/packages/corpora/routers/corpustextfile.py @@ -4,18 +4,18 @@ from ninja import Query, Router from ninja.errors import HttpError -from ..lib.files import compute_checksum +from ..auth import BearerAuth from ..lib.dj.decorators import async_raise_not_found +from ..lib.files import compute_checksum from ..models import Corpus, CorpusTextFile -from ..schema.core import FileSchema, FileResponseSchema -from ..auth import BearerAuth +from ..schema.core import FileResponseSchema, FileSchema file_router = Router(tags=["file"], auth=BearerAuth()) # Get file by path, given a corpus ID @file_router.get( - "/corpus/{corpus_id}", response=FileResponseSchema, operation_id="get_file_by_path" + "/corpus/{corpus_id}", response=FileResponseSchema, operation_id="get_file_by_path", ) @async_raise_not_found async def get_file_by_path( @@ -24,9 +24,8 @@ async def get_file_by_path( path: str = Query(..., description="Path to the file"), ): """Retrieve a File by path within a Corpus.""" - ctf = await CorpusTextFile.objects.select_related("corpus").aget( - corpus__id=corpus_id, path=path + corpus__id=corpus_id, path=path, ) return ctf @@ -40,7 +39,7 @@ async def get_file(request, file_id: uuid.UUID): @file_router.post( - "", response={201: FileResponseSchema, 409: str}, operation_id="create_file" + "", response={201: FileResponseSchema, 409: str}, operation_id="create_file", ) @async_raise_not_found async def create_file(request, payload: FileSchema): diff --git a/py/packages/corpora/routers/plan.py b/py/packages/corpora/routers/plan.py index b2b1b11..ef074e1 100644 --- a/py/packages/corpora/routers/plan.py +++ b/py/packages/corpora/routers/plan.py @@ -1,12 +1,11 @@ -from ninja import Router, Schema from asgiref.sync import sync_to_async - -from corpora.schema.chat import CorpusChatSchema, get_additional_context from corpora_ai.llm_interface import ChatCompletionTextMessage from corpora_ai.provider_loader import load_llm_provider +from ninja import Router, Schema + from corpora.auth import BearerAuth from corpora.models import Corpus - +from corpora.schema.chat import CorpusChatSchema, get_additional_context ISSUE_MAKER_SYSTEM_MESSAGE = ( "You are a skilled assistant focused on creating clear, actionable issues for this project. " @@ -35,7 +34,7 @@ async def get_issue(request, payload: CorpusChatSchema): # TODO: split context could be ... ? split_context = await sync_to_async(corpus.get_relevant_splits_context)( - "\n".join(message.text for message in payload.messages[-2:]) + "\n".join(message.text for message in payload.messages[-2:]), ) print(split_context) diff --git a/py/packages/corpora/routers/split.py b/py/packages/corpora/routers/split.py index 932b69b..45830cf 100644 --- a/py/packages/corpora/routers/split.py +++ b/py/packages/corpora/routers/split.py @@ -1,18 +1,18 @@ -from typing import List import uuid +from typing import List -from ninja import Router from asgiref.sync import sync_to_async +from ninja import Router +from ..auth import BearerAuth from ..models import Corpus, Split from ..schema.core import SplitResponseSchema, SplitVectorSearchSchema -from ..auth import BearerAuth split_router = Router(tags=["split"], auth=BearerAuth()) @split_router.post( - "/search", response=List[SplitResponseSchema], operation_id="vector_search" + "/search", response=List[SplitResponseSchema], operation_id="vector_search", ) async def vector_search(request, payload: SplitVectorSearchSchema): """Perform a vector similarity search for splits using a provided query vector.""" @@ -21,7 +21,7 @@ async def vector_search(request, payload: SplitVectorSearchSchema): corpus = await Corpus.objects.aget(id=corpus_id) similar_splits = await sync_to_async(list)( - corpus.get_relevant_splits(query, limit=payload.limit) + corpus.get_relevant_splits(query, limit=payload.limit), ) return similar_splits @@ -41,6 +41,6 @@ async def get_split(request, split_id: uuid.UUID): async def list_splits_for_file(request, file_id: uuid.UUID): """List all Splits for a specific CorpusTextFile.""" splits = await sync_to_async(list)( - Split.objects.filter(file_id=file_id).order_by("order") + Split.objects.filter(file_id=file_id).order_by("order"), ) return splits diff --git a/py/packages/corpora/routers/test_corpus.py b/py/packages/corpora/routers/test_corpus.py index 6eaea3a..a7b75bc 100644 --- a/py/packages/corpora/routers/test_corpus.py +++ b/py/packages/corpora/routers/test_corpus.py @@ -1,13 +1,14 @@ from unittest.mock import patch + import pytest -from django.test import TestCase +from asgiref.sync import sync_to_async from django.contrib.auth import get_user_model from django.core.files.uploadedfile import SimpleUploadedFile +from django.test import TestCase from ninja.testing import TestAsyncClient -from asgiref.sync import sync_to_async from .corpus import corpus_router -from .test_lib import create_user_and_token, create_corpus +from .test_lib import create_corpus, create_user_and_token User = get_user_model() client = TestAsyncClient(corpus_router) @@ -21,12 +22,12 @@ async def test_create_corpus(self): data = {"name": "Test Corpus", "url": "https://example.com/repo"} file_content = b"Dummy tarball content" file = SimpleUploadedFile( - "test.tar.gz", file_content, content_type="application/gzip" + "test.tar.gz", file_content, content_type="application/gzip", ) with patch("corpora.tasks.sync.process_tarball.delay") as mock_delay: response = await client.post( - "", data=data, FILES={"tarball": file}, headers=headers + "", data=data, FILES={"tarball": file}, headers=headers, ) response_data = response.json() mock_delay.assert_called_once_with(response_data["id"], file_content) @@ -46,7 +47,7 @@ async def test_update_files(self): # Prepare the tarball file file_content = b"Updated tarball content" file = SimpleUploadedFile( - "update.tar.gz", file_content, content_type="application/gzip" + "update.tar.gz", file_content, content_type="application/gzip", ) # Mock process_tarball to prevent actual processing @@ -76,11 +77,11 @@ async def test_create_corpus_conflict(self): data = {"name": "Duplicate Corpus", "url": "https://example.com/repo"} file_content = b"Dummy tarball content" file = SimpleUploadedFile( - "test.tar.gz", file_content, content_type="application/gzip" + "test.tar.gz", file_content, content_type="application/gzip", ) response = await client.post( - "", data=data, FILES={"tarball": file}, headers=headers + "", data=data, FILES={"tarball": file}, headers=headers, ) assert response.status_code == 409 assert ( @@ -105,7 +106,7 @@ async def test_get_corpus_not_found(self): """Test retrieving a non-existent corpus.""" _, headers = await create_user_and_token() response = await client.get( - "/00000000-0000-0000-0000-000000000000", headers=headers + "/00000000-0000-0000-0000-000000000000", headers=headers, ) assert response.status_code == 404 @@ -124,7 +125,7 @@ async def test_delete_corpus_not_found(self): """Test deleting a non-existent corpus.""" _, headers = await create_user_and_token() response = await client.delete( - "?corpus_name=NonExistentCorpus", headers=headers + "?corpus_name=NonExistentCorpus", headers=headers, ) assert response.status_code == 404 diff --git a/py/packages/corpora/routers/test_corpustextfile.py b/py/packages/corpora/routers/test_corpustextfile.py index 07240c3..aac8cd5 100644 --- a/py/packages/corpora/routers/test_corpustextfile.py +++ b/py/packages/corpora/routers/test_corpustextfile.py @@ -1,28 +1,27 @@ import pytest -from django.test import TestCase from django.contrib.auth import get_user_model +from django.test import TestCase from ninja.testing import TestAsyncClient from .corpustextfile import file_router -from .test_lib import create_user_and_token, create_corpus, create_file +from .test_lib import create_corpus, create_file, create_user_and_token User = get_user_model() client = TestAsyncClient(file_router) class CorpusTextFileAPITestCase(TestCase): - @pytest.mark.django_db async def test_get_file_by_path(self): """Test retrieving a file by path within a corpus.""" user, headers = await create_user_and_token() corpus = await create_corpus( - "Path Retrieval Corpus", "https://example.com/repo", user + "Path Retrieval Corpus", "https://example.com/repo", user, ) - file = await create_file(corpus, "nested/file1.txt", "Sample content") + await create_file(corpus, "nested/file1.txt", "Sample content") response = await client.get( - f"/corpus/{corpus.id}?path=nested/file1.txt", headers=headers + f"/corpus/{corpus.id}?path=nested/file1.txt", headers=headers, ) assert response.status_code == 200 data = response.json() @@ -35,11 +34,11 @@ async def test_get_file_by_path_not_found(self): """Test retrieving a non-existent file by path.""" user, headers = await create_user_and_token() corpus = await create_corpus( - "Nonexistent File Corpus", "https://example.com/repo", user + "Nonexistent File Corpus", "https://example.com/repo", user, ) response = await client.get( - f"/corpus/{corpus.id}?path=nonexistent/file.txt", headers=headers + f"/corpus/{corpus.id}?path=nonexistent/file.txt", headers=headers, ) assert response.status_code == 404 @@ -48,7 +47,7 @@ async def test_get_file_by_path_missing_query_param(self): """Test retrieving a file by path without providing the required query parameter.""" user, headers = await create_user_and_token() corpus = await create_corpus( - "Missing Query Param Corpus", "https://example.com/repo", user + "Missing Query Param Corpus", "https://example.com/repo", user, ) response = await client.get(f"/corpus/{corpus.id}", headers=headers) @@ -99,7 +98,7 @@ async def test_get_file(self): """Test retrieving a file by ID.""" user, headers = await create_user_and_token() corpus = await create_corpus( - "Retrieve File Corpus", "https://example.com/repo", user + "Retrieve File Corpus", "https://example.com/repo", user, ) file = await create_file(corpus, "file1.txt", "Sample content") @@ -115,6 +114,6 @@ async def test_get_file_not_found(self): """Test retrieving a non-existent file.""" _, headers = await create_user_and_token() response = await client.get( - "/00000000-0000-0000-0000-000000000000", headers=headers + "/00000000-0000-0000-0000-000000000000", headers=headers, ) assert response.status_code == 404 diff --git a/py/packages/corpora/routers/test_lib.py b/py/packages/corpora/routers/test_lib.py index 96d811c..29067d1 100644 --- a/py/packages/corpora/routers/test_lib.py +++ b/py/packages/corpora/routers/test_lib.py @@ -1,8 +1,8 @@ from datetime import timedelta +from asgiref.sync import sync_to_async from django.contrib.auth import get_user_model from django.utils import timezone -from asgiref.sync import sync_to_async from oauth2_provider.models import AccessToken, Application from corpora.models import Corpus, CorpusTextFile, Split @@ -14,7 +14,7 @@ @sync_to_async def create_user_and_token(): user, _ = User.objects.get_or_create( - username="testuser", defaults={"password": "password123"} + username="testuser", defaults={"password": "password123"}, ) application, _ = Application.objects.get_or_create( name="Test App", diff --git a/py/packages/corpora/routers/test_split.py b/py/packages/corpora/routers/test_split.py index 845ee0b..dc79231 100644 --- a/py/packages/corpora/routers/test_split.py +++ b/py/packages/corpora/routers/test_split.py @@ -1,12 +1,17 @@ -import pytest from unittest.mock import patch -from django.test import TestCase + +import pytest from django.contrib.auth import get_user_model +from django.test import TestCase from ninja.testing import TestAsyncClient from .split import split_router -from .test_lib import create_user_and_token, create_corpus, create_file, create_split - +from .test_lib import ( + create_corpus, + create_file, + create_split, + create_user_and_token, +) User = get_user_model() client = TestAsyncClient(split_router) @@ -62,7 +67,7 @@ async def test_vector_search_splits(self): with patch("corpora_ai.provider_loader.load_llm_provider") as mock_llm_provider: mock_llm_instance = mock_llm_provider.return_value mock_llm_instance.get_embedding.return_value = [ - 0.1 + 0.1, ] * 1536 # Mocked embedding # Execute the test request diff --git a/py/packages/corpora/routers/workon.py b/py/packages/corpora/routers/workon.py index 3fdadcc..236b771 100644 --- a/py/packages/corpora/routers/workon.py +++ b/py/packages/corpora/routers/workon.py @@ -1,10 +1,10 @@ -from ninja import Router, Schema from asgiref.sync import sync_to_async - -from corpora.schema.chat import CorpusFileChatSchema, get_additional_context from corpora_ai.llm_interface import ChatCompletionTextMessage from corpora_ai.provider_loader import load_llm_provider +from ninja import Router, Schema + from corpora.models import Corpus +from corpora.schema.chat import CorpusFileChatSchema, get_additional_context from ..auth import BearerAuth @@ -32,7 +32,7 @@ async def file(request, payload: CorpusFileChatSchema): # But, in the current design, we let the client decide the messages. # A separate endpoint could be used by the client to "compress conversation" split_context = await sync_to_async(corpus.get_relevant_splits_context)( - "\n".join(message.text for message in payload.messages[-2:]) + "\n".join(message.text for message in payload.messages[-2:]), ) print(payload.messages[-1].text) diff --git a/py/packages/corpora/schema/chat.py b/py/packages/corpora/schema/chat.py index a108ed7..dcfdcfe 100644 --- a/py/packages/corpora/schema/chat.py +++ b/py/packages/corpora/schema/chat.py @@ -1,4 +1,5 @@ from typing import List + from ninja import Schema @@ -31,7 +32,7 @@ def get_additional_context(payload: CorpusChatSchema, ext: str = "") -> str: payload.purpose, payload.structure, payload.directions, - ] + ], ): context += "\n\nADDITIONAL CONTEXT:\n\n" diff --git a/py/packages/corpora/schema/core.py b/py/packages/corpora/schema/core.py index 1c83ba2..cf1b5fb 100644 --- a/py/packages/corpora/schema/core.py +++ b/py/packages/corpora/schema/core.py @@ -1,8 +1,6 @@ from datetime import datetime from typing import Optional from uuid import UUID -from typing import List - from ninja import Schema diff --git a/py/packages/corpora/tasks/test_sync.py b/py/packages/corpora/tasks/test_sync.py index 90b81d0..a8ebdec 100644 --- a/py/packages/corpora/tasks/test_sync.py +++ b/py/packages/corpora/tasks/test_sync.py @@ -5,10 +5,10 @@ import pytest from .sync import ( - process_tarball, generate_summary_task, - split_file_task, generate_vector_task, + process_tarball, + split_file_task, ) @@ -51,7 +51,7 @@ def test_process_tarball( mock_corpus_get.assert_called_once_with(id="mock_corpus_id") mock_corpus.save.assert_called_once_with(update_fields=["updated_at"]) mock_get_or_create.assert_called_once_with( - corpus=mock_corpus, path="test_file.txt" + corpus=mock_corpus, path="test_file.txt", ) assert mock_file.content == "test file content" # assert mock_file.checksum == "mock_checksum" diff --git a/py/packages/corpora/test_models.py b/py/packages/corpora/test_models.py index a807e6a..a79fc7a 100644 --- a/py/packages/corpora/test_models.py +++ b/py/packages/corpora/test_models.py @@ -1,7 +1,9 @@ -import pytest from unittest.mock import patch + +import pytest from django.contrib.auth import get_user_model from django.utils import timezone + from corpora.models import Corpus, CorpusTextFile, Split User = get_user_model() @@ -12,7 +14,7 @@ def test_corpus_creation(): """Test creating a Corpus instance.""" user = User.objects.create(username="testuser", password="password123") corpus = Corpus.objects.create( - name="Test Corpus", owner=user, url="https://example.com" + name="Test Corpus", owner=user, url="https://example.com", ) assert corpus.name == "Test Corpus" @@ -34,16 +36,16 @@ def test_get_relevant_splits(mock_llm_provider): user = User.objects.create(username="testuser", password="password123") corpus = Corpus.objects.create(name="Test Corpus", owner=user) file = CorpusTextFile.objects.create( - corpus=corpus, path="test.txt", content="Content of the file." + corpus=corpus, path="test.txt", content="Content of the file.", ) split_1 = Split.objects.create( - file=file, order=1, content="First split content", vector=[0.1] * 1536 + file=file, order=1, content="First split content", vector=[0.1] * 1536, ) split_2 = Split.objects.create( - file=file, order=2, content="Second split content", vector=[0.2] * 1536 + file=file, order=2, content="Second split content", vector=[0.2] * 1536, ) split_3 = Split.objects.create( - file=file, order=3, content="Third split content", vector=[0.3] * 1536 + file=file, order=3, content="Third split content", vector=[0.3] * 1536, ) # Call the method @@ -86,7 +88,7 @@ def test_split_creation(): user = User.objects.create(username="testuser", password="password123") corpus = Corpus.objects.create(name="Test Corpus", owner=user) file = CorpusTextFile.objects.create( - corpus=corpus, path="test.txt", content="Split content." + corpus=corpus, path="test.txt", content="Split content.", ) split = Split.objects.create(file=file, order=1, content="First split part") @@ -104,7 +106,7 @@ def test_get_and_save_summary(mock_llm_provider): user = User.objects.create(username="testuser", password="password123") corpus = Corpus.objects.create(name="Test Corpus", owner=user) file = CorpusTextFile.objects.create( - corpus=corpus, path="test.txt", content="Some content" + corpus=corpus, path="test.txt", content="Some content", ) file.get_and_save_summary() @@ -122,7 +124,7 @@ def test_get_and_save_vector_of_summary(mock_llm_provider): user = User.objects.create(username="testuser", password="password123") corpus = Corpus.objects.create(name="Test Corpus", owner=user) file = CorpusTextFile.objects.create( - corpus=corpus, path="test.txt", ai_summary="Summary content" + corpus=corpus, path="test.txt", ai_summary="Summary content", ) file.get_and_save_vector_of_summary() diff --git a/py/packages/corpora/test_models_corpus.py b/py/packages/corpora/test_models_corpus.py index fc82714..7963abf 100644 --- a/py/packages/corpora/test_models_corpus.py +++ b/py/packages/corpora/test_models_corpus.py @@ -1,10 +1,12 @@ +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock from django.contrib.auth import get_user_model + from corpora.models import ( Corpus, - Split, CorpusTextFile, + Split, ) User = get_user_model() @@ -19,14 +21,14 @@ def user(self): @pytest.fixture def corpus(self, user): return Corpus.objects.create( - name="Test Corpus", owner=user, url="https://example.com" + name="Test Corpus", owner=user, url="https://example.com", ) @pytest.fixture def file(self, corpus): # Create a file associated with the corpus return CorpusTextFile.objects.create( - corpus=corpus, path="test.txt", checksum="abc123", content="File content" + corpus=corpus, path="test.txt", checksum="abc123", content="File content", ) @pytest.fixture @@ -48,7 +50,7 @@ def mock_splits(self, file): def test_get_relevant_splits(self, corpus, mock_splits): with patch( - "corpora_ai.provider_loader.load_llm_provider" + "corpora_ai.provider_loader.load_llm_provider", ) as mock_load_llm_provider: mock_llm = MagicMock() mock_load_llm_provider.return_value = mock_llm @@ -63,7 +65,7 @@ def test_get_relevant_splits(self, corpus, mock_splits): def test_get_relevant_splits_context(self, corpus, mock_splits): with patch( - "corpora_ai.provider_loader.load_llm_provider" + "corpora_ai.provider_loader.load_llm_provider", ) as mock_load_llm_provider: mock_llm = MagicMock() mock_load_llm_provider.return_value = mock_llm diff --git a/py/packages/corpora/views.py b/py/packages/corpora/views.py index 94743d4..3f0f14e 100644 --- a/py/packages/corpora/views.py +++ b/py/packages/corpora/views.py @@ -12,7 +12,7 @@ def get(self, request, arch, *args, **kwargs): with open(path, "rb") as binary_file: response = HttpResponse( - binary_file.read(), content_type="application/octet-stream" + binary_file.read(), content_type="application/octet-stream", ) response["Content-Disposition"] = "attachment; filename=corpora" return response diff --git a/py/packages/corpora_ai/count_tokens.py b/py/packages/corpora_ai/count_tokens.py index 876589d..645a2ff 100644 --- a/py/packages/corpora_ai/count_tokens.py +++ b/py/packages/corpora_ai/count_tokens.py @@ -2,8 +2,7 @@ def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int: - """ - Counts the number of tokens in a given text string for a specific model. + """Counts the number of tokens in a given text string for a specific model. Args: text (str): The text to count tokens for. @@ -11,6 +10,7 @@ def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int: Returns: int: The number of tokens in the text. + """ # Load the tokenizer for the specified model encoding = tiktoken.encoding_for_model(model) diff --git a/py/packages/corpora_ai/llm_interface.py b/py/packages/corpora_ai/llm_interface.py index 33748f9..93b03d3 100644 --- a/py/packages/corpora_ai/llm_interface.py +++ b/py/packages/corpora_ai/llm_interface.py @@ -1,6 +1,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass from typing import List, Type, TypeVar + from pydantic import BaseModel from corpora_ai.prompts import ( @@ -13,8 +14,7 @@ @dataclass class ChatCompletionTextMessage: - """ - Represents a message in a conversation, with a specific role and text. + """Represents a message in a conversation, with a specific role and text. """ role: str # e.g., "user", "system", "assistant" @@ -22,29 +22,26 @@ class ChatCompletionTextMessage: class LLMBaseInterface(ABC): - """ - Abstract base class for LLM providers, defining methods for text generation and embeddings. + """Abstract base class for LLM providers, defining methods for text generation and embeddings. """ @abstractmethod def get_text_completion(self, messages: List[ChatCompletionTextMessage]) -> str: - """ - Generates a text completion based on a list of Message objects. + """Generates a text completion based on a list of Message objects. Args: messages (List[Message]): A list of Message objects, each with a role and content. Returns: str: The generated response text. + """ - pass @abstractmethod def get_data_completion( - self, messages: List[ChatCompletionTextMessage], model: Type[T] + self, messages: List[ChatCompletionTextMessage], model: Type[T], ) -> T: - """ - Generates an instance of the provided schema based on a list of Message objects. + """Generates an instance of the provided schema based on a list of Message objects. Args: messages (List[Message]): A list of Message objects, each with a role and content. @@ -52,31 +49,30 @@ def get_data_completion( Returns: T: The generated instance of the schema type. + """ - pass @abstractmethod def get_embedding(self, text: str) -> List[float]: - """ - Generates an embedding vector for the input text, suitable for a pgvector VectorField. + """Generates an embedding vector for the input text, suitable for a pgvector VectorField. Args: text (str): The text to embed. Returns: List[float]: The embedding vector. + """ - pass def get_summary(self, text: str) -> str: - """ - Generates a summary of the input text. + """Generates a summary of the input text. Args: text (str): The text to summarize. Returns: str: The generated summary text. + """ return self.get_text_completion( [ @@ -88,12 +84,11 @@ def get_summary(self, text: str) -> str: role="user", text=f"Summarize the following:\n {text}", ), - ] + ], ) def get_synthetic_embedding_text(self, text: str) -> str: - """ - Given a short prompt, generate a synthetic embedding text + """Given a short prompt, generate a synthetic embedding text that is more like to match splits in the corpus. """ return self.get_text_completion( @@ -106,5 +101,5 @@ def get_synthetic_embedding_text(self, text: str) -> str: role="user", text=text, ), - ] + ], ) diff --git a/py/packages/corpora_ai/provider_loader.py b/py/packages/corpora_ai/provider_loader.py index cc6db9d..1444e27 100644 --- a/py/packages/corpora_ai/provider_loader.py +++ b/py/packages/corpora_ai/provider_loader.py @@ -1,5 +1,6 @@ import os from typing import Optional + from corpora_ai.llm_interface import LLMBaseInterface try: @@ -12,11 +13,11 @@ def load_llm_provider() -> Optional[LLMBaseInterface]: - """ - Dynamically loads the best LLM provider based on environment variables. + """Dynamically loads the best LLM provider based on environment variables. Returns: Optional[LLMBaseInterface]: An instance of the best available LLM provider. + """ provider_name = os.getenv("LLM_PROVIDER", "openai") # TODO: we need to specify the model in the interface really diff --git a/py/packages/corpora_ai/split.py b/py/packages/corpora_ai/split.py index a261b20..37b4ce0 100644 --- a/py/packages/corpora_ai/split.py +++ b/py/packages/corpora_ai/split.py @@ -2,10 +2,10 @@ from typing import Union from langchain_text_splitters import ( - PythonCodeTextSplitter, + CharacterTextSplitter, # MarkdownHeaderTextSplitter, MarkdownTextSplitter, - CharacterTextSplitter, + PythonCodeTextSplitter, ) @@ -14,8 +14,7 @@ def get_text_splitter( chunk_size: int = 5000, # number of characters chunk_overlap: int = 0, # number of characters ) -> Union[PythonCodeTextSplitter, CharacterTextSplitter]: - """ - Returns an appropriate text splitter based on the file extension or name. + """Returns an appropriate text splitter based on the file extension or name. """ # Mapping specific extensions to splitters extension_to_splitter = { @@ -29,7 +28,7 @@ def get_text_splitter( ext = ext.lower() # Handle files without extensions using a default splitter - splitter_class = extension_to_splitter.get(ext, None) + splitter_class = extension_to_splitter.get(ext) # For files with defined splitters, return the configured splitter instance if splitter_class: @@ -37,5 +36,5 @@ def get_text_splitter( # For text-based formats or unknown extensions, use CharacterTextSplitter with `\n\n` return CharacterTextSplitter( - separator="\n\n", chunk_size=chunk_size, chunk_overlap=chunk_overlap + separator="\n\n", chunk_size=chunk_size, chunk_overlap=chunk_overlap, ) diff --git a/py/packages/corpora_ai/test_provider_loader.py b/py/packages/corpora_ai/test_provider_loader.py index fdfed50..ec695d0 100644 --- a/py/packages/corpora_ai/test_provider_loader.py +++ b/py/packages/corpora_ai/test_provider_loader.py @@ -1,21 +1,19 @@ import os import unittest -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch -from openai import azure_endpoint -from corpora_ai.provider_loader import load_llm_provider from corpora_ai.llm_interface import LLMBaseInterface +from corpora_ai.provider_loader import load_llm_provider class TestLoadLLMProvider(unittest.TestCase): @patch.dict( - os.environ, {"LLM_PROVIDER": "openai", "OPENAI_API_KEY": "test_api_key"} + os.environ, {"LLM_PROVIDER": "openai", "OPENAI_API_KEY": "test_api_key"}, ) @patch("corpora_ai.provider_loader.OpenAIClient") def test_load_openai_provider_success(self, MockOpenAIClient): - """ - Test loading the OpenAI provider successfully when environment variables are set correctly. + """Test loading the OpenAI provider successfully when environment variables are set correctly. """ mock_client_instance = MagicMock(spec=LLMBaseInterface) MockOpenAIClient.return_value = mock_client_instance @@ -23,7 +21,7 @@ def test_load_openai_provider_success(self, MockOpenAIClient): provider = load_llm_provider() MockOpenAIClient.assert_called_once_with( - api_key="test_api_key", azure_endpoint=None + api_key="test_api_key", azure_endpoint=None, ) self.assertIsInstance(provider, LLMBaseInterface) self.assertEqual(provider, mock_client_instance) @@ -31,8 +29,7 @@ def test_load_openai_provider_success(self, MockOpenAIClient): @patch.dict(os.environ, {"LLM_PROVIDER": "openai", "OPENAI_API_KEY": ""}) @patch("corpora_ai.provider_loader.OpenAIClient") def test_missing_openai_api_key(self, MockOpenAIClient): - """ - Test that ValueError is raised if the OPENAI_API_KEY environment variable is not set. + """Test that ValueError is raised if the OPENAI_API_KEY environment variable is not set. """ MockOpenAIClient.side_effect = None # Ensure OpenAIClient is available @@ -40,13 +37,12 @@ def test_missing_openai_api_key(self, MockOpenAIClient): load_llm_provider() self.assertEqual( - str(context.exception), "OPENAI_API_KEY environment variable is not set." + str(context.exception), "OPENAI_API_KEY environment variable is not set.", ) @patch.dict(os.environ, {"LLM_PROVIDER": "unsupported_provider"}) def test_invalid_provider(self): - """ - Test that ValueError is raised when an unsupported provider is specified. + """Test that ValueError is raised when an unsupported provider is specified. """ with self.assertRaises(ValueError) as context: load_llm_provider() @@ -56,8 +52,7 @@ def test_invalid_provider(self): @patch.dict(os.environ, {}) @patch("corpora_ai.provider_loader.OpenAIClient", None) def test_no_provider_found(self): - """ - Test that ValueError is raised when no valid provider is available and no environment variable is set. + """Test that ValueError is raised when no valid provider is available and no environment variable is set. """ with self.assertRaises(ValueError) as context: load_llm_provider() diff --git a/py/packages/corpora_ai_openai/llm_client.py b/py/packages/corpora_ai_openai/llm_client.py index 26d54ae..60af583 100644 --- a/py/packages/corpora_ai_openai/llm_client.py +++ b/py/packages/corpora_ai_openai/llm_client.py @@ -1,10 +1,9 @@ import json from typing import List, Type, TypeVar -from openai import OpenAI, OpenAIError, AzureOpenAI -from pydantic import BaseModel - -from corpora_ai.llm_interface import LLMBaseInterface, ChatCompletionTextMessage +from corpora_ai.llm_interface import ChatCompletionTextMessage, LLMBaseInterface +from openai import AzureOpenAI, OpenAI, OpenAIError +from pydantic import BaseModel T = TypeVar("T", bound=BaseModel) @@ -39,15 +38,14 @@ def get_text_completion(self, messages: List[ChatCompletionTextMessage]) -> str: # Convert Message objects to dictionaries for the OpenAI API message_dicts = [{"role": msg.role, "content": msg.text} for msg in messages] response = self.client.chat.completions.create( - model=self.completion_model, messages=message_dicts + model=self.completion_model, messages=message_dicts, ) return response.choices[0].message.content def get_data_completion( - self, messages: List[ChatCompletionTextMessage], model: Type[T] + self, messages: List[ChatCompletionTextMessage], model: Type[T], ) -> T: - """ - Generates structured data completion using OpenAI's function calling. + """Generates structured data completion using OpenAI's function calling. Args: messages (List[ChatCompletionTextMessage]): Input messages for the completion. @@ -55,6 +53,7 @@ def get_data_completion( Returns: BaseModel: An instance of the provided Pydantic model populated with data. + """ if not issubclass(model, BaseModel): raise ValueError("Schema must be a subclass of pydantic.BaseModel.") diff --git a/py/packages/corpora_ai_openai/test_llm_client.py b/py/packages/corpora_ai_openai/test_llm_client.py index e52fc21..c5dc5af 100644 --- a/py/packages/corpora_ai_openai/test_llm_client.py +++ b/py/packages/corpora_ai_openai/test_llm_client.py @@ -1,23 +1,22 @@ import unittest -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch -from corpora_ai_openai.llm_client import OpenAIClient from corpora_ai.llm_interface import ChatCompletionTextMessage +from corpora_ai_openai.llm_client import OpenAIClient + class TestOpenAIClient(unittest.TestCase): @patch("corpora_ai_openai.llm_client.OpenAI") def setUp(self, MockOpenAI): - """ - Set up the OpenAIClient instance and mock OpenAI API client. + """Set up the OpenAIClient instance and mock OpenAI API client. """ self.mock_openai_client = MockOpenAI.return_value self.client = OpenAIClient(api_key="test_api_key") def test_get_text_completion_success(self): - """ - Test that get_text_completion returns the correct response text. + """Test that get_text_completion returns the correct response text. """ # Mock response from OpenAI API mock_response = MagicMock() @@ -34,12 +33,11 @@ def test_get_text_completion_success(self): # Ensure OpenAI API was called with correct parameters self.mock_openai_client.chat.completions.create.assert_called_once_with( - model="gpt-4o", messages=[{"role": "user", "content": "Tell me a joke."}] + model="gpt-4o", messages=[{"role": "user", "content": "Tell me a joke."}], ) def test_get_embedding_success(self): - """ - Test that get_embedding returns the correct embedding vector. + """Test that get_embedding returns the correct embedding vector. """ # Mock response from OpenAI API mock_response = MagicMock() @@ -53,19 +51,17 @@ def test_get_embedding_success(self): # Ensure OpenAI API was called with correct parameters self.mock_openai_client.embeddings.create.assert_called_once_with( - input="Sample text for embedding", model="text-embedding-3-small" + input="Sample text for embedding", model="text-embedding-3-small", ) def test_get_text_completion_empty_messages(self): - """ - Test that get_text_completion raises an error when messages list is empty. + """Test that get_text_completion raises an error when messages list is empty. """ with self.assertRaises(ValueError): self.client.get_text_completion([]) def test_get_embedding_empty_text(self): - """ - Test that get_embedding raises an error when text is empty. + """Test that get_embedding raises an error when text is empty. """ with self.assertRaises(ValueError): self.client.get_embedding("") diff --git a/py/packages/corpora_cli/__init__py b/py/packages/corpora_cli/__init__.py similarity index 100% rename from py/packages/corpora_cli/__init__py rename to py/packages/corpora_cli/__init__.py diff --git a/py/packages/corpora_cli/auth.py b/py/packages/corpora_cli/auth.py index ef89adb..029fbf4 100644 --- a/py/packages/corpora_cli/auth.py +++ b/py/packages/corpora_cli/auth.py @@ -1,14 +1,14 @@ -import os import base64 +import os +from typing import Any, Dict, Optional + import requests import typer -from typing import Optional, Dict, Any class AuthError(Exception): """Custom exception for authentication errors.""" - pass class AuthResolver: @@ -18,8 +18,7 @@ def __init__(self, config: Dict[str, Any]): self.token_url = f"{base_url}/o/token/" def resolve_auth(self) -> str: - """ - Attempts to authenticate using available methods. + """Attempts to authenticate using available methods. Current supported methods: Client Credentials. Returns: @@ -27,6 +26,7 @@ def resolve_auth(self) -> str: Raises: AuthError: If no valid authentication method is available. + """ auth_token = self._authenticate_with_client_credentials() if auth_token: @@ -35,40 +35,39 @@ def resolve_auth(self) -> str: raise AuthError("No valid authentication method available.") def _authenticate_with_client_credentials(self) -> Optional[str]: - """ - Authenticate using client credentials from environment variables or config file. + """Authenticate using client credentials from environment variables or config file. Returns: Optional[str]: Access token if authentication is successful, otherwise None. + """ # Attempt to get credentials from environment variables or config credential = os.getenv("CREDENTIAL") client_id = os.getenv("CORPORA_CLIENT_ID") or self.config.get("auth", {}).get( - "client_id" + "client_id", ) client_secret = os.getenv("CORPORA_CLIENT_SECRET") or self.config.get( - "auth", {} + "auth", {}, ).get("client_secret") if credential: # Use pre-encoded credential if available typer.echo("Authenticating with encoded client credentials...") return self._request_token_with_basic_auth(credential) - elif client_id and client_secret: + if client_id and client_secret: # Encode client_id and client_secret in base64 for Basic Auth header typer.echo("Authenticating by encoding client credentials...") return self._request_token_with_basic_auth( - self._encode_credentials(client_id, client_secret) + self._encode_credentials(client_id, client_secret), ) typer.echo( - "Client credentials not found in environment or configuration.", err=True + "Client credentials not found in environment or configuration.", err=True, ) return None def _encode_credentials(self, client_id: str, client_secret: str) -> str: - """ - Encode client_id and client_secret to Base64 for Basic Authorization header. + """Encode client_id and client_secret to Base64 for Basic Authorization header. Args: client_id (str): OAuth client ID. @@ -76,13 +75,13 @@ def _encode_credentials(self, client_id: str, client_secret: str) -> str: Returns: str: Base64 encoded credentials. + """ credential = f"{client_id}:{client_secret}" return base64.b64encode(credential.encode("utf-8")).decode("utf-8") def _request_token_with_basic_auth(self, credential: str) -> str: - """ - Requests an access token using HTTP Basic Authentication. + """Requests an access token using HTTP Basic Authentication. Args: credential (str): Base64 encoded client credentials. @@ -92,6 +91,7 @@ def _request_token_with_basic_auth(self, credential: str) -> str: Raises: AuthError: If authentication fails. + """ headers = { "Authorization": f"Basic {credential}", diff --git a/py/packages/corpora_cli/commands/corpus.py b/py/packages/corpora_cli/commands/corpus.py index bff5852..ca34def 100644 --- a/py/packages/corpora_cli/commands/corpus.py +++ b/py/packages/corpora_cli/commands/corpus.py @@ -1,14 +1,15 @@ import os from pathlib import Path -import typer from pprint import pformat +import typer +from corpora_client.exceptions import ApiException + from corpora_cli.config import CONFIG_FILE_PATH, ID_FILE_PATH, save_config from corpora_cli.constants import CORPUS_EXISTS_MESSAGE from corpora_cli.context import ContextObject from corpora_cli.utils.collectors import get_best_collector from corpora_cli.utils.git import get_file_hash -from corpora_client.exceptions import ApiException app = typer.Typer(help="Corpus commands") @@ -80,7 +81,8 @@ def sync(ctx: typer.Context): collector = get_best_collector(repo_root, c.config) local_files = collector.collect_files() local_files_hash_map = { - file.relative_to(repo_root): get_file_hash(str(file)) for file in local_files + file.relative_to(repo_root): get_file_hash(str(file)) + for file in local_files } # TODO: debug flag! # c.console.print("Local file hash map:") @@ -108,14 +110,18 @@ def sync(ctx: typer.Context): c.console.print(pformat(files_to_delete, width=80)) if not files_to_update and not files_to_delete: - c.console.print("No changes detected. Everything is up-to-date!", style="green") + c.console.print( + "No changes detected. Everything is up-to-date!", + style="green", + ) return # Create tarball for files to update/add if files_to_update or files_to_delete: c.console.print("Creating tarball for updated/added files... ") tarball = collector.create_tarball( - [repo_root / p for p in files_to_update.keys()], repo_root + [repo_root / p for p in files_to_update], + repo_root, ).getvalue() c.console.print(f"Tarball created: {len(tarball)} bytes") @@ -194,9 +200,10 @@ def greet(name): c.console.print(table) # Progress bar - from rich.progress import track import time + from rich.progress import track + for _ in track(range(10), description="Processing..."): time.sleep(0.1) # Simulate a task @@ -212,7 +219,11 @@ def greet(name): # Panel from rich.panel import Panel - panel = Panel("This is inside a panel.", title="Panel Title", border_style="blue") + panel = Panel( + "This is inside a panel.", + title="Panel Title", + border_style="blue", + ) c.console.print(panel) # Exceptions diff --git a/py/packages/corpora_cli/commands/file.py b/py/packages/corpora_cli/commands/file.py index cff6ae3..6f9cba7 100644 --- a/py/packages/corpora_cli/commands/file.py +++ b/py/packages/corpora_cli/commands/file.py @@ -9,7 +9,10 @@ def add(ctx: typer.Context, corpus_id: str, path: str): """Add a file to a specified corpus.""" c: ContextObject = ctx.obj - c.console.print(f"Adding file at {path} to corpus {corpus_id}", style="green") + c.console.print( + f"Adding file at {path} to corpus {corpus_id}", + style="green", + ) @app.command() diff --git a/py/packages/corpora_cli/commands/plan.py b/py/packages/corpora_cli/commands/plan.py index c122fd1..faddd03 100644 --- a/py/packages/corpora_cli/commands/plan.py +++ b/py/packages/corpora_cli/commands/plan.py @@ -1,10 +1,11 @@ from typing import List -import typer -from prompt_toolkit.shortcuts import PromptSession +import typer from corpora_client.models.corpus_chat_schema import CorpusChatSchema from corpora_client.models.message_schema import MessageSchema from corpora_pm.providers.provider_loader import Corpus, load_provider +from prompt_toolkit.shortcuts import PromptSession + from corpora_cli.context import ContextObject app = typer.Typer(help="Interactive issue creation CLI") @@ -19,7 +20,7 @@ def extract_repo_path(url: str) -> str: def get_file_content_or_create(path: str) -> str: try: - with open(path, "r") as f: + with open(path) as f: return f.read() except FileNotFoundError: with open(path, "w") as f: @@ -28,9 +29,7 @@ def get_file_content_or_create(path: str) -> str: @app.command() def issue(ctx: typer.Context): - """ - Interactively create and refine a prospective issue for a given corpus. - """ + """Interactively create and refine a prospective issue for a given corpus.""" c: ContextObject = ctx.obj c.console.print("Entering interactive issue creation...", style="bold blue") @@ -51,7 +50,10 @@ def issue(ctx: typer.Context): c.console.print("Thinking...", style="bold blue") if not user_input: - c.console.print("No input provided. Please try again.", style="yellow") + c.console.print( + "No input provided. Please try again.", + style="yellow", + ) continue # Add the user's input as a new message @@ -73,17 +75,17 @@ def issue(ctx: typer.Context): purpose=purpose, structure=structure, directions=directions, - ) + ), ) # Display the generated draft issue - c.console.print(f"Draft Issue:", style="bold green") + c.console.print("Draft Issue:", style="bold green") c.console.print(f"Title: {draft_issue.title}", style="magenta") c.console.print(f"Body:\n{draft_issue.body}", style="dim") # Confirm if the user wants to post if typer.confirm("\nPost this issue?"): issue_tracker = load_provider( - Corpus(url=c.config["url"], id=c.config["id"]) + Corpus(url=c.config["url"], id=c.config["id"]), ) resp = issue_tracker.create_issue( extract_repo_path(c.config["url"]), @@ -93,36 +95,36 @@ def issue(ctx: typer.Context): c.console.print("Issue posted!", style="green") c.console.print(f"URL: {resp.url}", style="magenta") return - else: - c.console.print( - "You chose not to post the issue. Refine your messages or add new ones.", - style="yellow", - ) - messages.append( - MessageSchema( - role="assistant", - text=f"{draft_issue.title}\n{draft_issue.body}", - ) - ) + c.console.print( + "You chose not to post the issue. Refine your messages or add new ones.", + style="yellow", + ) + messages.append( + MessageSchema( + role="assistant", + text=f"{draft_issue.title}\n{draft_issue.body}", + ), + ) @app.command() def update_issue(ctx: typer.Context, issue_number: int): - """ - Interactively update an existing issue for a given corpus. - """ + """Interactively update an existing issue for a given corpus.""" c: ContextObject = ctx.obj c.console.print("Fetching existing issue...", style="bold blue") - issue_tracker = load_provider(Corpus(url=c.config["url"], id=c.config["id"])) + issue_tracker = load_provider( + Corpus(url=c.config["url"], id=c.config["id"]), + ) repo_path = extract_repo_path(c.config["url"]) existing_issue = issue_tracker.get_issue(repo_path, issue_number) # Start with the existing issue state messages: List[MessageSchema] = [ MessageSchema( - role="user", text=f"Title: {existing_issue.title}\n{existing_issue.body}" - ) + role="user", + text=f"Title: {existing_issue.title}\n{existing_issue.body}", + ), ] c.console.print("Existing Issue:", style="bold green") @@ -143,7 +145,10 @@ def update_issue(ctx: typer.Context, issue_number: int): c.console.print("Thinking...", style="bold blue") if not user_input: - c.console.print("No input provided. Please try again.", style="yellow") + c.console.print( + "No input provided. Please try again.", + style="yellow", + ) continue # Add the user's input as a new message @@ -165,10 +170,10 @@ def update_issue(ctx: typer.Context, issue_number: int): purpose=purpose, structure=structure, directions=directions, - ) + ), ) # Display the updated draft issue - c.console.print(f"Updated Draft Issue:", style="bold green") + c.console.print("Updated Draft Issue:", style="bold green") c.console.print(f"Title: {updated_issue.title}", style="magenta") c.console.print(f"Body:\n{updated_issue.body}", style="dim") @@ -183,14 +188,13 @@ def update_issue(ctx: typer.Context, issue_number: int): c.console.print("Issue updated!", style="green") c.console.print(f"URL: {resp.url}", style="magenta") return - else: - c.console.print( - "You chose not to update the issue. Refine your messages or add new ones.", - style="yellow", - ) - messages.append( - MessageSchema( - role="assistant", - text=f"{updated_issue.title}\n{updated_issue.body}", - ) - ) + c.console.print( + "You chose not to update the issue. Refine your messages or add new ones.", + style="yellow", + ) + messages.append( + MessageSchema( + role="assistant", + text=f"{updated_issue.title}\n{updated_issue.body}", + ), + ) diff --git a/py/packages/corpora_cli/commands/split.py b/py/packages/corpora_cli/commands/split.py index 411e7fa..4ad2253 100644 --- a/py/packages/corpora_cli/commands/split.py +++ b/py/packages/corpora_cli/commands/split.py @@ -1,7 +1,9 @@ import typer +from corpora_client.models.split_vector_search_schema import ( + SplitVectorSearchSchema, +) from corpora_cli.context import ContextObject -from corpora_client.models.split_vector_search_schema import SplitVectorSearchSchema app = typer.Typer(help="Split commands") diff --git a/py/packages/corpora_cli/commands/test_corpus.py b/py/packages/corpora_cli/commands/test_corpus.py index f2fcf57..e625f82 100644 --- a/py/packages/corpora_cli/commands/test_corpus.py +++ b/py/packages/corpora_cli/commands/test_corpus.py @@ -1,11 +1,11 @@ -from unittest.mock import patch, Mock, mock_open from io import StringIO -from typer.testing import CliRunner -from rich.console import Console +from unittest.mock import Mock, mock_open, patch from corpora_client.exceptions import ApiException -from corpora_cli.commands.corpus import app +from rich.console import Console +from typer.testing import CliRunner +from corpora_cli.commands.corpus import app runner = CliRunner() @@ -16,7 +16,7 @@ @patch("corpora_cli.commands.corpus.ContextObject") @patch("builtins.open", new_callable=mock_open) def test_init_command( - mock_open_file, mock_context, mock_get_best_collector, mock_path, mock_save_config + mock_open_file, mock_context, mock_get_best_collector, mock_path, mock_save_config, ): """Test the `init` command for basic behavior.""" # Create a real console and capture output in a StringIO buffer @@ -77,7 +77,7 @@ def test_init_command( { "name": "test_repo", "url": "https://github.com/test/repo", - } + }, ) # Ensure `open` was called to write the corpus ID @@ -103,7 +103,7 @@ def test_delete_command(mock_context): assert "Deleting corpus: test_corpus" in output assert "test_corpus deleted" in output mock_context_instance.corpus_api.delete_corpus.assert_called_once_with( - "test_corpus" + "test_corpus", ) @@ -119,7 +119,7 @@ def test_delete_command_corpus_not_found(mock_context): # Use ApiException with a status attribute to simulate 404 response mock_context_instance.corpus_api.delete_corpus.side_effect = ApiException( - status=404 + status=404, ) result = runner.invoke(app, ["delete"], obj=mock_context_instance) diff --git a/py/packages/corpora_cli/commands/test_file.py b/py/packages/corpora_cli/commands/test_file.py index 2d850a1..d94ad7e 100644 --- a/py/packages/corpora_cli/commands/test_file.py +++ b/py/packages/corpora_cli/commands/test_file.py @@ -1,7 +1,8 @@ from io import StringIO from unittest.mock import patch -from typer.testing import CliRunner + from rich.console import Console +from typer.testing import CliRunner from corpora_cli.commands.file import app @@ -40,7 +41,7 @@ def test_remove_command(mock_context): file_id = "test_file_id" result = runner.invoke( - app, ["remove", corpus_id, file_id], obj=mock_context_instance + app, ["remove", corpus_id, file_id], obj=mock_context_instance, ) output = console_output.getvalue() diff --git a/py/packages/corpora_cli/commands/test_split.py b/py/packages/corpora_cli/commands/test_split.py index da04dda..c0f67dc 100644 --- a/py/packages/corpora_cli/commands/test_split.py +++ b/py/packages/corpora_cli/commands/test_split.py @@ -1,7 +1,8 @@ from io import StringIO -from unittest.mock import patch, MagicMock -from typer.testing import CliRunner +from unittest.mock import MagicMock, patch + from rich.console import Console +from typer.testing import CliRunner from corpora_cli.commands.split import app # Adjust if the path is different @@ -62,7 +63,7 @@ def test_list_command(mock_context): # Mock APIs mock_context_instance.file_api.get_file_by_path.return_value = MagicMock( - id="file123" + id="file123", ) mock_context_instance.split_api.list_splits_for_file.return_value = [ MagicMock(order=1, content="This is split one."), diff --git a/py/packages/corpora_cli/commands/workon.py b/py/packages/corpora_cli/commands/workon.py index 61a1e49..c86f79b 100644 --- a/py/packages/corpora_cli/commands/workon.py +++ b/py/packages/corpora_cli/commands/workon.py @@ -1,10 +1,10 @@ from typing import List -from requests import session -import typer -from prompt_toolkit.shortcuts import PromptSession +import typer from corpora_client.models.corpus_file_chat_schema import CorpusFileChatSchema from corpora_client.models.message_schema import MessageSchema +from prompt_toolkit.shortcuts import PromptSession + from corpora_cli.context import ContextObject app = typer.Typer(help="Interactive issue creation CLI") @@ -14,9 +14,7 @@ @app.command() def file(ctx: typer.Context, path: str): - """ - Workon a file in the corpus. - """ + """Workon a file in the corpus.""" c: ContextObject = ctx.obj c.console.print(f"Working on file: {path}", style="bold blue") ext = path.split(".")[-1] @@ -24,7 +22,7 @@ def file(ctx: typer.Context, path: str): # show current file content on disk, load the content from the # CWD and print it with dim try: - with open(path, "r") as f: + with open(path) as f: current_file_content = f.read() if f else "" except FileNotFoundError: current_file_content = "" @@ -41,7 +39,7 @@ def file(ctx: typer.Context, path: str): MessageSchema( role="user", text=f"The original file content was:\n```{ext}\n{current_file_content}```", - ) + ), ) # REPL loop @@ -53,7 +51,10 @@ def file(ctx: typer.Context, path: str): ) if not user_input: - c.console.print("No input provided. Please try again.", style="yellow") + c.console.print( + "No input provided. Please try again.", + style="yellow", + ) continue # Add the user's input as a new message @@ -63,13 +64,13 @@ def file(ctx: typer.Context, path: str): c.console.print("Generating revision...", style="bold blue") # if file doesn't exist, use empty string - with open(".corpora/VOICE.md", "r") as f: + with open(".corpora/VOICE.md") as f: voice = f.read() if f else "" - with open(".corpora/PURPOSE.md", "r") as f: + with open(".corpora/PURPOSE.md") as f: purpose = f.read() if f else "" - with open(".corpora/STRUCTURE.md", "r") as f: + with open(".corpora/STRUCTURE.md") as f: structure = f.read() if f else "" - with open(f".corpora/{ext}/DIRECTIONS.md", "r") as f: + with open(f".corpora/{ext}/DIRECTIONS.md") as f: directions = f.read() if f else "" revision = c.workon_api.file( @@ -81,7 +82,7 @@ def file(ctx: typer.Context, path: str): purpose=purpose, structure=structure, directions=directions, - ) + ), ) c.console.print(f"{revision}", style="dim") c.console.print(f"{path}", style="dim magenta") @@ -92,9 +93,8 @@ def file(ctx: typer.Context, path: str): f.write(revision) c.console.print("File written!", style="green") continue - else: - c.console.print( - "You chose not to write the file. Give more input to revise.", - style="magenta", - ) - continue + c.console.print( + "You chose not to write the file. Give more input to revise.", + style="magenta", + ) + continue diff --git a/py/packages/corpora_cli/config.py b/py/packages/corpora_cli/config.py index bb33fac..a756677 100644 --- a/py/packages/corpora_cli/config.py +++ b/py/packages/corpora_cli/config.py @@ -1,10 +1,11 @@ -from genericpath import exists import os import re -import yaml -import typer +from genericpath import exists from typing import Any, Dict +import typer +import yaml + from corpora_cli.utils.git import get_git_remote_url, get_git_repo_name CONFIG_FILE_PATH = ".corpora.yaml" @@ -14,17 +15,16 @@ # TODO: type the config def load_config() -> Dict[str, Any]: - """ - Load and parse the .corpora.yaml configuration file, substituting + """Load and parse the .corpora.yaml configuration file, substituting any ${VAR_NAME} placeholders with values from environment variables. If the config file is missing, infer defaults from Git. """ try: # Load YAML config - with open(CONFIG_FILE_PATH, "r") as file: + with open(CONFIG_FILE_PATH) as file: config = yaml.safe_load(file) if exists(ID_FILE_PATH): - with open(ID_FILE_PATH, "r") as file: + with open(ID_FILE_PATH) as file: config["id"] = file.read().strip() except FileNotFoundError: # If config file doesn't exist, fall back to Git @@ -53,23 +53,21 @@ def load_config() -> Dict[str, Any]: def save_config(config: Dict[str, Any]) -> None: - """ - Save the given configuration dictionary to .corpora.yaml. + """Save the given configuration dictionary to .corpora.yaml. """ with open(CONFIG_FILE_PATH, "w") as file: yaml.safe_dump(config, file) def substitute_env_variables(config: Any) -> Any: - """ - Recursively substitute ${VAR_NAME} placeholders with environment variables. + """Recursively substitute ${VAR_NAME} placeholders with environment variables. Handles nested dictionaries and lists in the configuration. """ if isinstance(config, dict): return {k: substitute_env_variables(v) for k, v in config.items()} - elif isinstance(config, list): + if isinstance(config, list): return [substitute_env_variables(item) for item in config] - elif isinstance(config, str): + if isinstance(config, str): # Replace ${VAR_NAME} with its environment value, if available return ENV_VAR_PATTERN.sub(lambda match: os.getenv(match.group(1), ""), config) return config # Return non-str types (e.g., int, float) unchanged diff --git a/py/packages/corpora_cli/constants.py b/py/packages/corpora_cli/constants.py index 4cc77d8..0ce1feb 100644 --- a/py/packages/corpora_cli/constants.py +++ b/py/packages/corpora_cli/constants.py @@ -15,7 +15,7 @@ export CORPORA_CLIENT_ID="{your_client_id}" export CORPORA_CLIENT_SECRET="{your_client_secret}" ``` -""" +""", ) CORPUS_EXISTS_MESSAGE = Markdown( @@ -23,5 +23,5 @@ A corpus with this name already exists for this owner. Call `corpus delete` to delete the existing corpus or use a different name. -""" +""", ) diff --git a/py/packages/corpora_cli/context.py b/py/packages/corpora_cli/context.py index 56d5755..bd44b59 100644 --- a/py/packages/corpora_cli/context.py +++ b/py/packages/corpora_cli/context.py @@ -1,8 +1,8 @@ -from typing import Any, Dict from dataclasses import dataclass -from rich.console import Console +from typing import Any, Dict -from corpora_client import CorpusApi, FileApi, SplitApi, PlanApi, WorkonApi +from corpora_client import CorpusApi, FileApi, PlanApi, SplitApi, WorkonApi +from rich.console import Console @dataclass diff --git a/py/packages/corpora_cli/main.py b/py/packages/corpora_cli/main.py index 11cccf4..678cd2a 100755 --- a/py/packages/corpora_cli/main.py +++ b/py/packages/corpora_cli/main.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 from typing import Tuple + +import corpora_client import typer from rich.console import Console from rich.text import Text -import corpora_client -from corpora_cli.commands import corpus, file, split, plan, workon +from corpora_cli.auth import AuthError, AuthResolver +from corpora_cli.commands import corpus, file, plan, split, workon from corpora_cli.config import load_config -from corpora_cli.auth import AuthResolver, AuthError from corpora_cli.constants import NO_AUTHENTICATION_MESSAGE from corpora_cli.context import ContextObject @@ -24,8 +25,7 @@ def get_api_clients( corpora_client.PlanApi, corpora_client.WorkonApi, ]: - """ - Initialize and authenticate API client with given config. + """Initialize and authenticate API client with given config. Returns an authenticated CorporaApi instance. """ try: @@ -42,7 +42,7 @@ def get_api_clients( client_config = corpora_client.Configuration() # TODO: deploy and default to the main production server? client_config.host = config.get("server", {}).get( - "base_url", "http://corpora-app:8877" + "base_url", "http://corpora-app:8877", ) client_config.access_token = auth_token return ( @@ -58,7 +58,7 @@ def get_api_clients( def main(ctx: typer.Context): """Main entry point. Sets up configuration and API client.""" corpus_api, files_api, split_api, plan_api, workon_api = get_api_clients( - load_config() + load_config(), ) config = load_config() @@ -79,7 +79,7 @@ def main(ctx: typer.Context): app.add_typer(split.app, name="split", help="Commands for split operations") app.add_typer(plan.app, name="plan", help="Commands for plan operations") app.add_typer( - workon.app, name="workon", help="Commands for working on files in the corpus" + workon.app, name="workon", help="Commands for working on files in the corpus", ) if __name__ == "__main__": diff --git a/py/packages/corpora_cli/test_auth.py b/py/packages/corpora_cli/test_auth.py index 23f3dc7..aae76ca 100644 --- a/py/packages/corpora_cli/test_auth.py +++ b/py/packages/corpora_cli/test_auth.py @@ -1,7 +1,9 @@ import os +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock -from corpora_cli.auth import AuthResolver, AuthError + +from corpora_cli.auth import AuthError, AuthResolver @pytest.fixture @@ -18,7 +20,7 @@ def test_resolve_auth_success_with_env_credential(auth_resolver): # Mock environment variable CREDENTIAL with patch.dict(os.environ, {"CREDENTIAL": "encodedcredential"}): with patch.object( - auth_resolver, "_request_token_with_basic_auth", return_value="test_token" + auth_resolver, "_request_token_with_basic_auth", return_value="test_token", ) as mock_request: token = auth_resolver.resolve_auth() assert token == "test_token" @@ -32,11 +34,11 @@ def test_resolve_auth_success_with_client_credentials(auth_resolver): {"CORPORA_CLIENT_ID": "test_id", "CORPORA_CLIENT_SECRET": "test_secret"}, ): with patch.object( - auth_resolver, "_request_token_with_basic_auth", return_value="test_token" + auth_resolver, "_request_token_with_basic_auth", return_value="test_token", ) as mock_request: token = auth_resolver.resolve_auth() encoded_credentials = auth_resolver._encode_credentials( - "test_id", "test_secret" + "test_id", "test_secret", ) assert token == "test_token" mock_request.assert_called_once_with(encoded_credentials) diff --git a/py/packages/corpora_cli/test_config.py b/py/packages/corpora_cli/test_config.py index 8de4fa8..30620d0 100644 --- a/py/packages/corpora_cli/test_config.py +++ b/py/packages/corpora_cli/test_config.py @@ -1,8 +1,8 @@ import os -import yaml +from unittest.mock import mock_open, patch + import pytest -from unittest.mock import patch, mock_open -import typer +import yaml from corpora_cli.config import load_config, substitute_env_variables @@ -40,7 +40,9 @@ def mocked_env(): @patch("builtins.open", new_callable=mock_open) @patch("yaml.safe_load") -def test_load_config_success(mock_yaml_load, mock_file_open, yaml_content, mocked_env): +def test_load_config_success( + mock_yaml_load, mock_file_open, yaml_content, mocked_env, +): """Test load_config with successful loading and env substitution.""" # Set up mock for yaml.safe_load to return the parsed YAML structure mock_yaml_load.return_value = { @@ -73,7 +75,9 @@ def test_load_config_missing_file(mock_file_open): "corpora_cli.config.get_git_remote_url", return_value="https://example.com/test-repo", ): - with patch("corpora_cli.config.get_git_repo_name", return_value="test-repo"): + with patch( + "corpora_cli.config.get_git_repo_name", return_value="test-repo", + ): config = load_config() # Assert defaults are set @@ -85,15 +89,19 @@ def test_load_config_missing_file(mock_file_open): def test_load_config_invalid_yaml(mock_file_open): """Test load_config raises a yaml.YAMLError on YAML parsing error.""" # Simulate invalid YAML content in the file - mock_file_open.return_value.__enter__.return_value = "invalid: yaml: content" + mock_file_open.return_value.__enter__.return_value = ( + "invalid: yaml: content" + ) # Mock yaml.safe_load to raise a YAMLError - with patch("yaml.safe_load", side_effect=yaml.YAMLError("YAML parsing error")): + with patch( + "yaml.safe_load", side_effect=yaml.YAMLError("YAML parsing error"), + ): with pytest.raises(yaml.YAMLError, match="YAML parsing error"): load_config() # Ensure that the file was attempted to be opened - mock_file_open.assert_called_once_with(".corpora.yaml", "r") + mock_file_open.assert_called_once_with(".corpora.yaml") def test_substitute_env_variables(mocked_env): diff --git a/py/packages/corpora_cli/test_main.py b/py/packages/corpora_cli/test_main.py index 212da44..638ed6e 100644 --- a/py/packages/corpora_cli/test_main.py +++ b/py/packages/corpora_cli/test_main.py @@ -1,12 +1,13 @@ +from unittest.mock import Mock, patch + import pytest import typer -from unittest.mock import patch, Mock -from typer.testing import CliRunner from rich.text import Text +from typer.testing import CliRunner -from corpora_cli.main import get_api_clients, main -from corpora_cli.constants import NO_AUTHENTICATION_MESSAGE from corpora_cli.auth import AuthError +from corpora_cli.constants import NO_AUTHENTICATION_MESSAGE +from corpora_cli.main import get_api_clients, main runner = CliRunner() @@ -28,7 +29,7 @@ def mock_token(): @patch("corpora_cli.auth.AuthResolver.resolve_auth") def test_get_api_clients_successful_authentication( - mock_resolve_auth, mock_config, mock_token + mock_resolve_auth, mock_config, mock_token, ): """Test get_api_clients with successful authentication.""" # Mock the resolve_auth method to return the token @@ -49,7 +50,7 @@ def test_get_api_clients_successful_authentication( @patch("corpora_cli.main.Console") @patch("corpora_cli.main.AuthResolver") def test_get_api_clients_authentication_failure( - mock_auth_resolver, mock_console, mock_config + mock_auth_resolver, mock_console, mock_config, ): """Test get_api_clients with authentication failure.""" # Mock AuthResolver to raise an AuthError @@ -60,10 +61,10 @@ def test_get_api_clients_authentication_failure( # Verify console error message and exit code mock_console.return_value.print.assert_any_call( - Text("Auth failed", style="bold red") + Text("Auth failed", style="bold red"), ) mock_console.return_value.print.assert_any_call( - NO_AUTHENTICATION_MESSAGE, style="yellow" + NO_AUTHENTICATION_MESSAGE, style="yellow", ) # Check if typer.Exit was raised assert exc_info.type == typer.Exit diff --git a/py/packages/corpora_cli/utils/__init__.py b/py/packages/corpora_cli/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py/packages/corpora_cli/utils/collectors.py b/py/packages/corpora_cli/utils/collectors.py index 87e72fd..76cd321 100644 --- a/py/packages/corpora_cli/utils/collectors.py +++ b/py/packages/corpora_cli/utils/collectors.py @@ -1,14 +1,13 @@ import io -import tarfile -import subprocess import shutil +import subprocess +import tarfile from pathlib import Path from typing import Dict, List, Optional class CorpusFileCollector: - """ - Abstract base class for collecting corpus files. + """Abstract base class for collecting corpus files. Implementations should define how to collect files. """ @@ -16,8 +15,7 @@ def collect_files(self) -> List[Path]: raise NotImplementedError("Must implement collect_files method") def create_tarball(self, files: List[Path], repo_root: Path) -> io.BytesIO: - """ - Creates a tar.gz archive in memory for a list of files. + """Creates a tar.gz archive in memory for a list of files. """ tar_buffer = io.BytesIO() with tarfile.open(fileobj=tar_buffer, mode="w:gz") as tar: @@ -65,10 +63,9 @@ def is_git_repository(repo_root: Path) -> bool: def get_best_collector( - repo_root: Optional[Path] = None, config: Optional[Dict] = None + repo_root: Optional[Path] = None, config: Optional[Dict] = None, ) -> "CorpusFileCollector": - """ - Factory function to get the most appropriate file collector based on provided arguments. + """Factory function to get the most appropriate file collector based on provided arguments. Args: repo_root (Optional[Path]): The root path of the repository (if any). @@ -79,12 +76,13 @@ def get_best_collector( Raises: ValueError: If neither repo_root nor config is suitable for any collector. + """ if repo_root and is_git_installed() and is_git_repository(repo_root): return GitCorpusFileCollector(repo_root) - elif config: + if config: return ConfigCorpusFileCollector(config) raise ValueError( - "Unable to determine an appropriate file collector. Please provide a valid `repo_root` for a Git repository or a `config`." + "Unable to determine an appropriate file collector. Please provide a valid `repo_root` for a Git repository or a `config`.", ) diff --git a/py/packages/corpora_cli/utils/git.py b/py/packages/corpora_cli/utils/git.py index 4f52536..ef4972c 100644 --- a/py/packages/corpora_cli/utils/git.py +++ b/py/packages/corpora_cli/utils/git.py @@ -1,14 +1,11 @@ import subprocess -from httpx import get - def run_command(command: list) -> str: - """ - Run a command and return its output as a string. + """Run a command and return its output as a string. """ result = subprocess.run( - command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True, ) return result.stdout.strip() @@ -25,8 +22,7 @@ def get_file_hash(path: str) -> str: def get_git_remote_url() -> str: - """ - Retrieve the main remote URL of the current Git repository. + """Retrieve the main remote URL of the current Git repository. """ try: result = subprocess.run( @@ -42,8 +38,7 @@ def get_git_remote_url() -> str: def get_git_repo_name(url: str) -> str: - """ - Extract the repository name from a Git remote URL. + """Extract the repository name from a Git remote URL. """ if not url: return "" diff --git a/py/packages/corpora_cli/utils/test_collectors.py b/py/packages/corpora_cli/utils/test_collectors.py index a6133ee..0f2c0ee 100644 --- a/py/packages/corpora_cli/utils/test_collectors.py +++ b/py/packages/corpora_cli/utils/test_collectors.py @@ -1,32 +1,36 @@ import io import tarfile -from pathlib import Path import unittest -from unittest.mock import patch, MagicMock +from pathlib import Path +from unittest.mock import MagicMock, patch + from corpora_cli.utils.collectors import ( + ConfigCorpusFileCollector, CorpusFileCollector, GitCorpusFileCollector, - ConfigCorpusFileCollector, + get_best_collector, is_git_installed, is_git_repository, - get_best_collector, ) class TestCorpusFileCollector(unittest.TestCase): def setUp(self): self.repo_root = Path("/fake/repo") - self.files = [self.repo_root / "file1.txt", self.repo_root / "file2.txt"] + self.files = [ + self.repo_root / "file1.txt", + self.repo_root / "file2.txt", + ] @patch( - "pathlib.Path.exists", return_value=True + "pathlib.Path.exists", + return_value=True, ) # Mock Path.exists to pretend files exist @patch( - "tarfile.TarFile.add" + "tarfile.TarFile.add", ) # Mock tarfile.TarFile.add to simulate adding files without real I/O def test_create_tarball(self, mock_add, mock_exists): """Test that create_tarball creates a tar.gz archive in memory without needing actual files.""" - # Create a CorpusFileCollector instance and call create_tarball collector = CorpusFileCollector() tar_buffer = collector.create_tarball(self.files, self.repo_root) @@ -38,7 +42,11 @@ def test_create_tarball(self, mock_add, mock_exists): # Patch the TarFile.open context to mock entries in the tarball with tarfile.open(fileobj=tar_buffer, mode="r:gz") as tar: # Instead of actual files, we mock the members of the tar archive - with patch.object(tar, "getnames", return_value=["file1.txt", "file2.txt"]): + with patch.object( + tar, + "getnames", + return_value=["file1.txt", "file2.txt"], + ): tar_members = tar.getnames() self.assertIn("file1.txt", tar_members) self.assertIn("file2.txt", tar_members) @@ -70,7 +78,10 @@ def test_collect_files(self, mock_run): ) # Check that the returned files match expected output - expected_files = [self.repo_root / "file1.txt", self.repo_root / "file2.txt"] + expected_files = [ + self.repo_root / "file1.txt", + self.repo_root / "file2.txt", + ] self.assertEqual(files, expected_files) diff --git a/py/packages/corpora_client/api/__init__.py b/py/packages/corpora_client/api/__init__.py index 4d43257..16f2c1b 100644 --- a/py/packages/corpora_client/api/__init__.py +++ b/py/packages/corpora_client/api/__init__.py @@ -6,3 +6,4 @@ from corpora_client.api.plan_api import PlanApi from corpora_client.api.split_api import SplitApi from corpora_client.api.workon_api import WorkonApi + diff --git a/py/packages/corpora_client/api/corpus_api.py b/py/packages/corpora_client/api/corpus_api.py index fadbb88..82ea7e5 100644 --- a/py/packages/corpora_client/api/corpus_api.py +++ b/py/packages/corpora_client/api/corpus_api.py @@ -38,6 +38,7 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_call def chat( self, @@ -46,8 +47,9 @@ def chat( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -80,22 +82,23 @@ def chat( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._chat_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -103,6 +106,7 @@ def chat( response_types_map=_response_types_map, ).data + @validate_call def chat_with_http_info( self, @@ -111,8 +115,9 @@ def chat_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -145,22 +150,23 @@ def chat_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._chat_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -168,6 +174,7 @@ def chat_with_http_info( response_types_map=_response_types_map, ) + @validate_call def chat_without_preload_content( self, @@ -176,8 +183,9 @@ def chat_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -210,25 +218,27 @@ def chat_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._chat_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _chat_serialize( self, corpus_chat_schema, @@ -240,7 +250,8 @@ def _chat_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -259,28 +270,37 @@ def _chat_serialize( if corpus_chat_schema is not None: _body_params = corpus_chat_schema + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["application/json"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/corpus/chat", + method='POST', + resource_path='/api/corpora/corpus/chat', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -290,9 +310,12 @@ def _chat_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def create_corpus( self, @@ -303,8 +326,9 @@ def create_corpus( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -341,7 +365,7 @@ def create_corpus( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_corpus_serialize( name=name, @@ -350,16 +374,17 @@ def create_corpus( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "CorpusResponseSchema", - "400": "str", - "409": "str", + '201': "CorpusResponseSchema", + '400': "str", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -367,6 +392,7 @@ def create_corpus( response_types_map=_response_types_map, ).data + @validate_call def create_corpus_with_http_info( self, @@ -377,8 +403,9 @@ def create_corpus_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -415,7 +442,7 @@ def create_corpus_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_corpus_serialize( name=name, @@ -424,16 +451,17 @@ def create_corpus_with_http_info( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "CorpusResponseSchema", - "400": "str", - "409": "str", + '201': "CorpusResponseSchema", + '400': "str", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -441,6 +469,7 @@ def create_corpus_with_http_info( response_types_map=_response_types_map, ) + @validate_call def create_corpus_without_preload_content( self, @@ -451,8 +480,9 @@ def create_corpus_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -489,7 +519,7 @@ def create_corpus_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_corpus_serialize( name=name, @@ -498,19 +528,21 @@ def create_corpus_without_preload_content( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "CorpusResponseSchema", - "400": "str", - "409": "str", + '201': "CorpusResponseSchema", + '400': "str", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _create_corpus_serialize( self, name, @@ -524,7 +556,8 @@ def _create_corpus_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -540,35 +573,44 @@ def _create_corpus_serialize( # process the header parameters # process the form parameters if name is not None: - _form_params.append(("name", name)) + _form_params.append(('name', name)) if url is not None: - _form_params.append(("url", url)) + _form_params.append(('url', url)) if tarball is not None: - _files["tarball"] = tarball + _files['tarball'] = tarball # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["multipart/form-data"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'multipart/form-data' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/corpus", + method='POST', + resource_path='/api/corpora/corpus', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -578,9 +620,12 @@ def _create_corpus_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def delete_corpus( self, @@ -589,8 +634,9 @@ def delete_corpus( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -623,22 +669,23 @@ def delete_corpus( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_corpus_serialize( corpus_name=corpus_name, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "204": "str", - "404": "str", + '204': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -646,6 +693,7 @@ def delete_corpus( response_types_map=_response_types_map, ).data + @validate_call def delete_corpus_with_http_info( self, @@ -654,8 +702,9 @@ def delete_corpus_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -688,22 +737,23 @@ def delete_corpus_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_corpus_serialize( corpus_name=corpus_name, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "204": "str", - "404": "str", + '204': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -711,6 +761,7 @@ def delete_corpus_with_http_info( response_types_map=_response_types_map, ) + @validate_call def delete_corpus_without_preload_content( self, @@ -719,8 +770,9 @@ def delete_corpus_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -753,25 +805,27 @@ def delete_corpus_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_corpus_serialize( corpus_name=corpus_name, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "204": "str", - "404": "str", + '204': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _delete_corpus_serialize( self, corpus_name, @@ -783,7 +837,8 @@ def _delete_corpus_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -797,25 +852,31 @@ def _delete_corpus_serialize( # process the path parameters # process the query parameters if corpus_name is not None: - - _query_params.append(("corpus_name", corpus_name)) - + + _query_params.append(('corpus_name', corpus_name)) + # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="DELETE", - resource_path="/api/corpora/corpus", + method='DELETE', + resource_path='/api/corpora/corpus', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -825,9 +886,12 @@ def _delete_corpus_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def get_corpus( self, @@ -836,8 +900,9 @@ def get_corpus( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -870,21 +935,22 @@ def get_corpus( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_corpus_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "CorpusResponseSchema", + '200': "CorpusResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -892,6 +958,7 @@ def get_corpus( response_types_map=_response_types_map, ).data + @validate_call def get_corpus_with_http_info( self, @@ -900,8 +967,9 @@ def get_corpus_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -934,21 +1002,22 @@ def get_corpus_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_corpus_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "CorpusResponseSchema", + '200': "CorpusResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -956,6 +1025,7 @@ def get_corpus_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_corpus_without_preload_content( self, @@ -964,8 +1034,9 @@ def get_corpus_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -998,24 +1069,26 @@ def get_corpus_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_corpus_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "CorpusResponseSchema", + '200': "CorpusResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_corpus_serialize( self, corpus_id, @@ -1027,7 +1100,8 @@ def _get_corpus_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -1040,24 +1114,30 @@ def _get_corpus_serialize( # process the path parameters if corpus_id is not None: - _path_params["corpus_id"] = corpus_id + _path_params['corpus_id'] = corpus_id # process the query parameters # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/corpus/{corpus_id}", + method='GET', + resource_path='/api/corpora/corpus/{corpus_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -1067,9 +1147,12 @@ def _get_corpus_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def get_file_hashes( self, @@ -1078,8 +1161,9 @@ def get_file_hashes( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1112,21 +1196,22 @@ def get_file_hashes( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_hashes_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Dict[str, str]", + '200': "Dict[str, str]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1134,6 +1219,7 @@ def get_file_hashes( response_types_map=_response_types_map, ).data + @validate_call def get_file_hashes_with_http_info( self, @@ -1142,8 +1228,9 @@ def get_file_hashes_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1176,21 +1263,22 @@ def get_file_hashes_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_hashes_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Dict[str, str]", + '200': "Dict[str, str]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1198,6 +1286,7 @@ def get_file_hashes_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_file_hashes_without_preload_content( self, @@ -1206,8 +1295,9 @@ def get_file_hashes_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1240,24 +1330,26 @@ def get_file_hashes_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_hashes_serialize( corpus_id=corpus_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Dict[str, str]", + '200': "Dict[str, str]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_file_hashes_serialize( self, corpus_id, @@ -1269,7 +1361,8 @@ def _get_file_hashes_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -1282,24 +1375,30 @@ def _get_file_hashes_serialize( # process the path parameters if corpus_id is not None: - _path_params["corpus_id"] = corpus_id + _path_params['corpus_id'] = corpus_id # process the query parameters # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/corpus/{corpus_id}/files", + method='GET', + resource_path='/api/corpora/corpus/{corpus_id}/files', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -1309,9 +1408,12 @@ def _get_file_hashes_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def list_corpora( self, @@ -1319,8 +1421,9 @@ def list_corpora( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1351,20 +1454,21 @@ def list_corpora( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_corpora_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[CorpusResponseSchema]", + '200': "List[CorpusResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1372,6 +1476,7 @@ def list_corpora( response_types_map=_response_types_map, ).data + @validate_call def list_corpora_with_http_info( self, @@ -1379,8 +1484,9 @@ def list_corpora_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1411,20 +1517,21 @@ def list_corpora_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_corpora_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[CorpusResponseSchema]", + '200': "List[CorpusResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1432,6 +1539,7 @@ def list_corpora_with_http_info( response_types_map=_response_types_map, ) + @validate_call def list_corpora_without_preload_content( self, @@ -1439,8 +1547,9 @@ def list_corpora_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1471,23 +1580,25 @@ def list_corpora_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_corpora_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[CorpusResponseSchema]", + '200': "List[CorpusResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _list_corpora_serialize( self, _request_auth, @@ -1498,7 +1609,8 @@ def _list_corpora_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -1515,18 +1627,24 @@ def _list_corpora_serialize( # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/corpus", + method='GET', + resource_path='/api/corpora/corpus', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -1536,9 +1654,12 @@ def _list_corpora_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def update_files( self, @@ -1549,8 +1670,9 @@ def update_files( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1587,7 +1709,7 @@ def update_files( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_files_serialize( corpus_id=corpus_id, @@ -1596,15 +1718,16 @@ def update_files( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1612,6 +1735,7 @@ def update_files( response_types_map=_response_types_map, ).data + @validate_call def update_files_with_http_info( self, @@ -1622,8 +1746,9 @@ def update_files_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1660,7 +1785,7 @@ def update_files_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_files_serialize( corpus_id=corpus_id, @@ -1669,15 +1794,16 @@ def update_files_with_http_info( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -1685,6 +1811,7 @@ def update_files_with_http_info( response_types_map=_response_types_map, ) + @validate_call def update_files_without_preload_content( self, @@ -1695,8 +1822,9 @@ def update_files_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1733,7 +1861,7 @@ def update_files_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_files_serialize( corpus_id=corpus_id, @@ -1742,18 +1870,20 @@ def update_files_without_preload_content( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", - "404": "str", + '200': "str", + '404': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _update_files_serialize( self, corpus_id, @@ -1768,7 +1898,7 @@ def _update_files_serialize( _host = None _collection_formats: Dict[str, str] = { - "delete_files": "csv", + 'delete_files': 'csv', } _path_params: Dict[str, str] = {} @@ -1782,38 +1912,47 @@ def _update_files_serialize( # process the path parameters if corpus_id is not None: - _path_params["corpus_id"] = corpus_id + _path_params['corpus_id'] = corpus_id # process the query parameters # process the header parameters # process the form parameters if delete_files is not None: - _form_params.append(("delete_files", delete_files)) + _form_params.append(('delete_files', delete_files)) if tarball is not None: - _files["tarball"] = tarball + _files['tarball'] = tarball # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["multipart/form-data"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'multipart/form-data' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/corpus/{corpus_id}/files", + method='POST', + resource_path='/api/corpora/corpus/{corpus_id}/files', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -1823,5 +1962,7 @@ def _update_files_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + diff --git a/py/packages/corpora_client/api/file_api.py b/py/packages/corpora_client/api/file_api.py index bea2d6f..844dea0 100644 --- a/py/packages/corpora_client/api/file_api.py +++ b/py/packages/corpora_client/api/file_api.py @@ -38,6 +38,7 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_call def create_file( self, @@ -46,8 +47,9 @@ def create_file( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -80,22 +82,23 @@ def create_file( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_file_serialize( file_schema=file_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "FileResponseSchema", - "409": "str", + '201': "FileResponseSchema", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -103,6 +106,7 @@ def create_file( response_types_map=_response_types_map, ).data + @validate_call def create_file_with_http_info( self, @@ -111,8 +115,9 @@ def create_file_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -145,22 +150,23 @@ def create_file_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_file_serialize( file_schema=file_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "FileResponseSchema", - "409": "str", + '201': "FileResponseSchema", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -168,6 +174,7 @@ def create_file_with_http_info( response_types_map=_response_types_map, ) + @validate_call def create_file_without_preload_content( self, @@ -176,8 +183,9 @@ def create_file_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -210,25 +218,27 @@ def create_file_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._create_file_serialize( file_schema=file_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "201": "FileResponseSchema", - "409": "str", + '201': "FileResponseSchema", + '409': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _create_file_serialize( self, file_schema, @@ -240,7 +250,8 @@ def _create_file_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -259,28 +270,37 @@ def _create_file_serialize( if file_schema is not None: _body_params = file_schema + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["application/json"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/file", + method='POST', + resource_path='/api/corpora/file', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -290,9 +310,12 @@ def _create_file_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def get_file( self, @@ -301,8 +324,9 @@ def get_file( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -335,21 +359,22 @@ def get_file( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -357,6 +382,7 @@ def get_file( response_types_map=_response_types_map, ).data + @validate_call def get_file_with_http_info( self, @@ -365,8 +391,9 @@ def get_file_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -399,21 +426,22 @@ def get_file_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -421,6 +449,7 @@ def get_file_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_file_without_preload_content( self, @@ -429,8 +458,9 @@ def get_file_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -463,24 +493,26 @@ def get_file_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_file_serialize( self, file_id, @@ -492,7 +524,8 @@ def _get_file_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -505,24 +538,30 @@ def _get_file_serialize( # process the path parameters if file_id is not None: - _path_params["file_id"] = file_id + _path_params['file_id'] = file_id # process the query parameters # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/file/{file_id}", + method='GET', + resource_path='/api/corpora/file/{file_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -532,9 +571,12 @@ def _get_file_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def get_file_by_path( self, @@ -544,8 +586,9 @@ def get_file_by_path( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -580,7 +623,7 @@ def get_file_by_path( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_by_path_serialize( corpus_id=corpus_id, @@ -588,14 +631,15 @@ def get_file_by_path( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -603,6 +647,7 @@ def get_file_by_path( response_types_map=_response_types_map, ).data + @validate_call def get_file_by_path_with_http_info( self, @@ -612,8 +657,9 @@ def get_file_by_path_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -648,7 +694,7 @@ def get_file_by_path_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_by_path_serialize( corpus_id=corpus_id, @@ -656,14 +702,15 @@ def get_file_by_path_with_http_info( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -671,6 +718,7 @@ def get_file_by_path_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_file_by_path_without_preload_content( self, @@ -680,8 +728,9 @@ def get_file_by_path_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -716,7 +765,7 @@ def get_file_by_path_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_file_by_path_serialize( corpus_id=corpus_id, @@ -724,17 +773,19 @@ def get_file_by_path_without_preload_content( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "FileResponseSchema", + '200': "FileResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_file_by_path_serialize( self, corpus_id, @@ -747,7 +798,8 @@ def _get_file_by_path_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -760,28 +812,34 @@ def _get_file_by_path_serialize( # process the path parameters if corpus_id is not None: - _path_params["corpus_id"] = corpus_id + _path_params['corpus_id'] = corpus_id # process the query parameters if path is not None: - - _query_params.append(("path", path)) - + + _query_params.append(('path', path)) + # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/file/corpus/{corpus_id}", + method='GET', + resource_path='/api/corpora/file/corpus/{corpus_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -791,5 +849,7 @@ def _get_file_by_path_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + diff --git a/py/packages/corpora_client/api/plan_api.py b/py/packages/corpora_client/api/plan_api.py index d1f425b..1898d60 100644 --- a/py/packages/corpora_client/api/plan_api.py +++ b/py/packages/corpora_client/api/plan_api.py @@ -36,6 +36,7 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_call def get_issue( self, @@ -44,8 +45,9 @@ def get_issue( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -77,21 +79,22 @@ def get_issue( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_issue_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "IssueSchema", + '200': "IssueSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -99,6 +102,7 @@ def get_issue( response_types_map=_response_types_map, ).data + @validate_call def get_issue_with_http_info( self, @@ -107,8 +111,9 @@ def get_issue_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -140,21 +145,22 @@ def get_issue_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_issue_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "IssueSchema", + '200': "IssueSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -162,6 +168,7 @@ def get_issue_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_issue_without_preload_content( self, @@ -170,8 +177,9 @@ def get_issue_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -203,24 +211,26 @@ def get_issue_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_issue_serialize( corpus_chat_schema=corpus_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "IssueSchema", + '200': "IssueSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_issue_serialize( self, corpus_chat_schema, @@ -232,7 +242,8 @@ def _get_issue_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -251,28 +262,37 @@ def _get_issue_serialize( if corpus_chat_schema is not None: _body_params = corpus_chat_schema + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["application/json"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/plan/issue", + method='POST', + resource_path='/api/corpora/plan/issue', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -282,5 +302,7 @@ def _get_issue_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + diff --git a/py/packages/corpora_client/api/split_api.py b/py/packages/corpora_client/api/split_api.py index 60d5359..c4a3e4d 100644 --- a/py/packages/corpora_client/api/split_api.py +++ b/py/packages/corpora_client/api/split_api.py @@ -38,6 +38,7 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_call def get_split( self, @@ -46,8 +47,9 @@ def get_split( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -80,21 +82,22 @@ def get_split( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_split_serialize( split_id=split_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "SplitResponseSchema", + '200': "SplitResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -102,6 +105,7 @@ def get_split( response_types_map=_response_types_map, ).data + @validate_call def get_split_with_http_info( self, @@ -110,8 +114,9 @@ def get_split_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -144,21 +149,22 @@ def get_split_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_split_serialize( split_id=split_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "SplitResponseSchema", + '200': "SplitResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -166,6 +172,7 @@ def get_split_with_http_info( response_types_map=_response_types_map, ) + @validate_call def get_split_without_preload_content( self, @@ -174,8 +181,9 @@ def get_split_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -208,24 +216,26 @@ def get_split_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_split_serialize( split_id=split_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "SplitResponseSchema", + '200': "SplitResponseSchema", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _get_split_serialize( self, split_id, @@ -237,7 +247,8 @@ def _get_split_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -250,24 +261,30 @@ def _get_split_serialize( # process the path parameters if split_id is not None: - _path_params["split_id"] = split_id + _path_params['split_id'] = split_id # process the query parameters # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/split/{split_id}", + method='GET', + resource_path='/api/corpora/split/{split_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -277,9 +294,12 @@ def _get_split_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def list_splits_for_file( self, @@ -288,8 +308,9 @@ def list_splits_for_file( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -322,21 +343,22 @@ def list_splits_for_file( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_splits_for_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -344,6 +366,7 @@ def list_splits_for_file( response_types_map=_response_types_map, ).data + @validate_call def list_splits_for_file_with_http_info( self, @@ -352,8 +375,9 @@ def list_splits_for_file_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -386,21 +410,22 @@ def list_splits_for_file_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_splits_for_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -408,6 +433,7 @@ def list_splits_for_file_with_http_info( response_types_map=_response_types_map, ) + @validate_call def list_splits_for_file_without_preload_content( self, @@ -416,8 +442,9 @@ def list_splits_for_file_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -450,24 +477,26 @@ def list_splits_for_file_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._list_splits_for_file_serialize( file_id=file_id, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _list_splits_for_file_serialize( self, file_id, @@ -479,7 +508,8 @@ def _list_splits_for_file_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -492,24 +522,30 @@ def _list_splits_for_file_serialize( # process the path parameters if file_id is not None: - _path_params["file_id"] = file_id + _path_params['file_id'] = file_id # process the query parameters # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) + # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="GET", - resource_path="/api/corpora/split/file/{file_id}", + method='GET', + resource_path='/api/corpora/split/file/{file_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -519,9 +555,12 @@ def _list_splits_for_file_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + + @validate_call def vector_search( self, @@ -530,8 +569,9 @@ def vector_search( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -564,21 +604,22 @@ def vector_search( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._vector_search_serialize( split_vector_search_schema=split_vector_search_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -586,6 +627,7 @@ def vector_search( response_types_map=_response_types_map, ).data + @validate_call def vector_search_with_http_info( self, @@ -594,8 +636,9 @@ def vector_search_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -628,21 +671,22 @@ def vector_search_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._vector_search_serialize( split_vector_search_schema=split_vector_search_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -650,6 +694,7 @@ def vector_search_with_http_info( response_types_map=_response_types_map, ) + @validate_call def vector_search_without_preload_content( self, @@ -658,8 +703,9 @@ def vector_search_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -692,24 +738,26 @@ def vector_search_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._vector_search_serialize( split_vector_search_schema=split_vector_search_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "List[SplitResponseSchema]", + '200': "List[SplitResponseSchema]", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _vector_search_serialize( self, split_vector_search_schema, @@ -721,7 +769,8 @@ def _vector_search_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -740,28 +789,37 @@ def _vector_search_serialize( if split_vector_search_schema is not None: _body_params = split_vector_search_schema + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["application/json"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/split/search", + method='POST', + resource_path='/api/corpora/split/search', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -771,5 +829,7 @@ def _vector_search_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + diff --git a/py/packages/corpora_client/api/workon_api.py b/py/packages/corpora_client/api/workon_api.py index ade807d..e679e96 100644 --- a/py/packages/corpora_client/api/workon_api.py +++ b/py/packages/corpora_client/api/workon_api.py @@ -36,6 +36,7 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_call def file( self, @@ -44,8 +45,9 @@ def file( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -77,21 +79,22 @@ def file( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._file_serialize( corpus_file_chat_schema=corpus_file_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", + '200': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -99,6 +102,7 @@ def file( response_types_map=_response_types_map, ).data + @validate_call def file_with_http_info( self, @@ -107,8 +111,9 @@ def file_with_http_info( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -140,21 +145,22 @@ def file_with_http_info( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._file_serialize( corpus_file_chat_schema=corpus_file_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", + '200': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) response_data.read() return self.api_client.response_deserialize( @@ -162,6 +168,7 @@ def file_with_http_info( response_types_map=_response_types_map, ) + @validate_call def file_without_preload_content( self, @@ -170,8 +177,9 @@ def file_without_preload_content( None, Annotated[StrictFloat, Field(gt=0)], Tuple[ - Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] - ], + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[Dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -203,24 +211,26 @@ def file_without_preload_content( in the spec for a single request. :type _host_index: int, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._file_serialize( corpus_file_chat_schema=corpus_file_chat_schema, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, - _host_index=_host_index, + _host_index=_host_index ) _response_types_map: Dict[str, Optional[str]] = { - "200": "str", + '200': "str", } response_data = self.api_client.call_api( - *_param, _request_timeout=_request_timeout + *_param, + _request_timeout=_request_timeout ) return response_data.response + def _file_serialize( self, corpus_file_chat_schema, @@ -232,7 +242,8 @@ def _file_serialize( _host = None - _collection_formats: Dict[str, str] = {} + _collection_formats: Dict[str, str] = { + } _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] @@ -251,28 +262,37 @@ def _file_serialize( if corpus_file_chat_schema is not None: _body_params = corpus_file_chat_schema + # set the HTTP header `Accept` - if "Accept" not in _header_params: - _header_params["Accept"] = self.api_client.select_header_accept( - ["application/json"] + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] ) # set the HTTP header `Content-Type` if _content_type: - _header_params["Content-Type"] = _content_type + _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ["application/json"] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: - _header_params["Content-Type"] = _default_content_type + _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: List[str] = ["BearerAuth"] + _auth_settings: List[str] = [ + 'BearerAuth' + ] return self.api_client.param_serialize( - method="POST", - resource_path="/api/corpora/workon/file", + method='POST', + resource_path='/api/corpora/workon/file', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -282,5 +302,7 @@ def _file_serialize( auth_settings=_auth_settings, collection_formats=_collection_formats, _host=_host, - _request_auth=_request_auth, + _request_auth=_request_auth ) + + diff --git a/py/packages/corpora_client/api_client.py b/py/packages/corpora_client/api_client.py index 3d0fa85..e285ecb 100644 --- a/py/packages/corpora_client/api_client.py +++ b/py/packages/corpora_client/api_client.py @@ -37,12 +37,11 @@ UnauthorizedException, ForbiddenException, NotFoundException, - ServiceException, + ServiceException ) RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]] - class ApiClient: """Generic API client for OpenAPI client library builds. @@ -61,20 +60,24 @@ class ApiClient: PRIMITIVE_TYPES = (float, bool, bytes, str, int) NATIVE_TYPES_MAPPING = { - "int": int, - "long": int, # TODO remove as only py3 is supported? - "float": float, - "str": str, - "bool": bool, - "date": datetime.date, - "datetime": datetime.datetime, - "decimal": decimal.Decimal, - "object": object, + 'int': int, + 'long': int, # TODO remove as only py3 is supported? + 'float': float, + 'str': str, + 'bool': bool, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'decimal': decimal.Decimal, + 'object': object, } _pool = None def __init__( - self, configuration=None, header_name=None, header_value=None, cookie=None + self, + configuration=None, + header_name=None, + header_value=None, + cookie=None ) -> None: # use default configuration if none is provided if configuration is None: @@ -87,7 +90,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = "OpenAPI-Generator/1.0.0/python" + self.user_agent = 'OpenAPI-Generator/1.0.0/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): @@ -99,15 +102,16 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers["User-Agent"] + return self.default_headers['User-Agent'] @user_agent.setter def user_agent(self, value): - self.default_headers["User-Agent"] = value + self.default_headers['User-Agent'] = value def set_default_header(self, header_name, header_value): self.default_headers[header_name] = header_value + _default = None @classmethod @@ -143,12 +147,12 @@ def param_serialize( header_params=None, body=None, post_params=None, - files=None, - auth_settings=None, + files=None, auth_settings=None, collection_formats=None, _host=None, - _request_auth=None, + _request_auth=None ) -> RequestSerialized: + """Builds the HTTP request params needed by the request. :param method: Method to call. :param resource_path: Path to method endpoint. @@ -177,28 +181,35 @@ def param_serialize( header_params = header_params or {} header_params.update(self.default_headers) if self.cookie: - header_params["Cookie"] = self.cookie + header_params['Cookie'] = self.cookie if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( - self.parameters_to_tuples(header_params, collection_formats) + self.parameters_to_tuples(header_params,collection_formats) ) # path parameters if path_params: path_params = self.sanitize_for_serialization(path_params) - path_params = self.parameters_to_tuples(path_params, collection_formats) + path_params = self.parameters_to_tuples( + path_params, + collection_formats + ) for k, v in path_params: # specified safe chars, encode everything resource_path = resource_path.replace( - "{%s}" % k, quote(str(v), safe=config.safe_chars_for_path_param) + '{%s}' % k, + quote(str(v), safe=config.safe_chars_for_path_param) ) # post parameters if post_params or files: post_params = post_params if post_params else [] post_params = self.sanitize_for_serialization(post_params) - post_params = self.parameters_to_tuples(post_params, collection_formats) + post_params = self.parameters_to_tuples( + post_params, + collection_formats + ) if files: post_params.extend(self.files_parameters(files)) @@ -210,7 +221,7 @@ def param_serialize( resource_path, method, body, - request_auth=_request_auth, + request_auth=_request_auth ) # body @@ -227,11 +238,15 @@ def param_serialize( # query parameters if query_params: query_params = self.sanitize_for_serialization(query_params) - url_query = self.parameters_to_url_query(query_params, collection_formats) + url_query = self.parameters_to_url_query( + query_params, + collection_formats + ) url += "?" + url_query return method, url, header_params, body, post_params + def call_api( self, method, @@ -239,7 +254,7 @@ def call_api( header_params=None, body=None, post_params=None, - _request_timeout=None, + _request_timeout=None ) -> rest.RESTResponse: """Makes the HTTP request (synchronous) :param method: Method to call. @@ -256,12 +271,10 @@ def call_api( try: # perform request and return response response_data = self.rest_client.request( - method, - url, + method, url, headers=header_params, - body=body, - post_params=post_params, - _request_timeout=_request_timeout, + body=body, post_params=post_params, + _request_timeout=_request_timeout ) except ApiException as e: @@ -272,7 +285,7 @@ def call_api( def response_deserialize( self, response_data: rest.RESTResponse, - response_types_map: Optional[Dict[str, ApiResponseT]] = None, + response_types_map: Optional[Dict[str, ApiResponseT]]=None ) -> ApiResponse[ApiResponseT]: """Deserializes response into an object. :param response_data: RESTResponse object to be deserialized. @@ -284,15 +297,9 @@ def response_deserialize( assert response_data.data is not None, msg response_type = response_types_map.get(str(response_data.status), None) - if ( - not response_type - and isinstance(response_data.status, int) - and 100 <= response_data.status <= 599 - ): + if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: # if not found, look for '1XX', '2XX', etc. - response_type = response_types_map.get( - str(response_data.status)[0] + "XX", None - ) + response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) # deserialize response data response_text = None @@ -304,14 +311,12 @@ def response_deserialize( return_data = self.__deserialize_file(response_data) elif response_type is not None: match = None - content_type = response_data.getheader("content-type") + content_type = response_data.getheader('content-type') if content_type is not None: match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) encoding = match.group(1) if match else "utf-8" response_text = response_data.data.decode(encoding) - return_data = self.deserialize( - response_text, response_type, content_type - ) + return_data = self.deserialize(response_text, response_type, content_type) finally: if not 200 <= response_data.status <= 299: raise ApiException.from_response( @@ -321,10 +326,10 @@ def response_deserialize( ) return ApiResponse( - status_code=response_data.status, - data=return_data, - headers=response_data.getheaders(), - raw_data=response_data.data, + status_code = response_data.status, + data = return_data, + headers = response_data.getheaders(), + raw_data = response_data.data ) def sanitize_for_serialization(self, obj): @@ -352,9 +357,13 @@ def sanitize_for_serialization(self, obj): elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): - return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] + return [ + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ] elif isinstance(obj, tuple): - return tuple(self.sanitize_for_serialization(sub_obj) for sub_obj in obj) + return tuple( + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ) elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() elif isinstance(obj, decimal.Decimal): @@ -368,18 +377,17 @@ def sanitize_for_serialization(self, obj): # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - if hasattr(obj, "to_dict") and callable(getattr(obj, "to_dict")): + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): obj_dict = obj.to_dict() else: obj_dict = obj.__dict__ return { - key: self.sanitize_for_serialization(val) for key, val in obj_dict.items() + key: self.sanitize_for_serialization(val) + for key, val in obj_dict.items() } - def deserialize( - self, response_text: str, response_type: str, content_type: Optional[str] - ): + def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): """Deserializes response into an object. :param response: RESTResponse object to be deserialized. @@ -396,20 +404,17 @@ def deserialize( data = json.loads(response_text) except ValueError: data = response_text - elif re.match( - r"^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)", - content_type, - re.IGNORECASE, - ): + elif re.match(r'^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): if response_text == "": data = "" else: data = json.loads(response_text) - elif re.match(r"^text\/[a-z.+-]+\s*(;|$)", content_type, re.IGNORECASE): + elif re.match(r'^text\/[a-z.+-]+\s*(;|$)', content_type, re.IGNORECASE): data = response_text else: raise ApiException( - status=0, reason="Unsupported content type: {0}".format(content_type) + status=0, + reason="Unsupported content type: {0}".format(content_type) ) return self.__deserialize(data, response_type) @@ -426,17 +431,19 @@ def __deserialize(self, data, klass): return None if isinstance(klass, str): - if klass.startswith("List["): - m = re.match(r"List\[(.*)]", klass) + if klass.startswith('List['): + m = re.match(r'List\[(.*)]', klass) assert m is not None, "Malformed List type definition" sub_kls = m.group(1) - return [self.__deserialize(sub_data, sub_kls) for sub_data in data] + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] - if klass.startswith("Dict["): - m = re.match(r"Dict\[([^,]*), (.*)]", klass) + if klass.startswith('Dict['): + m = re.match(r'Dict\[([^,]*), (.*)]', klass) assert m is not None, "Malformed Dict type definition" sub_kls = m.group(2) - return {k: self.__deserialize(v, sub_kls) for k, v in data.items()} + return {k: self.__deserialize(v, sub_kls) + for k, v in data.items()} # convert str to class if klass in self.NATIVE_TYPES_MAPPING: @@ -472,18 +479,19 @@ def parameters_to_tuples(self, params, collection_formats): for k, v in params.items() if isinstance(params, dict) else params: if k in collection_formats: collection_format = collection_formats[k] - if collection_format == "multi": + if collection_format == 'multi': new_params.extend((k, value) for value in v) else: - if collection_format == "ssv": - delimiter = " " - elif collection_format == "tsv": - delimiter = "\t" - elif collection_format == "pipes": - delimiter = "|" + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' else: # csv is the default - delimiter = "," - new_params.append((k, delimiter.join(str(value) for value in v))) + delimiter = ',' + new_params.append( + (k, delimiter.join(str(value) for value in v))) else: new_params.append((k, v)) return new_params @@ -508,17 +516,17 @@ def parameters_to_url_query(self, params, collection_formats): if k in collection_formats: collection_format = collection_formats[k] - if collection_format == "multi": + if collection_format == 'multi': new_params.extend((k, str(value)) for value in v) else: - if collection_format == "ssv": - delimiter = " " - elif collection_format == "tsv": - delimiter = "\t" - elif collection_format == "pipes": - delimiter = "|" + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' else: # csv is the default - delimiter = "," + delimiter = ',' new_params.append( (k, delimiter.join(quote(str(value)) for value in v)) ) @@ -539,7 +547,7 @@ def files_parameters( params = [] for k, v in files.items(): if isinstance(v, str): - with open(v, "rb") as f: + with open(v, 'rb') as f: filename = os.path.basename(f.name) filedata = f.read() elif isinstance(v, bytes): @@ -553,8 +561,13 @@ def files_parameters( continue else: raise ValueError("Unsupported file value") - mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream" - params.append(tuple([k, tuple([filename, filedata, mimetype])])) + mimetype = ( + mimetypes.guess_type(filename)[0] + or 'application/octet-stream' + ) + params.append( + tuple([k, tuple([filename, filedata, mimetype])]) + ) return params def select_header_accept(self, accepts: List[str]) -> Optional[str]: @@ -567,7 +580,7 @@ def select_header_accept(self, accepts: List[str]) -> Optional[str]: return None for accept in accepts: - if re.search("json", accept, re.IGNORECASE): + if re.search('json', accept, re.IGNORECASE): return accept return accepts[0] @@ -582,7 +595,7 @@ def select_header_content_type(self, content_types): return None for content_type in content_types: - if re.search("json", content_type, re.IGNORECASE): + if re.search('json', content_type, re.IGNORECASE): return content_type return content_types[0] @@ -595,7 +608,7 @@ def update_params_for_auth( resource_path, method, body, - request_auth=None, + request_auth=None ) -> None: """Updates header and query params based on authentication setting. @@ -614,18 +627,34 @@ def update_params_for_auth( if request_auth: self._apply_auth_params( - headers, queries, resource_path, method, body, request_auth + headers, + queries, + resource_path, + method, + body, + request_auth ) else: for auth in auth_settings: auth_setting = self.configuration.auth_settings().get(auth) if auth_setting: self._apply_auth_params( - headers, queries, resource_path, method, body, auth_setting + headers, + queries, + resource_path, + method, + body, + auth_setting ) def _apply_auth_params( - self, headers, queries, resource_path, method, body, auth_setting + self, + headers, + queries, + resource_path, + method, + body, + auth_setting ) -> None: """Updates the request parameters based on a single auth_setting @@ -637,15 +666,17 @@ def _apply_auth_params( The object type is the return value of sanitize_for_serialization(). :param auth_setting: auth settings for the endpoint """ - if auth_setting["in"] == "cookie": - headers["Cookie"] = auth_setting["value"] - elif auth_setting["in"] == "header": - if auth_setting["type"] != "http-signature": - headers[auth_setting["key"]] = auth_setting["value"] - elif auth_setting["in"] == "query": - queries.append((auth_setting["key"], auth_setting["value"])) + if auth_setting['in'] == 'cookie': + headers['Cookie'] = auth_setting['value'] + elif auth_setting['in'] == 'header': + if auth_setting['type'] != 'http-signature': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + queries.append((auth_setting['key'], auth_setting['value'])) else: - raise ApiValueError("Authentication token must be in `query` or `header`") + raise ApiValueError( + 'Authentication token must be in `query` or `header`' + ) def __deserialize_file(self, response): """Deserializes body to file @@ -665,7 +696,10 @@ def __deserialize_file(self, response): content_disposition = response.getheader("Content-Disposition") if content_disposition: - m = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition) + m = re.search( + r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition + ) assert m is not None, "Unexpected 'content-disposition' header value" filename = m.group(1) path = os.path.join(os.path.dirname(path), filename) @@ -709,7 +743,8 @@ def __deserialize_date(self, string): return string except ValueError: raise rest.ApiException( - status=0, reason="Failed to parse `{0}` as date object".format(string) + status=0, + reason="Failed to parse `{0}` as date object".format(string) ) def __deserialize_datetime(self, string): @@ -727,7 +762,10 @@ def __deserialize_datetime(self, string): except ValueError: raise rest.ApiException( status=0, - reason=("Failed to parse `{0}` as datetime object".format(string)), + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) ) def __deserialize_enum(self, data, klass): @@ -741,7 +779,11 @@ def __deserialize_enum(self, data, klass): return klass(data) except ValueError: raise rest.ApiException( - status=0, reason=("Failed to parse `{0}` as `{1}`".format(data, klass)) + status=0, + reason=( + "Failed to parse `{0}` as `{1}`" + .format(data, klass) + ) ) def __deserialize_model(self, data, klass): diff --git a/py/packages/corpora_client/api_response.py b/py/packages/corpora_client/api_response.py index 1ce1372..9bc7c11 100644 --- a/py/packages/corpora_client/api_response.py +++ b/py/packages/corpora_client/api_response.py @@ -6,7 +6,6 @@ T = TypeVar("T") - class ApiResponse(BaseModel, Generic[T]): """ API response object @@ -17,4 +16,6 @@ class ApiResponse(BaseModel, Generic[T]): data: T = Field(description="Deserialized data given the data type") raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") - model_config = {"arbitrary_types_allowed": True} + model_config = { + "arbitrary_types_allowed": True + } diff --git a/py/packages/corpora_client/configuration.py b/py/packages/corpora_client/configuration.py index 6618350..c8997ee 100644 --- a/py/packages/corpora_client/configuration.py +++ b/py/packages/corpora_client/configuration.py @@ -25,16 +25,9 @@ JSON_SCHEMA_VALIDATION_KEYWORDS = { - "multipleOf", - "maximum", - "exclusiveMaximum", - "minimum", - "exclusiveMinimum", - "maxLength", - "minLength", - "pattern", - "maxItems", - "minItems", + 'multipleOf', 'maximum', 'exclusiveMaximum', + 'minimum', 'exclusiveMinimum', 'maxLength', + 'minLength', 'pattern', 'maxItems', 'minItems' } ServerVariablesT = Dict[str, str] @@ -176,23 +169,24 @@ class Configuration: def __init__( self, - host: Optional[str] = None, - api_key: Optional[Dict[str, str]] = None, - api_key_prefix: Optional[Dict[str, str]] = None, - username: Optional[str] = None, - password: Optional[str] = None, - access_token: Optional[str] = None, - server_index: Optional[int] = None, - server_variables: Optional[ServerVariablesT] = None, - server_operation_index: Optional[Dict[int, int]] = None, - server_operation_variables: Optional[Dict[int, ServerVariablesT]] = None, - ignore_operation_servers: bool = False, - ssl_ca_cert: Optional[str] = None, + host: Optional[str]=None, + api_key: Optional[Dict[str, str]]=None, + api_key_prefix: Optional[Dict[str, str]]=None, + username: Optional[str]=None, + password: Optional[str]=None, + access_token: Optional[str]=None, + server_index: Optional[int]=None, + server_variables: Optional[ServerVariablesT]=None, + server_operation_index: Optional[Dict[int, int]]=None, + server_operation_variables: Optional[Dict[int, ServerVariablesT]]=None, + ignore_operation_servers: bool=False, + ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, *, debug: Optional[bool] = None, ) -> None: - """Constructor""" + """Constructor + """ self._base_path = "http://localhost" if host is None else host """Default Base url """ @@ -238,7 +232,7 @@ def __init__( """ self.logger["package_logger"] = logging.getLogger("corpora_client") self.logger["urllib3_logger"] = logging.getLogger("urllib3") - self.logger_format = "%(asctime)s %(levelname)s %(message)s" + self.logger_format = '%(asctime)s %(levelname)s %(message)s' """Log format """ self.logger_stream_handler = None @@ -293,7 +287,7 @@ def __init__( self.proxy_headers = None """Proxy headers """ - self.safe_chars_for_path_param = "" + self.safe_chars_for_path_param = '' """Safe chars for path_param """ self.retries = retries @@ -314,12 +308,12 @@ def __init__( """date format """ - def __deepcopy__(self, memo: Dict[int, Any]) -> Self: + def __deepcopy__(self, memo: Dict[int, Any]) -> Self: cls = self.__class__ result = cls.__new__(cls) memo[id(self)] = result for k, v in self.__dict__.items(): - if k not in ("logger", "logger_file_handler"): + if k not in ('logger', 'logger_file_handler'): setattr(result, k, copy.deepcopy(v, memo)) # shallow copy of loggers result.logger = copy.copy(self.logger) @@ -451,9 +445,7 @@ def logger_format(self, value: str) -> None: self.__logger_format = value self.logger_formatter = logging.Formatter(self.__logger_format) - def get_api_key_with_prefix( - self, identifier: str, alias: Optional[str] = None - ) -> Optional[str]: + def get_api_key_with_prefix(self, identifier: str, alias: Optional[str]=None) -> Optional[str]: """Gets API key (with prefix if set). :param identifier: The identifier of apiKey. @@ -462,9 +454,7 @@ def get_api_key_with_prefix( """ if self.refresh_api_key_hook is not None: self.refresh_api_key_hook(self) - key = self.api_key.get( - identifier, self.api_key.get(alias) if alias is not None else None - ) + key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) if key: prefix = self.api_key_prefix.get(identifier) if prefix: @@ -485,22 +475,22 @@ def get_basic_auth_token(self) -> Optional[str]: password = "" if self.password is not None: password = self.password - return urllib3.util.make_headers(basic_auth=username + ":" + password).get( - "authorization" - ) + return urllib3.util.make_headers( + basic_auth=username + ':' + password + ).get('authorization') - def auth_settings(self) -> AuthSettings: + def auth_settings(self)-> AuthSettings: """Gets Auth Settings dict for api client. :return: The Auth Settings information dict. """ auth: AuthSettings = {} if self.access_token is not None: - auth["BearerAuth"] = { - "type": "bearer", - "in": "header", - "key": "Authorization", - "value": "Bearer " + self.access_token, + auth['BearerAuth'] = { + 'type': 'bearer', + 'in': 'header', + 'key': 'Authorization', + 'value': 'Bearer ' + self.access_token } return auth @@ -509,13 +499,12 @@ def to_debug_report(self) -> str: :return: The report for debugging. """ - return ( - "Python SDK Debug Report:\n" - "OS: {env}\n" - "Python Version: {pyversion}\n" - "Version of the API: 0.1.0\n" - "SDK Package Version: 1.0.0".format(env=sys.platform, pyversion=sys.version) - ) + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 0.1.0\n"\ + "SDK Package Version: 1.0.0".\ + format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: """Gets an array of host settings @@ -524,16 +513,16 @@ def get_host_settings(self) -> List[HostSetting]: """ return [ { - "url": "", - "description": "No description provided", + 'url': "", + 'description': "No description provided", } ] def get_host_from_settings( self, index: Optional[int], - variables: Optional[ServerVariablesT] = None, - servers: Optional[List[HostSetting]] = None, + variables: Optional[ServerVariablesT]=None, + servers: Optional[List[HostSetting]]=None, ) -> str: """Gets host URL based on the index and variables :param index: array index of the host settings @@ -552,22 +541,22 @@ def get_host_from_settings( except IndexError: raise ValueError( "Invalid index {0} when selecting the host settings. " - "Must be less than {1}".format(index, len(servers)) - ) + "Must be less than {1}".format(index, len(servers))) - url = server["url"] + url = server['url'] # go through variables and replace placeholders - for variable_name, variable in server.get("variables", {}).items(): - used_value = variables.get(variable_name, variable["default_value"]) + for variable_name, variable in server.get('variables', {}).items(): + used_value = variables.get( + variable_name, variable['default_value']) - if "enum_values" in variable and used_value not in variable["enum_values"]: + if 'enum_values' in variable \ + and used_value not in variable['enum_values']: raise ValueError( "The variable `{0}` in the host URL has invalid value " "{1}. Must be {2}.".format( - variable_name, variables[variable_name], variable["enum_values"] - ) - ) + variable_name, variables[variable_name], + variable['enum_values'])) url = url.replace("{" + variable_name + "}", used_value) @@ -576,9 +565,7 @@ def get_host_from_settings( @property def host(self) -> str: """Return generated host.""" - return self.get_host_from_settings( - self.server_index, variables=self.server_variables - ) + return self.get_host_from_settings(self.server_index, variables=self.server_variables) @host.setter def host(self, value: str) -> None: diff --git a/py/packages/corpora_client/exceptions.py b/py/packages/corpora_client/exceptions.py index d375b45..fd00bd3 100644 --- a/py/packages/corpora_client/exceptions.py +++ b/py/packages/corpora_client/exceptions.py @@ -14,16 +14,14 @@ from typing import Any, Optional from typing_extensions import Self - class OpenApiException(Exception): """The base exception class for all OpenAPIExceptions""" class ApiTypeError(OpenApiException, TypeError): - def __init__( - self, msg, path_to_item=None, valid_classes=None, key_type=None - ) -> None: - """Raises an exception for TypeErrors + def __init__(self, msg, path_to_item=None, valid_classes=None, + key_type=None) -> None: + """ Raises an exception for TypeErrors Args: msg (str): the exception message @@ -106,9 +104,9 @@ def __init__(self, msg, path_to_item=None) -> None: class ApiException(OpenApiException): def __init__( - self, - status=None, - reason=None, + self, + status=None, + reason=None, http_resp=None, *, body: Optional[str] = None, @@ -127,17 +125,17 @@ def __init__( self.reason = http_resp.reason if self.body is None: try: - self.body = http_resp.data.decode("utf-8") + self.body = http_resp.data.decode('utf-8') except Exception: pass self.headers = http_resp.getheaders() @classmethod def from_response( - cls, - *, - http_resp, - body: Optional[str], + cls, + *, + http_resp, + body: Optional[str], data: Optional[Any], ) -> Self: if http_resp.status == 400: @@ -158,9 +156,11 @@ def from_response( def __str__(self): """Custom error messages for exception""" - error_message = "({0})\n" "Reason: {1}\n".format(self.status, self.reason) + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) if self.headers: - error_message += "HTTP response headers: {0}\n".format(self.headers) + error_message += "HTTP response headers: {0}\n".format( + self.headers) if self.data or self.body: error_message += "HTTP response body: {0}\n".format(self.data or self.body) diff --git a/py/packages/corpora_client/models/corpus_chat_schema.py b/py/packages/corpora_client/models/corpus_chat_schema.py index 1f50f04..00d13ec 100644 --- a/py/packages/corpora_client/models/corpus_chat_schema.py +++ b/py/packages/corpora_client/models/corpus_chat_schema.py @@ -23,26 +23,17 @@ from typing import Optional, Set from typing_extensions import Self - class CorpusChatSchema(BaseModel): """ CorpusChatSchema - """ # noqa: E501 - + """ # noqa: E501 corpus_id: StrictStr messages: List[MessageSchema] - voice: Optional[StrictStr] = "" - purpose: Optional[StrictStr] = "" - structure: Optional[StrictStr] = "" - directions: Optional[StrictStr] = "" - __properties: ClassVar[List[str]] = [ - "corpus_id", - "messages", - "voice", - "purpose", - "structure", - "directions", - ] + voice: Optional[StrictStr] = '' + purpose: Optional[StrictStr] = '' + structure: Optional[StrictStr] = '' + directions: Optional[StrictStr] = '' + __properties: ClassVar[List[str]] = ["corpus_id", "messages", "voice", "purpose", "structure", "directions"] model_config = ConfigDict( populate_by_name=True, @@ -50,6 +41,7 @@ class CorpusChatSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -74,7 +66,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -87,7 +80,7 @@ def to_dict(self) -> Dict[str, Any]: for _item_messages in self.messages: if _item_messages: _items.append(_item_messages.to_dict()) - _dict["messages"] = _items + _dict['messages'] = _items return _dict @classmethod @@ -99,22 +92,14 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "corpus_id": obj.get("corpus_id"), - "messages": ( - [MessageSchema.from_dict(_item) for _item in obj["messages"]] - if obj.get("messages") is not None - else None - ), - "voice": obj.get("voice") if obj.get("voice") is not None else "", - "purpose": obj.get("purpose") if obj.get("purpose") is not None else "", - "structure": ( - obj.get("structure") if obj.get("structure") is not None else "" - ), - "directions": ( - obj.get("directions") if obj.get("directions") is not None else "" - ), - } - ) + _obj = cls.model_validate({ + "corpus_id": obj.get("corpus_id"), + "messages": [MessageSchema.from_dict(_item) for _item in obj["messages"]] if obj.get("messages") is not None else None, + "voice": obj.get("voice") if obj.get("voice") is not None else '', + "purpose": obj.get("purpose") if obj.get("purpose") is not None else '', + "structure": obj.get("structure") if obj.get("structure") is not None else '', + "directions": obj.get("directions") if obj.get("directions") is not None else '' + }) return _obj + + diff --git a/py/packages/corpora_client/models/corpus_file_chat_schema.py b/py/packages/corpora_client/models/corpus_file_chat_schema.py index 624beeb..1e5590f 100644 --- a/py/packages/corpora_client/models/corpus_file_chat_schema.py +++ b/py/packages/corpora_client/models/corpus_file_chat_schema.py @@ -23,28 +23,18 @@ from typing import Optional, Set from typing_extensions import Self - class CorpusFileChatSchema(BaseModel): """ CorpusFileChatSchema - """ # noqa: E501 - + """ # noqa: E501 corpus_id: StrictStr messages: List[MessageSchema] - voice: Optional[StrictStr] = "" - purpose: Optional[StrictStr] = "" - structure: Optional[StrictStr] = "" - directions: Optional[StrictStr] = "" + voice: Optional[StrictStr] = '' + purpose: Optional[StrictStr] = '' + structure: Optional[StrictStr] = '' + directions: Optional[StrictStr] = '' path: StrictStr - __properties: ClassVar[List[str]] = [ - "corpus_id", - "messages", - "voice", - "purpose", - "structure", - "directions", - "path", - ] + __properties: ClassVar[List[str]] = ["corpus_id", "messages", "voice", "purpose", "structure", "directions", "path"] model_config = ConfigDict( populate_by_name=True, @@ -52,6 +42,7 @@ class CorpusFileChatSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -76,7 +67,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -89,7 +81,7 @@ def to_dict(self) -> Dict[str, Any]: for _item_messages in self.messages: if _item_messages: _items.append(_item_messages.to_dict()) - _dict["messages"] = _items + _dict['messages'] = _items return _dict @classmethod @@ -101,23 +93,15 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "corpus_id": obj.get("corpus_id"), - "messages": ( - [MessageSchema.from_dict(_item) for _item in obj["messages"]] - if obj.get("messages") is not None - else None - ), - "voice": obj.get("voice") if obj.get("voice") is not None else "", - "purpose": obj.get("purpose") if obj.get("purpose") is not None else "", - "structure": ( - obj.get("structure") if obj.get("structure") is not None else "" - ), - "directions": ( - obj.get("directions") if obj.get("directions") is not None else "" - ), - "path": obj.get("path"), - } - ) + _obj = cls.model_validate({ + "corpus_id": obj.get("corpus_id"), + "messages": [MessageSchema.from_dict(_item) for _item in obj["messages"]] if obj.get("messages") is not None else None, + "voice": obj.get("voice") if obj.get("voice") is not None else '', + "purpose": obj.get("purpose") if obj.get("purpose") is not None else '', + "structure": obj.get("structure") if obj.get("structure") is not None else '', + "directions": obj.get("directions") if obj.get("directions") is not None else '', + "path": obj.get("path") + }) return _obj + + diff --git a/py/packages/corpora_client/models/corpus_response_schema.py b/py/packages/corpora_client/models/corpus_response_schema.py index f651ba7..8cc4f91 100644 --- a/py/packages/corpora_client/models/corpus_response_schema.py +++ b/py/packages/corpora_client/models/corpus_response_schema.py @@ -23,24 +23,16 @@ from typing import Optional, Set from typing_extensions import Self - class CorpusResponseSchema(BaseModel): """ CorpusResponseSchema - """ # noqa: E501 - + """ # noqa: E501 id: StrictStr name: StrictStr url: Optional[StrictStr] = None created_at: datetime updated_at: datetime - __properties: ClassVar[List[str]] = [ - "id", - "name", - "url", - "created_at", - "updated_at", - ] + __properties: ClassVar[List[str]] = ["id", "name", "url", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -48,6 +40,7 @@ class CorpusResponseSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -72,7 +65,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -82,7 +76,7 @@ def to_dict(self) -> Dict[str, Any]: # set to None if url (nullable) is None # and model_fields_set contains the field if self.url is None and "url" in self.model_fields_set: - _dict["url"] = None + _dict['url'] = None return _dict @@ -95,13 +89,13 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "id": obj.get("id"), - "name": obj.get("name"), - "url": obj.get("url"), - "created_at": obj.get("created_at"), - "updated_at": obj.get("updated_at"), - } - ) + _obj = cls.model_validate({ + "id": obj.get("id"), + "name": obj.get("name"), + "url": obj.get("url"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") + }) return _obj + + diff --git a/py/packages/corpora_client/models/corpus_schema.py b/py/packages/corpora_client/models/corpus_schema.py index 02c160c..e4564a1 100644 --- a/py/packages/corpora_client/models/corpus_schema.py +++ b/py/packages/corpora_client/models/corpus_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class CorpusSchema(BaseModel): """ CorpusSchema - """ # noqa: E501 - + """ # noqa: E501 name: StrictStr url: Optional[StrictStr] = None __properties: ClassVar[List[str]] = ["name", "url"] @@ -38,6 +36,7 @@ class CorpusSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -62,7 +61,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -72,7 +72,7 @@ def to_dict(self) -> Dict[str, Any]: # set to None if url (nullable) is None # and model_fields_set contains the field if self.url is None and "url" in self.model_fields_set: - _dict["url"] = None + _dict['url'] = None return _dict @@ -85,5 +85,10 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"name": obj.get("name"), "url": obj.get("url")}) + _obj = cls.model_validate({ + "name": obj.get("name"), + "url": obj.get("url") + }) return _obj + + diff --git a/py/packages/corpora_client/models/corpus_update_files_schema.py b/py/packages/corpora_client/models/corpus_update_files_schema.py index 47a66f4..45d0650 100644 --- a/py/packages/corpora_client/models/corpus_update_files_schema.py +++ b/py/packages/corpora_client/models/corpus_update_files_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class CorpusUpdateFilesSchema(BaseModel): """ CorpusUpdateFilesSchema - """ # noqa: E501 - + """ # noqa: E501 delete_files: Optional[List[StrictStr]] = None __properties: ClassVar[List[str]] = ["delete_files"] @@ -37,6 +35,7 @@ class CorpusUpdateFilesSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -61,7 +60,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -71,7 +71,7 @@ def to_dict(self) -> Dict[str, Any]: # set to None if delete_files (nullable) is None # and model_fields_set contains the field if self.delete_files is None and "delete_files" in self.model_fields_set: - _dict["delete_files"] = None + _dict['delete_files'] = None return _dict @@ -84,5 +84,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"delete_files": obj.get("delete_files")}) + _obj = cls.model_validate({ + "delete_files": obj.get("delete_files") + }) return _obj + + diff --git a/py/packages/corpora_client/models/file_response_schema.py b/py/packages/corpora_client/models/file_response_schema.py index 5182037..69a3c27 100644 --- a/py/packages/corpora_client/models/file_response_schema.py +++ b/py/packages/corpora_client/models/file_response_schema.py @@ -23,12 +23,10 @@ from typing import Optional, Set from typing_extensions import Self - class FileResponseSchema(BaseModel): """ FileResponseSchema - """ # noqa: E501 - + """ # noqa: E501 id: StrictStr corpus_id: StrictStr path: StrictStr @@ -36,15 +34,7 @@ class FileResponseSchema(BaseModel): checksum: StrictStr created_at: datetime updated_at: datetime - __properties: ClassVar[List[str]] = [ - "id", - "corpus_id", - "path", - "content", - "checksum", - "created_at", - "updated_at", - ] + __properties: ClassVar[List[str]] = ["id", "corpus_id", "path", "content", "checksum", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -52,6 +42,7 @@ class FileResponseSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -76,7 +67,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -94,15 +86,15 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "id": obj.get("id"), - "corpus_id": obj.get("corpus_id"), - "path": obj.get("path"), - "content": obj.get("content"), - "checksum": obj.get("checksum"), - "created_at": obj.get("created_at"), - "updated_at": obj.get("updated_at"), - } - ) + _obj = cls.model_validate({ + "id": obj.get("id"), + "corpus_id": obj.get("corpus_id"), + "path": obj.get("path"), + "content": obj.get("content"), + "checksum": obj.get("checksum"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") + }) return _obj + + diff --git a/py/packages/corpora_client/models/file_schema.py b/py/packages/corpora_client/models/file_schema.py index 7a94162..4de1cd1 100644 --- a/py/packages/corpora_client/models/file_schema.py +++ b/py/packages/corpora_client/models/file_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class FileSchema(BaseModel): """ FileSchema - """ # noqa: E501 - + """ # noqa: E501 path: StrictStr content: StrictStr corpus_id: StrictStr @@ -39,6 +37,7 @@ class FileSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -63,7 +62,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -81,11 +81,11 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "path": obj.get("path"), - "content": obj.get("content"), - "corpus_id": obj.get("corpus_id"), - } - ) + _obj = cls.model_validate({ + "path": obj.get("path"), + "content": obj.get("content"), + "corpus_id": obj.get("corpus_id") + }) return _obj + + diff --git a/py/packages/corpora_client/models/issue_schema.py b/py/packages/corpora_client/models/issue_schema.py index e31e497..2716d30 100644 --- a/py/packages/corpora_client/models/issue_schema.py +++ b/py/packages/corpora_client/models/issue_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class IssueSchema(BaseModel): """ IssueSchema - """ # noqa: E501 - + """ # noqa: E501 title: StrictStr body: StrictStr __properties: ClassVar[List[str]] = ["title", "body"] @@ -38,6 +36,7 @@ class IssueSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -62,7 +61,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -80,5 +80,10 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"title": obj.get("title"), "body": obj.get("body")}) + _obj = cls.model_validate({ + "title": obj.get("title"), + "body": obj.get("body") + }) return _obj + + diff --git a/py/packages/corpora_client/models/message_schema.py b/py/packages/corpora_client/models/message_schema.py index 72d10bf..74003b3 100644 --- a/py/packages/corpora_client/models/message_schema.py +++ b/py/packages/corpora_client/models/message_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class MessageSchema(BaseModel): """ MessageSchema - """ # noqa: E501 - + """ # noqa: E501 role: StrictStr text: StrictStr __properties: ClassVar[List[str]] = ["role", "text"] @@ -38,6 +36,7 @@ class MessageSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -62,7 +61,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -80,5 +80,10 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({"role": obj.get("role"), "text": obj.get("text")}) + _obj = cls.model_validate({ + "role": obj.get("role"), + "text": obj.get("text") + }) return _obj + + diff --git a/py/packages/corpora_client/models/split_response_schema.py b/py/packages/corpora_client/models/split_response_schema.py index 35724d6..0075479 100644 --- a/py/packages/corpora_client/models/split_response_schema.py +++ b/py/packages/corpora_client/models/split_response_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class SplitResponseSchema(BaseModel): """ SplitResponseSchema - """ # noqa: E501 - + """ # noqa: E501 id: StrictStr content: StrictStr order: StrictInt @@ -40,6 +38,7 @@ class SplitResponseSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -64,7 +63,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -82,12 +82,12 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "id": obj.get("id"), - "content": obj.get("content"), - "order": obj.get("order"), - "file_id": obj.get("file_id"), - } - ) + _obj = cls.model_validate({ + "id": obj.get("id"), + "content": obj.get("content"), + "order": obj.get("order"), + "file_id": obj.get("file_id") + }) return _obj + + diff --git a/py/packages/corpora_client/models/split_vector_search_schema.py b/py/packages/corpora_client/models/split_vector_search_schema.py index e9396f9..ef74453 100644 --- a/py/packages/corpora_client/models/split_vector_search_schema.py +++ b/py/packages/corpora_client/models/split_vector_search_schema.py @@ -22,12 +22,10 @@ from typing import Optional, Set from typing_extensions import Self - class SplitVectorSearchSchema(BaseModel): """ SplitVectorSearchSchema - """ # noqa: E501 - + """ # noqa: E501 corpus_id: StrictStr text: StrictStr limit: Optional[StrictInt] = 10 @@ -39,6 +37,7 @@ class SplitVectorSearchSchema(BaseModel): protected_namespaces=(), ) + def to_str(self) -> str: """Returns the string representation of the model using alias""" return pprint.pformat(self.model_dump(by_alias=True)) @@ -63,7 +62,8 @@ def to_dict(self) -> Dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: Set[str] = set([]) + excluded_fields: Set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -81,11 +81,11 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - "corpus_id": obj.get("corpus_id"), - "text": obj.get("text"), - "limit": obj.get("limit") if obj.get("limit") is not None else 10, - } - ) + _obj = cls.model_validate({ + "corpus_id": obj.get("corpus_id"), + "text": obj.get("text"), + "limit": obj.get("limit") if obj.get("limit") is not None else 10 + }) return _obj + + diff --git a/py/packages/corpora_client/rest.py b/py/packages/corpora_client/rest.py index da782e2..49f626a 100644 --- a/py/packages/corpora_client/rest.py +++ b/py/packages/corpora_client/rest.py @@ -78,19 +78,22 @@ def __init__(self, configuration) -> None: "key_file": configuration.key_file, } if configuration.assert_hostname is not None: - pool_args["assert_hostname"] = configuration.assert_hostname + pool_args['assert_hostname'] = ( + configuration.assert_hostname + ) if configuration.retries is not None: - pool_args["retries"] = configuration.retries + pool_args['retries'] = configuration.retries if configuration.tls_server_name: - pool_args["server_hostname"] = configuration.tls_server_name + pool_args['server_hostname'] = configuration.tls_server_name + if configuration.socket_options is not None: - pool_args["socket_options"] = configuration.socket_options + pool_args['socket_options'] = configuration.socket_options if configuration.connection_pool_maxsize is not None: - pool_args["maxsize"] = configuration.connection_pool_maxsize + pool_args['maxsize'] = configuration.connection_pool_maxsize # https pool manager self.pool_manager: urllib3.PoolManager @@ -98,7 +101,6 @@ def __init__(self, configuration) -> None: if configuration.proxy: if is_socks_proxy_url(configuration.proxy): from urllib3.contrib.socks import SOCKSProxyManager - pool_args["proxy_url"] = configuration.proxy pool_args["headers"] = configuration.proxy_headers self.pool_manager = SOCKSProxyManager(**pool_args) @@ -116,7 +118,7 @@ def request( headers=None, body=None, post_params=None, - _request_timeout=None, + _request_timeout=None ): """Perform requests. @@ -133,7 +135,15 @@ def request( (connection, read) timeouts. """ method = method.upper() - assert method in ["GET", "HEAD", "DELETE", "POST", "PUT", "PATCH", "OPTIONS"] + assert method in [ + 'GET', + 'HEAD', + 'DELETE', + 'POST', + 'PUT', + 'PATCH', + 'OPTIONS' + ] if post_params and body: raise ApiValueError( @@ -147,18 +157,25 @@ def request( if _request_timeout: if isinstance(_request_timeout, (int, float)): timeout = urllib3.Timeout(total=_request_timeout) - elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2: + elif ( + isinstance(_request_timeout, tuple) + and len(_request_timeout) == 2 + ): timeout = urllib3.Timeout( - connect=_request_timeout[0], read=_request_timeout[1] + connect=_request_timeout[0], + read=_request_timeout[1] ) try: # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` - if method in ["POST", "PUT", "PATCH", "OPTIONS", "DELETE"]: + if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: # no content type provided or payload is json - content_type = headers.get("Content-Type") - if not content_type or re.search("json", content_type, re.IGNORECASE): + content_type = headers.get('Content-Type') + if ( + not content_type + or re.search('json', content_type, re.IGNORECASE) + ): request_body = None if body is not None: request_body = json.dumps(body) @@ -168,9 +185,9 @@ def request( body=request_body, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) - elif content_type == "application/x-www-form-urlencoded": + elif content_type == 'application/x-www-form-urlencoded': r = self.pool_manager.request( method, url, @@ -178,18 +195,15 @@ def request( encode_multipart=False, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) - elif content_type == "multipart/form-data": + elif content_type == 'multipart/form-data': # must del headers['Content-Type'], or the correct # Content-Type which generated by urllib3 will be # overwritten. - del headers["Content-Type"] + del headers['Content-Type'] # Ensures that dict objects are serialized - post_params = [ - (a, json.dumps(b)) if isinstance(b, dict) else (a, b) - for a, b in post_params - ] + post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params] r = self.pool_manager.request( method, url, @@ -197,7 +211,7 @@ def request( encode_multipart=True, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) # Pass a `string` parameter directly in the body to support # other content types than JSON when `body` argument is @@ -209,11 +223,9 @@ def request( body=body, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) - elif headers["Content-Type"].startswith("text/") and isinstance( - body, bool - ): + elif headers['Content-Type'].startswith('text/') and isinstance(body, bool): request_body = "true" if body else "false" r = self.pool_manager.request( method, @@ -221,8 +233,7 @@ def request( body=request_body, preload_content=False, timeout=timeout, - headers=headers, - ) + headers=headers) else: # Cannot generate the request from given parameters msg = """Cannot prepare a request message for provided @@ -237,7 +248,7 @@ def request( fields={}, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) except urllib3.exceptions.SSLError as e: msg = "\n".join([type(e).__name__, str(e)]) diff --git a/py/packages/corpora_client/setup.py b/py/packages/corpora_client/setup.py index 35bba0d..9199b8f 100644 --- a/py/packages/corpora_client/setup.py +++ b/py/packages/corpora_client/setup.py @@ -41,7 +41,7 @@ install_requires=REQUIRES, packages=find_packages(exclude=["test", "tests"]), include_package_data=True, - long_description_content_type="text/markdown", + long_description_content_type='text/markdown', long_description="""\ API for managing and processing corpora """, # noqa: E501 diff --git a/py/packages/corpora_client/test/test_corpus_api.py b/py/packages/corpora_client/test/test_corpus_api.py index 565475e..07e9ee9 100644 --- a/py/packages/corpora_client/test/test_corpus_api.py +++ b/py/packages/corpora_client/test/test_corpus_api.py @@ -76,5 +76,5 @@ def test_update_files(self) -> None: pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_corpus_chat_schema.py b/py/packages/corpora_client/test/test_corpus_chat_schema.py index e5fb7f5..abae99b 100644 --- a/py/packages/corpora_client/test/test_corpus_chat_schema.py +++ b/py/packages/corpora_client/test/test_corpus_chat_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.corpus_chat_schema import CorpusChatSchema - class TestCorpusChatSchema(unittest.TestCase): """CorpusChatSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> CorpusChatSchema: """Test CorpusChatSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `CorpusChatSchema` """ model = CorpusChatSchema() @@ -63,6 +62,5 @@ def testCorpusChatSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_corpus_file_chat_schema.py b/py/packages/corpora_client/test/test_corpus_file_chat_schema.py index 0d7a6b8..7a0af28 100644 --- a/py/packages/corpora_client/test/test_corpus_file_chat_schema.py +++ b/py/packages/corpora_client/test/test_corpus_file_chat_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.corpus_file_chat_schema import CorpusFileChatSchema - class TestCorpusFileChatSchema(unittest.TestCase): """CorpusFileChatSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> CorpusFileChatSchema: """Test CorpusFileChatSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `CorpusFileChatSchema` """ model = CorpusFileChatSchema() @@ -65,6 +64,5 @@ def testCorpusFileChatSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_corpus_response_schema.py b/py/packages/corpora_client/test/test_corpus_response_schema.py index 915d0c5..f365599 100644 --- a/py/packages/corpora_client/test/test_corpus_response_schema.py +++ b/py/packages/corpora_client/test/test_corpus_response_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.corpus_response_schema import CorpusResponseSchema - class TestCorpusResponseSchema(unittest.TestCase): """CorpusResponseSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> CorpusResponseSchema: """Test CorpusResponseSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `CorpusResponseSchema` """ model = CorpusResponseSchema() @@ -56,6 +55,5 @@ def testCorpusResponseSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_corpus_schema.py b/py/packages/corpora_client/test/test_corpus_schema.py index e9265b4..e12361c 100644 --- a/py/packages/corpora_client/test/test_corpus_schema.py +++ b/py/packages/corpora_client/test/test_corpus_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.corpus_schema import CorpusSchema - class TestCorpusSchema(unittest.TestCase): """CorpusSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> CorpusSchema: """Test CorpusSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `CorpusSchema` """ model = CorpusSchema() @@ -50,6 +49,5 @@ def testCorpusSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_corpus_update_files_schema.py b/py/packages/corpora_client/test/test_corpus_update_files_schema.py index fb60304..1e0d616 100644 --- a/py/packages/corpora_client/test/test_corpus_update_files_schema.py +++ b/py/packages/corpora_client/test/test_corpus_update_files_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.corpus_update_files_schema import CorpusUpdateFilesSchema - class TestCorpusUpdateFilesSchema(unittest.TestCase): """CorpusUpdateFilesSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> CorpusUpdateFilesSchema: """Test CorpusUpdateFilesSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `CorpusUpdateFilesSchema` """ model = CorpusUpdateFilesSchema() @@ -50,6 +49,5 @@ def testCorpusUpdateFilesSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_file_api.py b/py/packages/corpora_client/test/test_file_api.py index 3d03003..5e04984 100644 --- a/py/packages/corpora_client/test/test_file_api.py +++ b/py/packages/corpora_client/test/test_file_api.py @@ -48,5 +48,5 @@ def test_get_file_by_path(self) -> None: pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_file_response_schema.py b/py/packages/corpora_client/test/test_file_response_schema.py index 757f3ee..88f8b97 100644 --- a/py/packages/corpora_client/test/test_file_response_schema.py +++ b/py/packages/corpora_client/test/test_file_response_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.file_response_schema import FileResponseSchema - class TestFileResponseSchema(unittest.TestCase): """FileResponseSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> FileResponseSchema: """Test FileResponseSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `FileResponseSchema` """ model = FileResponseSchema() @@ -61,6 +60,5 @@ def testFileResponseSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_file_schema.py b/py/packages/corpora_client/test/test_file_schema.py index 6326b5d..e77630b 100644 --- a/py/packages/corpora_client/test/test_file_schema.py +++ b/py/packages/corpora_client/test/test_file_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.file_schema import FileSchema - class TestFileSchema(unittest.TestCase): """FileSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> FileSchema: """Test FileSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `FileSchema` """ model = FileSchema() @@ -53,6 +52,5 @@ def testFileSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_issue_schema.py b/py/packages/corpora_client/test/test_issue_schema.py index 15895c9..dbb483a 100644 --- a/py/packages/corpora_client/test/test_issue_schema.py +++ b/py/packages/corpora_client/test/test_issue_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.issue_schema import IssueSchema - class TestIssueSchema(unittest.TestCase): """IssueSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> IssueSchema: """Test IssueSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `IssueSchema` """ model = IssueSchema() @@ -51,6 +50,5 @@ def testIssueSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_message_schema.py b/py/packages/corpora_client/test/test_message_schema.py index 045a06f..a16dd67 100644 --- a/py/packages/corpora_client/test/test_message_schema.py +++ b/py/packages/corpora_client/test/test_message_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.message_schema import MessageSchema - class TestMessageSchema(unittest.TestCase): """MessageSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> MessageSchema: """Test MessageSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `MessageSchema` """ model = MessageSchema() @@ -51,6 +50,5 @@ def testMessageSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_plan_api.py b/py/packages/corpora_client/test/test_plan_api.py index 93370ce..15dbb86 100644 --- a/py/packages/corpora_client/test/test_plan_api.py +++ b/py/packages/corpora_client/test/test_plan_api.py @@ -34,5 +34,5 @@ def test_get_issue(self) -> None: pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_split_api.py b/py/packages/corpora_client/test/test_split_api.py index a493369..0466978 100644 --- a/py/packages/corpora_client/test/test_split_api.py +++ b/py/packages/corpora_client/test/test_split_api.py @@ -48,5 +48,5 @@ def test_vector_search(self) -> None: pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_split_response_schema.py b/py/packages/corpora_client/test/test_split_response_schema.py index 51db814..e4d65f1 100644 --- a/py/packages/corpora_client/test/test_split_response_schema.py +++ b/py/packages/corpora_client/test/test_split_response_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.split_response_schema import SplitResponseSchema - class TestSplitResponseSchema(unittest.TestCase): """SplitResponseSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> SplitResponseSchema: """Test SplitResponseSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `SplitResponseSchema` """ model = SplitResponseSchema() @@ -55,6 +54,5 @@ def testSplitResponseSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_split_vector_search_schema.py b/py/packages/corpora_client/test/test_split_vector_search_schema.py index d686878..cebd678 100644 --- a/py/packages/corpora_client/test/test_split_vector_search_schema.py +++ b/py/packages/corpora_client/test/test_split_vector_search_schema.py @@ -16,7 +16,6 @@ from corpora_client.models.split_vector_search_schema import SplitVectorSearchSchema - class TestSplitVectorSearchSchema(unittest.TestCase): """SplitVectorSearchSchema unit test stubs""" @@ -28,9 +27,9 @@ def tearDown(self): def make_instance(self, include_optional) -> SplitVectorSearchSchema: """Test SplitVectorSearchSchema - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included""" + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ # uncomment below to create an instance of `SplitVectorSearchSchema` """ model = SplitVectorSearchSchema() @@ -52,6 +51,5 @@ def testSplitVectorSearchSchema(self): # inst_req_only = self.make_instance(include_optional=False) # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_client/test/test_workon_api.py b/py/packages/corpora_client/test/test_workon_api.py index 7e3034c..b40ce2a 100644 --- a/py/packages/corpora_client/test/test_workon_api.py +++ b/py/packages/corpora_client/test/test_workon_api.py @@ -34,5 +34,5 @@ def test_file(self) -> None: pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() diff --git a/py/packages/corpora_pm/abstract.py b/py/packages/corpora_pm/abstract.py index fd820d2..b913f91 100644 --- a/py/packages/corpora_pm/abstract.py +++ b/py/packages/corpora_pm/abstract.py @@ -1,11 +1,10 @@ from abc import ABC, abstractmethod -from typing import List, Optional, Dict, Any from datetime import datetime +from typing import List, Optional class Issue: - """ - A class representing a generic issue in an issue tracking system. + """A class representing a generic issue in an issue tracking system. """ def __init__( @@ -32,14 +31,12 @@ def __init__( class AbstractIssueTracker(ABC): - """ - Abstract base class defining the interface for issue tracking systems. + """Abstract base class defining the interface for issue tracking systems. """ @abstractmethod def list_issues(self, repo: str, state: str = "open") -> List[Issue]: - """ - List issues for a repository. + """List issues for a repository. Args: repo (str): The repository name in the format "owner/repo". @@ -47,13 +44,12 @@ def list_issues(self, repo: str, state: str = "open") -> List[Issue]: Returns: List[Issue]: A list of issues. + """ - pass @abstractmethod def get_issue(self, repo: str, issue_id: int) -> Issue: - """ - Retrieve a specific issue by ID. + """Retrieve a specific issue by ID. Args: repo (str): The repository name in the format "owner/repo". @@ -61,8 +57,8 @@ def get_issue(self, repo: str, issue_id: int) -> Issue: Returns: Issue: The retrieved issue. + """ - pass @abstractmethod def create_issue( @@ -73,8 +69,7 @@ def create_issue( labels: Optional[List[str]] = None, assignees: Optional[List[str]] = None, ) -> Issue: - """ - Create a new issue. + """Create a new issue. Args: repo (str): The repository name in the format "owner/repo". @@ -85,8 +80,8 @@ def create_issue( Returns: Issue: The created issue. + """ - pass @abstractmethod def update_issue( @@ -99,8 +94,7 @@ def update_issue( labels: Optional[List[str]] = None, assignees: Optional[List[str]] = None, ) -> Issue: - """ - Update an existing issue. + """Update an existing issue. Args: repo (str): The repository name in the format "owner/repo". @@ -113,13 +107,12 @@ def update_issue( Returns: Issue: The updated issue. + """ - pass @abstractmethod def add_comment(self, repo: str, issue_id: int, comment: str) -> None: - """ - Add a comment to an issue. + """Add a comment to an issue. Args: repo (str): The repository name in the format "owner/repo". @@ -128,5 +121,5 @@ def add_comment(self, repo: str, issue_id: int, comment: str) -> None: Returns: None + """ - pass diff --git a/py/packages/corpora_pm/providers/github/pm.py b/py/packages/corpora_pm/providers/github/pm.py index 10d0034..bf15672 100644 --- a/py/packages/corpora_pm/providers/github/pm.py +++ b/py/packages/corpora_pm/providers/github/pm.py @@ -1,14 +1,14 @@ +from __future__ import annotations + import os from datetime import datetime -from typing import Any, Dict, List, Optional +from typing import Any -from corpora_pm.abstract import Issue, AbstractIssueTracker +from corpora_pm.abstract import AbstractIssueTracker, Issue class GitHubIssueTracker(AbstractIssueTracker): - """ - A concrete implementation of AbstractIssueTracker for GitHub. - """ + """A concrete implementation of AbstractIssueTracker for GitHub.""" def __init__( self, @@ -19,17 +19,26 @@ def __init__( self.base_url = base_url def _request( - self, method: str, endpoint: str, data: Optional[Dict[str, Any]] = None + self, + method: str, + endpoint: str, + data: dict[str, Any] | None = None, ) -> Any: import requests headers = {"Authorization": f"token {self.token}"} url = f"{self.base_url}/{endpoint}" - response = requests.request(method, url, headers=headers, json=data) + response = requests.request( + method, + url, + headers=headers, + json=data, + timeout=10, + ) response.raise_for_status() return response.json() - def list_issues(self, repo: str, state: str = "open") -> List[Issue]: + def list_issues(self, repo: str, state: str = "open") -> list[Issue]: endpoint = f"repos/{repo}/issues?state={state}" issues_data = self._request("GET", endpoint) return [ @@ -61,7 +70,8 @@ def get_issue(self, repo: str, issue_id: int) -> Issue: state=issue_data["state"], labels=[label["name"] for label in issue_data.get("labels", [])], assignees=[ - assignee["login"] for assignee in issue_data.get("assignees", []) + assignee["login"] + for assignee in issue_data.get("assignees", []) ], url=issue_data["html_url"], ) @@ -71,8 +81,8 @@ def create_issue( repo: str, title: str, body: str, - labels: Optional[List[str]] = None, - assignees: Optional[List[str]] = None, + labels: list[str] | None = None, + assignees: list[str] | None = None, ) -> Issue: endpoint = f"repos/{repo}/issues" data = { @@ -88,11 +98,11 @@ def update_issue( self, repo: str, issue_id: int, - title: Optional[str] = None, - body: Optional[str] = None, - state: Optional[str] = None, - labels: Optional[List[str]] = None, - assignees: Optional[List[str]] = None, + title: str | None = None, + body: str | None = None, + state: str | None = None, + labels: list[str] | None = None, + assignees: list[str] | None = None, ) -> Issue: endpoint = f"repos/{repo}/issues/{issue_id}" data = { @@ -103,7 +113,9 @@ def update_issue( "assignees": assignees, } self._request( - "PATCH", endpoint, {k: v for k, v in data.items() if v is not None} + "PATCH", + endpoint, + {k: v for k, v in data.items() if v is not None}, ) return self.get_issue(repo, issue_id) diff --git a/py/packages/corpora_pm/providers/github/test_pm.py b/py/packages/corpora_pm/providers/github/test_pm.py index 775a066..c0d22f0 100644 --- a/py/packages/corpora_pm/providers/github/test_pm.py +++ b/py/packages/corpora_pm/providers/github/test_pm.py @@ -1,13 +1,14 @@ import unittest -from unittest.mock import patch, MagicMock from datetime import datetime -from corpora_pm.providers.github.pm import GitHubIssueTracker +from unittest.mock import MagicMock, patch + from corpora_pm.abstract import Issue +from corpora_pm.providers.github.pm import GitHubIssueTracker class TestGitHubIssueTracker(unittest.TestCase): def setUp(self): - self.token = "fake_token" + self.token = "fake_token" # noqa: S105 self.repo = "fake_repo" self.issue_id = 1 self.tracker = GitHubIssueTracker(token=self.token) @@ -26,7 +27,7 @@ def test_list_issues(self, mock_request): "labels": [{"name": "bug"}], "assignees": [{"login": "user1"}], "html_url": "https://github.com/fake_repo/issues/1", - } + }, ] mock_request.return_value = mock_response @@ -79,7 +80,9 @@ def test_create_issue(self, mock_request): ), ): issue = self.tracker.create_issue( - self.repo, "New Issue", "Body of new issue" + self.repo, + "New Issue", + "Body of new issue", ) self.assertIsInstance(issue, Issue) self.assertEqual(issue.id, 1) @@ -127,6 +130,7 @@ def test_add_comment(self, mock_request): f"https://api.github.com/repos/{self.repo}/issues/{self.issue_id}/comments", headers={"Authorization": f"token {self.token}"}, json={"body": "This is a comment"}, + timeout=10, ) diff --git a/py/packages/corpora_pm/providers/provider_loader.py b/py/packages/corpora_pm/providers/provider_loader.py index 30c4a26..96a154a 100644 --- a/py/packages/corpora_pm/providers/provider_loader.py +++ b/py/packages/corpora_pm/providers/provider_loader.py @@ -1,9 +1,11 @@ # from corpora.models import Corpus import uuid -from ..abstract import AbstractIssueTracker + from pydantic import BaseModel +from ..abstract import AbstractIssueTracker + class Corpus(BaseModel): url: str @@ -11,8 +13,7 @@ class Corpus(BaseModel): def load_provider(corpus: Corpus) -> AbstractIssueTracker: - """ - Load an issue tracker provider for the given corpus. + """Load an issue tracker provider for the given corpus. """ # TODO: better way to determine provider # - support enterprise with custom URL diff --git a/py/packages/corpora_proj/__init__.py b/py/packages/corpora_proj/__init__.py index 5931bea..fbfba2d 100644 --- a/py/packages/corpora_proj/__init__.py +++ b/py/packages/corpora_proj/__init__.py @@ -1 +1 @@ -from .celery_app import app as celery_app # noqa +from .celery_app import app as celery_app # noqa: F401 diff --git a/py/packages/corpora_proj/asgi.py b/py/packages/corpora_proj/asgi.py index 976f165..27cd260 100644 --- a/py/packages/corpora_proj/asgi.py +++ b/py/packages/corpora_proj/asgi.py @@ -1,5 +1,4 @@ -""" -ASGI config for corpora_proj project. +"""ASGI config for corpora_proj project. It exposes the ASGI callable as a module-level variable named ``application``. diff --git a/py/packages/corpora_proj/celery_app.py b/py/packages/corpora_proj/celery_app.py index 7451eb0..906c1d1 100644 --- a/py/packages/corpora_proj/celery_app.py +++ b/py/packages/corpora_proj/celery_app.py @@ -1,5 +1,5 @@ -from __future__ import absolute_import, unicode_literals import os + from celery import Celery # Set the default Django settings module diff --git a/py/packages/corpora_proj/manage.py b/py/packages/corpora_proj/manage.py index c66dde3..3de5209 100755 --- a/py/packages/corpora_proj/manage.py +++ b/py/packages/corpora_proj/manage.py @@ -13,7 +13,7 @@ def main(): raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" + "forget to activate a virtual environment?", ) from exc execute_from_command_line(sys.argv) diff --git a/py/packages/corpora_proj/settings.py b/py/packages/corpora_proj/settings.py index d9d6b95..3604535 100644 --- a/py/packages/corpora_proj/settings.py +++ b/py/packages/corpora_proj/settings.py @@ -1,5 +1,4 @@ -""" -Django settings for corpora_proj project. +"""Django settings for corpora_proj project. Generated by 'django-admin startproject' using Django 5.1.2. @@ -19,7 +18,7 @@ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get( - "SECRET_KEY", "django-insecure-&amtx9f($xhj8vof6pn#gczuu6c!0^3!^9po+l_279q(6h_soa" + "SECRET_KEY", "django-insecure-&amtx9f($xhj8vof6pn#gczuu6c!0^3!^9po+l_279q(6h_soa", ) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -88,7 +87,7 @@ "PORT": os.environ.get("POSTGRES_PORT", "5432"), # not usable with async # "ATOMIC_REQUESTS": True, - } + }, } # Password validation diff --git a/py/packages/corpora_proj/urls.py b/py/packages/corpora_proj/urls.py index 5f1e6e4..bbb7c51 100644 --- a/py/packages/corpora_proj/urls.py +++ b/py/packages/corpora_proj/urls.py @@ -1,11 +1,12 @@ -from django.contrib import admin -from django.urls import include, path -from django.conf import settings -from oauth2_provider import urls as oauth2_urls -from ninja import NinjaAPI +"""URL Configuration for corpora_proj.""" from corpora.router import api as corpora_router from corpora.views import BinaryView +from django.conf import settings +from django.contrib import admin +from django.urls import include, path +from ninja import NinjaAPI +from oauth2_provider import urls as oauth2_urls router = NinjaAPI( title="Corpora API", diff --git a/py/packages/corpora_proj/wsgi.py b/py/packages/corpora_proj/wsgi.py index 7c481e8..4f1434c 100644 --- a/py/packages/corpora_proj/wsgi.py +++ b/py/packages/corpora_proj/wsgi.py @@ -1,5 +1,4 @@ -""" -WSGI config for corpora_proj project. +"""WSGI config for corpora_proj project. It exposes the WSGI callable as a module-level variable named ``application``. diff --git a/py/pyproject.toml b/py/pyproject.toml index 8bb6ee5..b3d2a42 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -1,2 +1,44 @@ -[tool.black] -line-length = 88 +# https://docs.astral.sh/ruff/configuration/ +[tool.ruff] +line-length = 80 + +[tool.ruff.lint] +select = ["ALL"] +fixable = ["ALL"] + +ignore = [ + "E501", # Line too long + "D", # Docstrings + "ERA001", # commented out code + "EM", # Exception .. string literal, assign to variable first + "TRY", # Avoid specifying long messages outside the exception class + "ANN", # type annotations + "T", # print statements + "PGH", # specific rules with noqa + "FIX", # I do TODO how I feel + "TD", # I do TODO how I feel + "TID", # relative imports + "PT", # pytest - maybe we turn on + "DTZ", # datetime timezone - maybe we turn on + "UP", # UP006 Use `list` instead of `List` for type annotation + "PLR", # Too many arguments in function definition (7 > 5) + "FA", # FA100 Add `from __future__ import annotations` to simplify `typing.Optional` + "A", # A002 Function argument `id` is shadowing a Python builtin + "SIM", # SIM117 Use a single `with` statement with multiple contexts instead of nested `with` statements + "ARG", # ARG002 Unused method argument + "S", # subprocess + "RUF", # RUF100 [*] Unused `noqa` directive + "SLF", # SLF001 Private member accessed + "PTH", # PTH123 `open()` should be replaced by `Path.open()` + "B", # B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + "RET", # RET504 Unnecessary assignment to `config` before `return` + "G004", # Logging statement uses f-string + "N803", # Argument name `MockOpenAIClient` should be lowercase" + "FBT002", # Boolean default positional argument in function definition" + "TC001", # Move application import `corpora_cli.context.ContextObject` into a type-checking blockRuffTC001 + +] +exclude = ["packages/corpora_client/*"] + +[tool.ruff.format] +quote-style = "double" diff --git a/py/requirements-dev.txt b/py/requirements-dev.txt index c410174..9719b1d 100644 --- a/py/requirements-dev.txt +++ b/py/requirements-dev.txt @@ -1,7 +1,7 @@ -black==24.10.0 django-extensions==3.2.3 ipython==8.29.0 pyinstaller==6.11.1 pytest==8.3.3 pytest-asyncio==0.24.0 pytest-django==4.9.0 +ruff==0.8.0 diff --git a/rs/core/corpora_cli/src/commands/sync.rs b/rs/core/corpora_cli/src/commands/sync.rs index 6eee322..d9712a2 100644 --- a/rs/core/corpora_cli/src/commands/sync.rs +++ b/rs/core/corpora_cli/src/commands/sync.rs @@ -1,6 +1,27 @@ use crate::context::Context; use std::{collections::HashMap, fs, path::PathBuf}; +// Implement the `cleanup_temp_files` function +// // Clean up the tarball +// ctx.success("Cleaning up temporary tarball file..."); +// if let Err(err) = fs::remove_file(&tarball_path) { +// ctx.warn(&format!("Failed to remove temporary tarball: {:?}", err)); +// } else { +// ctx.success("Temporary tarball file removed successfully."); +// } + +/// Clean up a list of temporary files +pub fn cleanup_temp_files(files: &[PathBuf], ctx: &Context) { + for file in files { + ctx.success(&format!("Cleaning up temporary file: {}", file.display())); + if let Err(err) = fs::remove_file(file) { + ctx.warn(&format!("Failed to remove temporary file: {:?}", err)); + } else { + ctx.success("Temporary file removed successfully."); + } + } +} + /// Run the `sync` command pub fn run(ctx: &Context) { ctx.success("Starting corpus sync..."); @@ -70,17 +91,14 @@ pub fn run(ctx: &Context) { .cloned() .collect(); - // Log the differences - ctx.success("Files to update/add:"); + ctx.warn(&format!("Files to update/add ({}):", files_to_update.len())); for file in files_to_update.keys() { - ctx.success(&format!(" - {}", file)); + ctx.dim(&format!(" - {}", file)); } - - ctx.success("Files to delete:"); + ctx.warn(&format!("Files to delete ({}):", files_to_delete.len())); for file in &files_to_delete { - ctx.success(&format!(" - {}", file)); + ctx.dim(&format!(" - {}", file)); } - if files_to_update.is_empty() && files_to_delete.is_empty() { ctx.success("No changes detected. Everything is up-to-date!"); return; @@ -109,8 +127,13 @@ pub fn run(ctx: &Context) { } }; - // Send the update to the server - ctx.success("Uploading changes to the server..."); + let upload = ctx.prompt_confirm("Do you want to upload?"); + if !upload { + cleanup_temp_files(&[tarball_path], ctx); + ctx.warn("Aborting sync. No changes have been made."); + return; + } + match corpora_client::apis::corpus_api::update_files( &ctx.api_config, &corpus_id, @@ -125,13 +148,7 @@ pub fn run(ctx: &Context) { } } - // Clean up the tarball - ctx.success("Cleaning up temporary tarball file..."); - if let Err(err) = fs::remove_file(&tarball_path) { - ctx.warn(&format!("Failed to remove temporary tarball: {:?}", err)); - } else { - ctx.success("Temporary tarball file removed successfully."); - } + cleanup_temp_files(&[tarball_path], ctx); } /// Calculate a hash for the given file path diff --git a/rs/core/corpora_cli/src/context/config.rs b/rs/core/corpora_cli/src/context/config.rs index adbb5a3..e1f05cf 100644 --- a/rs/core/corpora_cli/src/context/config.rs +++ b/rs/core/corpora_cli/src/context/config.rs @@ -28,7 +28,7 @@ pub fn load_config() -> Option { let config_path = current_dir.join(".corpora.yaml"); if config_path.exists() { let contents = fs::read_to_string(&config_path).ok()?; - println!("{}", contents); + // println!("{}", contents); let mut config: CorporaConfig = serde_yaml::from_str(&contents).ok()?; // Set additional fields that are not part of the config file @@ -48,7 +48,7 @@ pub fn load_config() -> Option { config.id = None; } - println!("{:?}", config); + // println!("{:?}", config); return Some(config); } diff --git a/rs/core/corpora_cli/src/context/mod.rs b/rs/core/corpora_cli/src/context/mod.rs index c1dc5d5..6e6ebcd 100644 --- a/rs/core/corpora_cli/src/context/mod.rs +++ b/rs/core/corpora_cli/src/context/mod.rs @@ -87,6 +87,7 @@ impl Context { /// A boolean indicating whether the user confirmed. pub fn prompt_confirm(&self, prompt: &str) -> bool { dialoguer::Confirm::new() + .default(false) .with_prompt(prompt) .interact() .unwrap_or_else(|_| { @@ -141,4 +142,13 @@ impl Context { let warn_style = Style::new().yellow().bold(); self.print(message, warn_style); } + + /// Print a dim message + /// Dim messages are used for less important information + /// # Arguments + /// * `message` - The message to print. + pub fn dim(&self, message: &str) { + let dim_style = Style::new().dim(); + self.print(message, dim_style); + } }