diff --git a/poetry.lock b/poetry.lock index 5a5a415..59e308f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -201,17 +201,17 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "boto3" -version = "1.35.96" +version = "1.35.97" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.35.96-py3-none-any.whl", hash = "sha256:e6acb2380791b13d8fd55062d9bbc6e27c3ddb3e73cff71c4ca02e6743780c67"}, - {file = "boto3-1.35.96.tar.gz", hash = "sha256:bace02ef2181d176cedc1f8f90c95c301bb7c555db124cf80bc193cbb52a7c64"}, + {file = "boto3-1.35.97-py3-none-any.whl", hash = "sha256:8e49416216a6e3a62c2a0c44fba4dd2852c85472e7b702516605b1363867d220"}, + {file = "boto3-1.35.97.tar.gz", hash = "sha256:7d398f66a11e67777c189d1f58c0a75d9d60f98d0ee51b8817e828930bf19e4e"}, ] [package.dependencies] -botocore = ">=1.35.96,<1.36.0" +botocore = ">=1.35.97,<1.36.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -220,13 +220,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.96" +version = "1.35.97" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.96-py3-none-any.whl", hash = "sha256:b5f4cf11372aeccf87bb0b6148a020212c4c42fb5bcdebb6590bb10f6612b98e"}, - {file = "botocore-1.35.96.tar.gz", hash = "sha256:385fd406ed14bdd624e082d3e15dd6575d490d5d7374fb02f0a798c3ca9ea802"}, + {file = "botocore-1.35.97-py3-none-any.whl", hash = "sha256:fed4f156b1a9b8ece53738f702ba5851b8c6216b4952de326547f349cc494f14"}, + {file = "botocore-1.35.97.tar.gz", hash = "sha256:88f2fab29192ffe2f2115d5bafbbd823ff4b6eb2774296e03ec8b5b0fe074f61"}, ] [package.dependencies] @@ -1179,13 +1179,13 @@ files = [ [[package]] name = "openai" -version = "1.59.6" +version = "1.59.7" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" files = [ - {file = "openai-1.59.6-py3-none-any.whl", hash = "sha256:b28ed44eee3d5ebe1a3ea045ee1b4b50fea36ecd50741aaa5ce5a5559c900cb6"}, - {file = "openai-1.59.6.tar.gz", hash = "sha256:c7670727c2f1e4473f62fea6fa51475c8bc098c9ffb47bfb9eef5be23c747934"}, + {file = "openai-1.59.7-py3-none-any.whl", hash = "sha256:cfa806556226fa96df7380ab2e29814181d56fea44738c2b0e581b462c268692"}, + {file = "openai-1.59.7.tar.gz", hash = "sha256:043603def78c00befb857df9f0a16ee76a3af5984ba40cb7ee5e2f40db4646bf"}, ] [package.dependencies] @@ -1991,4 +1991,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "c3aae2d736278a055e7590ae105e41a5c691ac7cdfc530007e56a4047a3f5711" +content-hash = "00aabbcce56ea485c1a0cc2b9dd5055fb20f9638f23c773a3e79450e6390f71c" diff --git a/pyproject.toml b/pyproject.toml index 9c3e315..d139890 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ fastapi = "^0.115.6" pydantic = "^2.10.4" uvicorn = "^0.34.0" cloai = "^1.0.0" +openai = "^1.59.7" [tool.poetry.group.dev.dependencies] pytest = "^8.3.3" diff --git a/src/cloaiservice/config.py b/src/cloaiservice/config.py index 705d281..86baa60 100644 --- a/src/cloaiservice/config.py +++ b/src/cloaiservice/config.py @@ -5,26 +5,36 @@ from os import environ from typing import Literal +import fastapi +import pydantic +from fastapi import status + import cloai +from cloai.llm import bedrock as cloai_bedrock +from openai.types import chat_model from pydantic import BaseModel, Field -class AnthropicConfig(BaseModel): - """Anthropic client configuration.""" +class BedrockAnthropicConfig(BaseModel): + """Bedrock Anthropic client configuration.""" - type: Literal["anthropic"] - model: str - aws_access_key: str - aws_secret_key: str + type: Literal["bedrock-anthropic"] + model: cloai_bedrock.ANTHROPIC_BEDROCK_MODELS + aws_access_key: pydantic.SecretStr = pydantic.Field( + ..., min_length=20, max_length=20 + ) + aws_secret_key: pydantic.SecretStr = pydantic.Field( + ..., min_length=40, max_length=40 + ) region: str def create_client(self) -> cloai.LargeLanguageModel: """Create an Anthropic client instance.""" return cloai.LargeLanguageModel( client=cloai.AnthropicBedrockLlm( - model=self.model, # type: ignore # don't want to need to keep literal union in sync with cloai - aws_access_key=self.aws_access_key, - aws_secret_key=self.aws_secret_key, + model=self.model, + aws_access_key=self.aws_access_key.get_secret_value(), + aws_secret_key=self.aws_secret_key.get_secret_value(), region=self.region, ) ) @@ -34,8 +44,8 @@ class OpenAIConfig(BaseModel): """OpenAI client configuration.""" type: Literal["openai"] - model: str - api_key: str + model: chat_model.ChatModel | str + api_key: pydantic.SecretStr base_url: str | None = Field(default=None) def create_client(self) -> cloai.LargeLanguageModel: @@ -43,7 +53,7 @@ def create_client(self) -> cloai.LargeLanguageModel: return cloai.LargeLanguageModel( client=cloai.OpenAiLlm( model=self.model, - api_key=self.api_key, + api_key=self.api_key.get_secret_value(), base_url=self.base_url, ) ) @@ -53,7 +63,7 @@ class AzureConfig(BaseModel): """Azure client configuration.""" type: Literal["azure"] - api_key: str + api_key: pydantic.SecretStr endpoint: str deployment: str api_version: str @@ -62,7 +72,7 @@ def create_client(self) -> cloai.LargeLanguageModel: """Create an Azure client instance.""" return cloai.LargeLanguageModel( client=cloai.AzureLlm( - api_key=self.api_key, + api_key=self.api_key.get_secret_value(), endpoint=self.endpoint, deployment=self.deployment, api_version=self.api_version, @@ -73,7 +83,7 @@ def create_client(self) -> cloai.LargeLanguageModel: class ClientConfig(BaseModel): """Configuration for all clients.""" - clients: dict[str, AnthropicConfig | OpenAIConfig | AzureConfig] + clients: dict[str, BedrockAnthropicConfig | OpenAIConfig | AzureConfig] def create_clients(self) -> dict[str, cloai.LargeLanguageModel]: """Create all client instances."""