From 5954569b77977b84cb96cbb96c7d5b7430aedf34 Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Wed, 3 Sep 2025 18:30:43 +0300 Subject: [PATCH 1/2] reuse string --- api/routes/database.py | 4 +++- api/routes/graphs.py | 17 ++++++++++------- api/routes/tokens.py | 7 ++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/api/routes/database.py b/api/routes/database.py index 3f7368bf..23f5d99b 100644 --- a/api/routes/database.py +++ b/api/routes/database.py @@ -12,6 +12,8 @@ from api.loaders.postgres_loader import PostgresLoader from api.loaders.mysql_loader import MySQLLoader +from api.routes.tokens import UNAUTHORIZED_RESPONSE + database_router = APIRouter(tags=["Database Connection"]) # Use the same delimiter as in the JavaScript frontend for streaming chunks @@ -27,7 +29,7 @@ class DatabaseConnectionRequest(BaseModel): url: str @database_router.post("/database", operation_id="connect_database", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def connect_database(request: Request, db_request: DatabaseConnectionRequest): diff --git a/api/routes/graphs.py b/api/routes/graphs.py index 6385b217..f0f5d2e6 100644 --- a/api/routes/graphs.py +++ b/api/routes/graphs.py @@ -21,6 +21,8 @@ from api.loaders.mysql_loader import MySQLLoader from api.memory.graphiti_tool import MemoryTool +from api.routes.tokens import UNAUTHORIZED_RESPONSE + # Use the same delimiter as in the JavaScript MESSAGE_DELIMITER = "|||FALKORDB_MESSAGE_BOUNDARY|||" @@ -28,6 +30,7 @@ GENERAL_PREFIX = os.getenv("GENERAL_PREFIX") + class GraphData(BaseModel): """Graph data model. @@ -110,7 +113,7 @@ def _graph_name(request: Request, graph_id:str) -> str: return f"{request.state.user_id}_{graph_id}" @graphs_router.get("", operation_id="list_databases", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def list_graphs(request: Request): @@ -132,7 +135,7 @@ async def list_graphs(request: Request): return JSONResponse(content=filtered_graphs) @graphs_router.get("/{graph_id}/data", operation_id="database_schema", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def get_graph_data(request: Request, graph_id: str): # pylint: disable=too-many-locals,too-many-branches @@ -231,7 +234,7 @@ async def get_graph_data(request: Request, graph_id: str): # pylint: disable=to @graphs_router.post("", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def load_graph(request: Request, data: GraphData = None, file: UploadFile = File(None)): # pylint: disable=unused-argument @@ -267,7 +270,7 @@ async def load_graph(request: Request, data: GraphData = None, file: UploadFile raise HTTPException(status_code=415, detail="Unsupported Content-Type") @graphs_router.post("/{graph_id}", operation_id="query_database", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def query_graph(request: Request, graph_id: str, chat_data: ChatRequest): # pylint: disable=too-many-statements @@ -661,7 +664,7 @@ async def generate(): # pylint: disable=too-many-locals,too-many-branches,too-m @graphs_router.post("/{graph_id}/confirm", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def confirm_destructive_operation( @@ -825,7 +828,7 @@ async def generate_confirmation(): @graphs_router.post("/{graph_id}/refresh", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def refresh_graph_schema(request: Request, graph_id: str): @@ -856,7 +859,7 @@ async def refresh_graph_schema(request: Request, graph_id: str): raise HTTPException(status_code=500, detail="Internal server error while refreshing schema") # pylint: disable=raise-missing-from @graphs_router.delete("/{graph_id}", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def delete_graph(request: Request, graph_id: str): diff --git a/api/routes/tokens.py b/api/routes/tokens.py index 19ac3166..43be2784 100644 --- a/api/routes/tokens.py +++ b/api/routes/tokens.py @@ -11,6 +11,7 @@ from api.auth.user_management import token_required from api.extensions import db +UNAUTHORIZED_RESPONSE = {"description": "Unauthorized - Please log in or provide a valid API token"} # Router tokens_router = APIRouter(tags=["API Tokens"]) @@ -25,7 +26,7 @@ class TokenListResponse(BaseModel): tokens: List[TokenListItem] @tokens_router.post("/generate", response_model=TokenListItem, responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def generate_token(request: Request) -> TokenListItem: @@ -70,7 +71,7 @@ async def generate_token(request: Request) -> TokenListItem: ) from e @tokens_router.get("/list", response_model=TokenListResponse, responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def list_tokens(request: Request) -> TokenListResponse: @@ -110,7 +111,7 @@ async def list_tokens(request: Request) -> TokenListResponse: ) from e @tokens_router.delete("/{token_id}", responses={ - 401: {"description": "Unauthorized - Please log in or provide a valid API token"} + 401: UNAUTHORIZED_RESPONSE }) @token_required async def delete_token(request: Request, token_id: str) -> JSONResponse: From 7732f86240ce498b57dfca9eec1050c3cc547667 Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Thu, 4 Sep 2025 10:39:00 +0300 Subject: [PATCH 2/2] add apprunner --- apprunner.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 apprunner.yaml diff --git a/apprunner.yaml b/apprunner.yaml new file mode 100644 index 00000000..34e3e1b1 --- /dev/null +++ b/apprunner.yaml @@ -0,0 +1,11 @@ +version: 1.0 +runtime: python3 +build: + commands: + build: + - pip install pipenv + - pipenv install --deploy --ignore-pipfile +run: + command: pipenv run uvicorn main:app --host 0.0.0.0 --port 8000 + network: + port: 8000 \ No newline at end of file