Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prisma protocol class #6

Merged
merged 47 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
4dc0193
Add prisma protocol class
kumaranvpl Jul 24, 2024
11d0d38
Merge branch 'main' into add-protocol
kumaranvpl Jul 25, 2024
ce5649e
Move protocol files to db directory
kumaranvpl Jul 25, 2024
b4d5773
Update docs
kumaranvpl Jul 25, 2024
b6a5caa
Remove unnecessary commented out lines
kumaranvpl Jul 25, 2024
e43f920
Split protocol
kumaranvpl Jul 25, 2024
da62ebd
Remove unnecessary code and rearrange
kumaranvpl Jul 25, 2024
b090fa1
Update docs
kumaranvpl Jul 25, 2024
6f8a2d7
Add methods for getting prisma actions objects
kumaranvpl Jul 26, 2024
a677fd3
Merge branch 'main' into add-protocol
kumaranvpl Jul 26, 2024
ac3e520
Use protocol
kumaranvpl Jul 26, 2024
9e44484
Optimize code
kumaranvpl Jul 26, 2024
546a06c
Update docs
kumaranvpl Jul 26, 2024
1144e64
Update BaseFrontendProtocol
kumaranvpl Jul 29, 2024
e595767
Rename prisma backend db class
kumaranvpl Jul 29, 2024
08c4855
Delete unnecessary class
kumaranvpl Jul 29, 2024
b0d522a
Remove unnecessary methods
kumaranvpl Jul 29, 2024
7a459c4
Use default find model
kumaranvpl Jul 29, 2024
c6ad243
Remove get_authtoken_connection method
kumaranvpl Jul 29, 2024
640da68
Remove get_model_connection method
kumaranvpl Jul 29, 2024
f80bd3f
Fix mypy issues
kumaranvpl Jul 29, 2024
b4095d3
Fix mypy issue
kumaranvpl Jul 29, 2024
7748480
Merge branch 'main' into add-protocol
kumaranvpl Jul 29, 2024
ae9be3e
Rename protocol class
kumaranvpl Jul 30, 2024
9f6ce31
Add an empty line between methods in protocol
kumaranvpl Jul 30, 2024
7780308
Use sync get default and set default methods
kumaranvpl Jul 30, 2024
e51b368
Refactor code
kumaranvpl Jul 30, 2024
c4206ef
Add a internal method to create user
kumaranvpl Jul 30, 2024
4d3725b
Add tests for prisma backend classes
kumaranvpl Jul 30, 2024
9cda7d2
Add inmemory protocol implementation
kumaranvpl Jul 30, 2024
6f8ab8a
Update prisma test
kumaranvpl Jul 30, 2024
d89c619
Update docs
kumaranvpl Jul 30, 2024
8d3da1f
Use inmemory db in tests
kumaranvpl Jul 30, 2024
7b1982e
wip
davorrunje Jul 31, 2024
ea945e9
wip
davorrunje Jul 31, 2024
fb1b22d
Use class defaultdb
kumaranvpl Jul 31, 2024
d5a5952
Remove unnecessary type adapter
kumaranvpl Jul 31, 2024
631b2f6
Move lifespan
kumaranvpl Jul 31, 2024
ec65449
Reuse from_db in agents/base.py
kumaranvpl Jul 31, 2024
ce3dd3e
Use Union[str, UUID]
kumaranvpl Jul 31, 2024
de473fe
Raise common exceptions and handle it in fastapi app
kumaranvpl Jul 31, 2024
09e9157
Update docs
kumaranvpl Jul 31, 2024
497692e
Use exception args
kumaranvpl Aug 12, 2024
c6c5fbb
Update together model string
kumaranvpl Aug 12, 2024
0caf753
Update openai models list
kumaranvpl Aug 12, 2024
6a90bd0
Update openai schema in test
kumaranvpl Aug 12, 2024
26e021a
Update openai tests
kumaranvpl Aug 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions docs/docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,21 @@ search:
- [parse_expiry](api/fastagency/auth_token/auth/parse_expiry.md)
- [verify_auth_token](api/fastagency/auth_token/auth/verify_auth_token.md)
- db
- helpers
- [find_model_using_raw](api/fastagency/db/helpers/find_model_using_raw.md)
- [get_db_connection](api/fastagency/db/helpers/get_db_connection.md)
- [get_user](api/fastagency/db/helpers/get_user.md)
- [get_wasp_db_url](api/fastagency/db/helpers/get_wasp_db_url.md)
- base
- [BackendDBProtocol](api/fastagency/db/base/BackendDBProtocol.md)
- [DefaultDB](api/fastagency/db/base/DefaultDB.md)
- [FrontendDBProtocol](api/fastagency/db/base/FrontendDBProtocol.md)
- [KeyExistsError](api/fastagency/db/base/KeyExistsError.md)
- [KeyNotFoundError](api/fastagency/db/base/KeyNotFoundError.md)
- inmemory
- [InMemoryBackendDB](api/fastagency/db/inmemory/InMemoryBackendDB.md)
- [InMemoryFrontendDB](api/fastagency/db/inmemory/InMemoryFrontendDB.md)
- prisma
- [PrismaBackendDB](api/fastagency/db/prisma/PrismaBackendDB.md)
- [PrismaBaseDB](api/fastagency/db/prisma/PrismaBaseDB.md)
- [PrismaFrontendDB](api/fastagency/db/prisma/PrismaFrontendDB.md)
- [fastapi_lifespan](api/fastagency/db/prisma/fastapi_lifespan.md)
- [faststream_lifespan](api/fastagency/db/prisma/faststream_lifespan.md)
- faststream_app
- [ping_handler](api/fastagency/faststream_app/ping_handler.md)
- helpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ search:
boost: 0.5
---

::: fastagency.db.helpers.get_wasp_db_url
::: fastagency.db.base.BackendDBProtocol
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ search:
boost: 0.5
---

::: fastagency.db.helpers.get_user
::: fastagency.db.base.DefaultDB
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ search:
boost: 0.5
---

::: fastagency.db.helpers.get_db_connection
::: fastagency.db.base.FrontendDBProtocol
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ search:
boost: 0.5
---

::: fastagency.db.helpers.find_model_using_raw
::: fastagency.db.base.KeyExistsError
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/base/KeyNotFoundError.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.base.KeyNotFoundError
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/inmemory/InMemoryBackendDB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.inmemory.InMemoryBackendDB
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/inmemory/InMemoryFrontendDB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.inmemory.InMemoryFrontendDB
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/prisma/PrismaBackendDB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.prisma.PrismaBackendDB
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/prisma/PrismaBaseDB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.prisma.PrismaBaseDB
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/prisma/PrismaFrontendDB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.prisma.PrismaFrontendDB
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/prisma/fastapi_lifespan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.prisma.fastapi_lifespan
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/db/prisma/faststream_lifespan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.db.prisma.faststream_lifespan
114 changes: 63 additions & 51 deletions fastagency/app.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import json
import logging
from os import environ
from typing import Annotated, Any, Dict, List, Optional, Tuple, Union
from typing import (
Annotated,
Any,
Callable,
Coroutine,
Dict,
List,
Optional,
Tuple,
Union,
)
from uuid import UUID

import httpx
import yaml
from fastapi import BackgroundTasks, Body, FastAPI, HTTPException, Path
from fastapi.requests import Request
from fastapi.responses import JSONResponse, Response
from openai import AsyncAzureOpenAI
from prisma.models import Model
from pydantic import BaseModel, TypeAdapter, ValidationError
from pydantic import BaseModel, ValidationError

from .auth_token.auth import DeploymentAuthToken, create_deployment_auth_token
from .db.helpers import find_model_using_raw, get_db_connection, get_user
from .db.base import DefaultDB, KeyNotFoundError
from .db.prisma import fastapi_lifespan
from .helpers import (
add_model_to_user,
create_model,
Expand All @@ -23,7 +35,18 @@

logging.basicConfig(level=logging.INFO)

app = FastAPI()

app = FastAPI(lifespan=fastapi_lifespan)


@app.middleware("http")
async def handle_keynotfounderror_middleware(
request: Request, call_next: Callable[[Request], Coroutine[Any, Any, Response]]
) -> Response:
try:
return await call_next(request)
except KeyNotFoundError as e:
return JSONResponse(status_code=404, content={"detail": str(e)})
Fixed Show fixed Hide fixed


@app.get("/models/schemas")
Expand Down Expand Up @@ -78,7 +101,7 @@
) -> Dict[str, Any]:
type: str = "secret"

found_model = await find_model_using_raw(model_uuid=model_uuid)
found_model = await DefaultDB.backend().find_model(model_uuid=model_uuid)
if "api_key" in found_model["json_str"]:
model["api_key"] = found_model["json_str"]["api_key"]
try:
Expand All @@ -100,10 +123,9 @@
user_uuid: str,
type_name: Optional[str] = None,
) -> List[Any]:
models = await get_all_models_for_user(user_uuid=user_uuid, type_name=type_name)

ta = TypeAdapter(List[Model])
ret_val_without_mask = ta.dump_python(models, serialize_as_any=True) # type: ignore[call-arg]
ret_val_without_mask = await get_all_models_for_user(
user_uuid=user_uuid, type_name=type_name
)

ret_val = []
for model in ret_val_without_mask:
Expand Down Expand Up @@ -136,7 +158,7 @@


async def create_toolbox_for_new_user(user_uuid: Union[str, UUID]) -> Dict[str, Any]:
await get_user(user_uuid=user_uuid) # type: ignore[arg-type]
await DefaultDB.frontend().get_user(user_uuid=user_uuid) # type: ignore[arg-type]

domain = environ.get("DOMAIN", "localhost")
toolbox_openapi_url = (
Expand Down Expand Up @@ -181,18 +203,14 @@
registry = Registry.get_default()
validated_model = registry.validate(type_name, model_name, model)

async with get_db_connection() as db:
found_model = await find_model_using_raw(model_uuid=model_uuid)

await db.model.update(
where={"uuid": found_model["uuid"]}, # type: ignore[arg-type]
data={ # type: ignore[typeddict-unknown-key]
"type_name": type_name,
"model_name": model_name,
"json_str": validated_model.model_dump_json(), # type: ignore[typeddict-item]
"user_uuid": user_uuid,
},
)
found_model = await DefaultDB.backend().find_model(model_uuid=model_uuid)
await DefaultDB.backend().update_model(
model_uuid=found_model["uuid"],
user_uuid=user_uuid,
type_name=type_name,
model_name=model_name,
json_str=validated_model.model_dump_json(),
)

return validated_model.model_dump()

Expand All @@ -201,13 +219,9 @@
async def models_delete(
user_uuid: str, type_name: str, model_uuid: str
) -> Dict[str, Any]:
async with get_db_connection() as db:
found_model = await find_model_using_raw(model_uuid=model_uuid)
model = await db.model.delete(
where={"uuid": found_model["uuid"]} # type: ignore[arg-type]
)

return model.json_str # type: ignore
found_model = await DefaultDB.backend().find_model(model_uuid=model_uuid)
model = await DefaultDB.backend().delete_model(model_uuid=found_model["uuid"])
return model["json_str"] # type: ignore


def get_azure_llm_client() -> Tuple[AsyncAzureOpenAI, str]:
Expand Down Expand Up @@ -340,7 +354,7 @@

@app.post("/deployment/{deployment_uuid}/chat")
async def deployment_chat(deployment_uuid: str) -> Dict[str, Any]:
found_model = await find_model_using_raw(model_uuid=deployment_uuid)
found_model = await DefaultDB.backend().find_model(model_uuid=deployment_uuid)
team_name = found_model["json_str"]["name"]
team_uuid = found_model["json_str"]["team"]["uuid"]

Expand Down Expand Up @@ -381,21 +395,22 @@
async def get_all_deployment_auth_tokens(
user_uuid: str, deployment_uuid: str
) -> List[DeploymentAuthTokenInfo]:
user = await get_user(user_uuid=user_uuid)
deployment = await find_model_using_raw(model_uuid=deployment_uuid)
user = await DefaultDB.frontend().get_user(user_uuid=user_uuid)
deployment = await DefaultDB.backend().find_model(model_uuid=deployment_uuid)

if user["uuid"] != deployment["user_uuid"]:
raise HTTPException( # pragma: no cover
status_code=403, detail="User does not have access to this deployment"
)

async with get_db_connection() as db:
auth_tokens = await db.authtoken.find_many(
where={"deployment_uuid": deployment_uuid, "user_uuid": user_uuid},
)
auth_tokens = await DefaultDB.backend().find_many_auth_token(
user_uuid=user_uuid, deployment_uuid=deployment_uuid
)
return [
DeploymentAuthTokenInfo(
uuid=auth_token.uuid, name=auth_token.name, expiry=auth_token.expiry
uuid=auth_token["uuid"],
name=auth_token["name"],
expiry=auth_token["expiry"],
)
for auth_token in auth_tokens
]
Expand All @@ -407,24 +422,21 @@
deployment_uuid: str,
auth_token_uuid: str,
) -> DeploymentAuthTokenInfo:
user = await get_user(user_uuid=user_uuid)
deployment = await find_model_using_raw(model_uuid=deployment_uuid)
user = await DefaultDB.frontend().get_user(user_uuid=user_uuid)
deployment = await DefaultDB.backend().find_model(model_uuid=deployment_uuid)

if user["uuid"] != deployment["user_uuid"]:
raise HTTPException( # pragma: no cover
status_code=403, detail="User does not have access to this deployment"
)

async with get_db_connection() as db:
auth_token = await db.authtoken.delete(
where={ # type: ignore[typeddict-unknown-key]
"uuid": auth_token_uuid,
"deployment_uuid": deployment_uuid,
"user_uuid": user_uuid,
},
)
auth_token = await DefaultDB.backend().delete_auth_token(
auth_token_uuid=auth_token_uuid,
deployment_uuid=deployment_uuid,
user_uuid=user_uuid,
)
return DeploymentAuthTokenInfo(
uuid=auth_token.uuid, # type: ignore[union-attr]
name=auth_token.name, # type: ignore[union-attr]
expiry=auth_token.expiry, # type: ignore[union-attr]
uuid=auth_token["uuid"], # type: ignore[union-attr]
name=auth_token["name"], # type: ignore[union-attr]
expiry=auth_token["expiry"], # type: ignore[union-attr]
)
Loading
Loading