From c4e4337bc6d7edc1fab488e02755630bb7fc79d6 Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 16:22:22 -0700 Subject: [PATCH 1/6] Caching config in AgentHubAPI. --- src/python/AgentHubAPI/AgentHubAPI.pyproj | 3 ++- src/python/AgentHubAPI/app/dependencies.py | 15 ++++++++++----- src/python/AgentHubAPI/app/main.py | 5 ----- src/python/AgentHubAPI/app/routers/list_agents.py | 11 ++++++++--- src/python/AgentHubAPI/run.py | 5 +++++ 5 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 src/python/AgentHubAPI/run.py diff --git a/src/python/AgentHubAPI/AgentHubAPI.pyproj b/src/python/AgentHubAPI/AgentHubAPI.pyproj index 3ed49d3792..fe8d04ec2d 100644 --- a/src/python/AgentHubAPI/AgentHubAPI.pyproj +++ b/src/python/AgentHubAPI/AgentHubAPI.pyproj @@ -4,7 +4,7 @@ 2.0 865a944e-76c4-4da9-b367-6d1cab66abcc . - app/main.py + run.py ..\PythonSDK . Standard Python launcher @@ -34,6 +34,7 @@ + diff --git a/src/python/AgentHubAPI/app/dependencies.py b/src/python/AgentHubAPI/app/dependencies.py index 56a07bb4e6..e2ab757dbc 100644 --- a/src/python/AgentHubAPI/app/dependencies.py +++ b/src/python/AgentHubAPI/app/dependencies.py @@ -2,6 +2,7 @@ Provides dependencies for API calls. """ import logging +import time from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import APIKeyHeader @@ -18,10 +19,15 @@ def get_config() -> Configuration: Configuration Returns the application configuration settings. """ - return __config or Configuration() + global __config -def validate_api_key_header(config: Annotated[Configuration, Depends()], - x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): + start = time.time() + __config = __config or Configuration() + end = time.time() + print(f'Time to load config: {end-start}') + return __config + +def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): """ Validates that the X-API-Key value in the request header matches the key expected for this API. @@ -37,8 +43,7 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], Returns True of the X-API-Key value from the request header matches the expected value. Otherwise, returns False. """ - - result = x_api_key == config.get_value('FoundationaLLM:APIs:AgentHubAPI:APIKey') + result = x_api_key == get_config().get_value('FoundationaLLM:APIs:AgentHubAPI:APIKey') if not result: logging.error('Invalid API key. You must provide a valid API key in the X-API-KEY header.') diff --git a/src/python/AgentHubAPI/app/main.py b/src/python/AgentHubAPI/app/main.py index 157dfdcbe0..c672406cec 100644 --- a/src/python/AgentHubAPI/app/main.py +++ b/src/python/AgentHubAPI/app/main.py @@ -2,7 +2,6 @@ Main entry-point for the FoundationaLLM AgentHubAPI. Runs web server exposing the API. """ -import uvicorn from fastapi import FastAPI from app.dependencies import get_config from app.routers import resolve, status, list_agents @@ -52,7 +51,3 @@ async def root(): Returns a JSON object containing a message and value. """ return { 'message': 'FoundationaLLM AgentHubAPI' } - -if __name__ == '__main__': - uvicorn.run('app.main:app', host='0.0.0.0', port=8742, - reload=True, forwarded_allow_ips='*', proxy_headers=True) diff --git a/src/python/AgentHubAPI/app/routers/list_agents.py b/src/python/AgentHubAPI/app/routers/list_agents.py index 4429b2dd8d..5a18f66c54 100644 --- a/src/python/AgentHubAPI/app/routers/list_agents.py +++ b/src/python/AgentHubAPI/app/routers/list_agents.py @@ -2,7 +2,7 @@ The API endpoint for listing available agents. """ from typing import List -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, Request from foundationallm.hubs.agent import AgentHub from app.dependencies import validate_api_key_header, handle_exception @@ -15,9 +15,14 @@ ) @router.get('') -async def list_agents() -> List: +async def list_agents(request: Request) -> List: """ Retrieves a list of available agents. + + Parameters + ---------- + request : Request + The underlying HTTP request. Returns ------- @@ -25,6 +30,6 @@ async def list_agents() -> List: Returns a list of metadata objects for all available agents. """ try: - return AgentHub().list() + return AgentHub(config=request.app.extra['config']).list() except Exception as e: handle_exception(e) diff --git a/src/python/AgentHubAPI/run.py b/src/python/AgentHubAPI/run.py new file mode 100644 index 0000000000..c4b45c0f58 --- /dev/null +++ b/src/python/AgentHubAPI/run.py @@ -0,0 +1,5 @@ +import uvicorn + +if __name__ == '__main__': + uvicorn.run('app.main:app', host='0.0.0.0', port=8742, + reload=True, forwarded_allow_ips='*', proxy_headers=True) From e4e40827480f37a7ab434281687df154f7b76c1d Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 16:44:10 -0700 Subject: [PATCH 2/6] Caching config in DataSourceHub API --- src/python/AgentHubAPI/app/dependencies.py | 6 ++-- src/python/AgentHubAPI/app/main.py | 6 ++-- src/python/AgentHubAPI/run.py | 10 ++++-- .../DataSourceHubAPI/DataSourceHubAPI.pyproj | 3 +- .../DataSourceHubAPI/app/dependencies.py | 31 +++++++++++++++---- src/python/DataSourceHubAPI/app/main.py | 7 +---- .../DataSourceHubAPI/app/routers/resolve.py | 18 +++++------ src/python/DataSourceHubAPI/run.py | 11 +++++++ 8 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 src/python/DataSourceHubAPI/run.py diff --git a/src/python/AgentHubAPI/app/dependencies.py b/src/python/AgentHubAPI/app/dependencies.py index e2ab757dbc..7d5ff1a00f 100644 --- a/src/python/AgentHubAPI/app/dependencies.py +++ b/src/python/AgentHubAPI/app/dependencies.py @@ -33,8 +33,6 @@ def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Ke Parameters ---------- - app_config : Configuration - Used for retrieving application configuration settings. x_api_key : str The X-API-Key value in the request header. @@ -52,7 +50,7 @@ def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Ke detail = 'Invalid API key. You must provide a valid API key in the X-API-KEY header.' ) -def handle_exception(exception: Exception): +def handle_exception(exception: Exception, status_code: int = 500): """ Handles an exception that occurred while processing a request. @@ -63,6 +61,6 @@ def handle_exception(exception: Exception): """ logging.error(exception, stack_info=True, exc_info=True) raise HTTPException( - status_code = 500, + status_code = status_code, detail = str(exception) ) from exception diff --git a/src/python/AgentHubAPI/app/main.py b/src/python/AgentHubAPI/app/main.py index c672406cec..fac71d4857 100644 --- a/src/python/AgentHubAPI/app/main.py +++ b/src/python/AgentHubAPI/app/main.py @@ -16,10 +16,8 @@ app = FastAPI( title='FoundationaLLM AgentHubAPI', summary='API for retrieving Agent metadata', - description= - """The FoundationaLLM AgentHubAPI is a wrapper around - AgentHub functionality contained in the - foundationallm.core Python SDK.""", + description="""The FoundationaLLM AgentHubAPI is a wrapper around AgentHub + functionality contained in the foundationallm Python SDK.""", version='1.0.0', contact={ 'name':'Solliance, Inc.', diff --git a/src/python/AgentHubAPI/run.py b/src/python/AgentHubAPI/run.py index c4b45c0f58..ff02b728de 100644 --- a/src/python/AgentHubAPI/run.py +++ b/src/python/AgentHubAPI/run.py @@ -1,5 +1,11 @@ import uvicorn if __name__ == '__main__': - uvicorn.run('app.main:app', host='0.0.0.0', port=8742, - reload=True, forwarded_allow_ips='*', proxy_headers=True) + uvicorn.run( + 'app.main:app', + host='0.0.0.0', + port=8742, + reload=True, + forwarded_allow_ips='*', + proxy_headers=True + ) diff --git a/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj b/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj index 7056e6b904..33e43f7c64 100644 --- a/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj +++ b/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj @@ -6,7 +6,7 @@ 637b74c9-aeb1-4b1a-8e92-20ac35d111eb . {1b580a1a-fdb3-4b32-83e1-6407eb2722e6};{349c5851-65df-11da-9384-00065b846f21};{888888a0-9f3d-457c-b088-3a5042f75d52} - app/main.py + run.py ..\PythonSDK . Standard Python launcher @@ -36,6 +36,7 @@ + diff --git a/src/python/DataSourceHubAPI/app/dependencies.py b/src/python/DataSourceHubAPI/app/dependencies.py index e4393d75ce..cbf0accfde 100644 --- a/src/python/DataSourceHubAPI/app/dependencies.py +++ b/src/python/DataSourceHubAPI/app/dependencies.py @@ -2,6 +2,7 @@ Provides dependencies for API calls. """ import logging +import time from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import APIKeyHeader @@ -18,17 +19,20 @@ def get_config() -> Configuration: Configuration Returns the application configuration settings. """ - return __config or Configuration() + global __config -def validate_api_key_header(config: Annotated[Configuration, Depends()], - x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): + start = time.time() + __config = __config or Configuration() + end = time.time() + print(f'Time to load config: {end-start}') + return __config + +def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): """ Validates that the X-API-Key value in the request header matches the key expected for this API. Parameters ---------- - app_config : Configuration - Used for retrieving application configuration settings. x_api_key : str The X-API-Key value in the request header. @@ -38,7 +42,7 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], Otherwise, returns False. """ - result = x_api_key == config.get_value('FoundationaLLM:APIs:DataSourceHubAPI:APIKey') + result = x_api_key == get_config().get_value('FoundationaLLM:APIs:DataSourceHubAPI:APIKey') if not result: logging.error('Invalid API key. You must provide a valid API key in the X-API-KEY header.') @@ -46,3 +50,18 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], status_code = 401, detail = 'Invalid API key. You must provide a valid API key in the X-API-KEY header.' ) + +def handle_exception(exception: Exception, status_code: int = 500): + """ + Handles an exception that occurred while processing a request. + + Parameters + ---------- + exception : Exception + The exception that occurred. + """ + logging.error(exception, stack_info=True, exc_info=True) + raise HTTPException( + status_code = status_code, + detail = str(exception) + ) from exception diff --git a/src/python/DataSourceHubAPI/app/main.py b/src/python/DataSourceHubAPI/app/main.py index 18038a2d0d..a500333976 100644 --- a/src/python/DataSourceHubAPI/app/main.py +++ b/src/python/DataSourceHubAPI/app/main.py @@ -2,7 +2,6 @@ Main entry-point for the FoundationaLLM DataSourceHubAPI. Runs web server exposing the API. """ -import uvicorn from fastapi import FastAPI from app.dependencies import get_config from app.routers import resolve, status @@ -18,7 +17,7 @@ title='FoundationaLLM DataSourceHubAPI', summary='API for retrieving DataSource metadata', description="""The FoundationaLLM DataSourceHubAPI is a wrapper around DataSourceHub - functionality contained in the foundationallm.core Python SDK.""", + functionality contained in the foundationallm Python SDK.""", version='1.0.0', contact={ 'name':'Solliance, Inc.', @@ -49,7 +48,3 @@ async def root(): Returns a JSON object containing a message and value. """ return { 'message': 'FoundationaLLM DataSourceHubAPI' } - -if __name__ == '__main__': - uvicorn.run('main:app', host='0.0.0.0', port=8842, - reload=True, forwarded_allow_ips='*', proxy_headers=True) diff --git a/src/python/DataSourceHubAPI/app/routers/resolve.py b/src/python/DataSourceHubAPI/app/routers/resolve.py index 25941610bb..236e7c1ee8 100644 --- a/src/python/DataSourceHubAPI/app/routers/resolve.py +++ b/src/python/DataSourceHubAPI/app/routers/resolve.py @@ -1,14 +1,16 @@ """ The API endpoint for returning the requested data source metadata. """ -import logging from typing import Optional -from fastapi import APIRouter, Depends, HTTPException, Header, Request +from fastapi import APIRouter, Depends, Header, Request from foundationallm.config import Context from foundationallm.models import AgentHint -from foundationallm.hubs.data_source import (DataSourceHubRequest, - DataSourceHubResponse, DataSourceHub) -from app.dependencies import validate_api_key_header +from foundationallm.hubs.data_source import ( + DataSourceHubRequest, + DataSourceHubResponse, + DataSourceHub +) +from app.dependencies import handle_exception, validate_api_key_header router = APIRouter( prefix='/resolve', @@ -49,8 +51,4 @@ async def resolve( return DataSourceHub(config=request.app.extra['config']).resolve(request=datasource_request, user_context=context, hint=agent_hint) return DataSourceHub(config=request.app.extra['config']).resolve(request=datasource_request, user_context=context) except Exception as e: - logging.error(e, stack_info=True, exc_info=True) - raise HTTPException( - status_code = 500, - detail = str(e) - ) from e + handle_exception(e) diff --git a/src/python/DataSourceHubAPI/run.py b/src/python/DataSourceHubAPI/run.py new file mode 100644 index 0000000000..979e4bdbbf --- /dev/null +++ b/src/python/DataSourceHubAPI/run.py @@ -0,0 +1,11 @@ +import uvicorn + +if __name__ == '__main__': + uvicorn.run( + 'app.main:app', + host='0.0.0.0', + port=8842, + reload=True, + forwarded_allow_ips='*', + proxy_headers=True + ) From e1ce423c5311e7a9e9c2e73a548a10e3e22e1252 Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 16:54:51 -0700 Subject: [PATCH 3/6] Caching config in GateKeeperIntegration and LangChain APIs. --- src/python/AgentHubAPI/app/routers/resolve.py | 2 +- .../app/dependencies.py | 20 +++++++----- src/python/LangChainAPI/LangChainAPI.pyproj | 3 +- src/python/LangChainAPI/app/dependencies.py | 31 +++++++++++++++---- src/python/LangChainAPI/app/main.py | 5 --- .../LangChainAPI/app/routers/orchestration.py | 13 +++----- src/python/LangChainAPI/run.py | 11 +++++++ 7 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 src/python/LangChainAPI/run.py diff --git a/src/python/AgentHubAPI/app/routers/resolve.py b/src/python/AgentHubAPI/app/routers/resolve.py index 6938a6047c..e4c4b5dc54 100644 --- a/src/python/AgentHubAPI/app/routers/resolve.py +++ b/src/python/AgentHubAPI/app/routers/resolve.py @@ -6,7 +6,7 @@ from foundationallm.config import Context from foundationallm.hubs.agent import AgentHub, AgentHubRequest, AgentHubResponse from foundationallm.models import AgentHint -from app.dependencies import validate_api_key_header, handle_exception +from app.dependencies import handle_exception, validate_api_key_header router = APIRouter( prefix='/resolve', diff --git a/src/python/GatekeeperIntegrationAPI/app/dependencies.py b/src/python/GatekeeperIntegrationAPI/app/dependencies.py index f3f65d4b99..f509f4056b 100644 --- a/src/python/GatekeeperIntegrationAPI/app/dependencies.py +++ b/src/python/GatekeeperIntegrationAPI/app/dependencies.py @@ -2,6 +2,7 @@ Provides dependencies for API calls. """ import logging +import time from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import APIKeyHeader @@ -18,17 +19,20 @@ def get_config() -> Configuration: Configuration Returns the application configuration settings. """ - return __config or Configuration() + global __config -def validate_api_key_header(config: Annotated[Configuration, Depends()], - x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): + start = time.time() + __config = __config or Configuration() + end = time.time() + print(f'Time to load config: {end-start}') + return __config + +def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): """ Validates that the X-API-Key value in the request header matches the key expected for this API. Parameters ---------- - app_config : Configuration - Used for retrieving application configuration settings. x_api_key : str The X-API-Key value in the request header. @@ -38,7 +42,7 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], Otherwise, returns False. """ - result = x_api_key == config.get_value('FoundationaLLM:APIs:GatekeeperIntegrationAPI:APIKey') + result = x_api_key == get_config().get_value('FoundationaLLM:APIs:GatekeeperIntegrationAPI:APIKey') if not result: logging.error('Invalid API key. You must provide a valid API key in the X-API-KEY header.') @@ -47,7 +51,7 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], detail = 'Invalid API key. You must provide a valid API key in the X-API-KEY header.' ) -def handle_exception(exception: Exception): +def handle_exception(exception: Exception, status_code: int = 500): """ Handles an exception that occurred while processing a request. @@ -58,6 +62,6 @@ def handle_exception(exception: Exception): """ logging.error(exception, stack_info=True, exc_info=True) raise HTTPException( - status_code = 500, + status_code = status_code, detail = str(exception) ) from exception diff --git a/src/python/LangChainAPI/LangChainAPI.pyproj b/src/python/LangChainAPI/LangChainAPI.pyproj index 61b5ab667a..5f4c1fb233 100644 --- a/src/python/LangChainAPI/LangChainAPI.pyproj +++ b/src/python/LangChainAPI/LangChainAPI.pyproj @@ -7,7 +7,7 @@ {1b580a1a-fdb3-4b32-83e1-6407eb2722e6};{349c5851-65df-11da-9384-00065b846f21};{888888a0-9f3d-457c-b088-3a5042f75d52} - app/main.py + run.py ..\PythonSDK . Standard Python launcher @@ -46,6 +46,7 @@ + diff --git a/src/python/LangChainAPI/app/dependencies.py b/src/python/LangChainAPI/app/dependencies.py index 76b445a2ff..be070b8926 100644 --- a/src/python/LangChainAPI/app/dependencies.py +++ b/src/python/LangChainAPI/app/dependencies.py @@ -2,6 +2,7 @@ Provides dependencies for API calls. """ import logging +import time from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import APIKeyHeader @@ -18,17 +19,20 @@ def get_config() -> Configuration: Configuration Returns the application configuration settings. """ - return __config or Configuration() + global __config -async def validate_api_key_header(config: Annotated[Configuration, Depends()], - x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))) -> bool: + start = time.time() + __config = __config or Configuration() + end = time.time() + print(f'Time to load config: {end-start}') + return __config + +async def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))) -> bool: """ Validates that the X-API-Key value in the request header matches the key expected for this API. Parameters ---------- - app_config : Configuration - Used for retrieving application configuration settings. x_api_key : str The X-API-Key value in the request header. @@ -38,7 +42,7 @@ async def validate_api_key_header(config: Annotated[Configuration, Depends()], Otherwise, returns False. """ - result = x_api_key == config.get_value('FoundationaLLM:LangChainAPI:Key') + result = x_api_key == get_config().get_value('FoundationaLLM:LangChainAPI:Key') if not result: logging.error('Invalid API key. You must provide a valid API key in the X-API-KEY header.') @@ -46,3 +50,18 @@ async def validate_api_key_header(config: Annotated[Configuration, Depends()], status_code = 401, detail = 'Invalid API key. You must provide a valid API key in the X-API-KEY header.' ) + +def handle_exception(exception: Exception, status_code: int = 500): + """ + Handles an exception that occurred while processing a request. + + Parameters + ---------- + exception : Exception + The exception that occurred. + """ + logging.error(exception, stack_info=True, exc_info=True) + raise HTTPException( + status_code = status_code, + detail = str(exception) + ) from exception diff --git a/src/python/LangChainAPI/app/main.py b/src/python/LangChainAPI/app/main.py index 80388d3caf..016fdc4000 100644 --- a/src/python/LangChainAPI/app/main.py +++ b/src/python/LangChainAPI/app/main.py @@ -2,7 +2,6 @@ Main entry-point for the FoundationaLLM LangChainAPI. Runs web server exposing the API. """ -import uvicorn from fastapi import FastAPI from app.dependencies import get_config from app.routers import orchestration, status @@ -49,7 +48,3 @@ async def root(): Returns a JSON object containing a message and value. """ return { 'message': 'FoundationaLLM LangChainAPI' } - -if __name__ == '__main__': - uvicorn.run('app.main:app', host='0.0.0.0', port=8765, reload=True, - forwarded_allow_ips='*', proxy_headers=True) diff --git a/src/python/LangChainAPI/app/routers/orchestration.py b/src/python/LangChainAPI/app/routers/orchestration.py index fc90c490bf..8d49cde54a 100644 --- a/src/python/LangChainAPI/app/routers/orchestration.py +++ b/src/python/LangChainAPI/app/routers/orchestration.py @@ -1,13 +1,12 @@ """ The API endpoint for returning the completion from the LLM for the specified user prompt. """ -import logging from typing import Optional -from fastapi import APIRouter, Depends, Header, HTTPException, Request +from fastapi import APIRouter, Depends, Header, Request from foundationallm.config import Context from foundationallm.models.orchestration import CompletionRequest, CompletionResponse from foundationallm.langchain.orchestration import OrchestrationManager -from app.dependencies import get_config, validate_api_key_header +from app.dependencies import handle_exception, validate_api_key_header # Initialize API routing router = APIRouter( @@ -32,6 +31,8 @@ async def get_completion( and generate a completion. request : Request The underlying HTTP request. + x_user_identity : str + The optional X-USER-IDENTITY header value. Returns ------- @@ -44,8 +45,4 @@ async def get_completion( context=Context(user_identity=x_user_identity)) return orchestration_manager.run(completion_request.user_prompt) except Exception as e: - logging.error(e, stack_info=True, exc_info=True) - raise HTTPException( - status_code = 500, - detail = str(e) - ) from e + handle_exception(e) diff --git a/src/python/LangChainAPI/run.py b/src/python/LangChainAPI/run.py new file mode 100644 index 0000000000..1db72d4e7c --- /dev/null +++ b/src/python/LangChainAPI/run.py @@ -0,0 +1,11 @@ +import uvicorn + +if __name__ == '__main__': + uvicorn.run( + 'app.main:app', + host='0.0.0.0', + port=8765, + reload=True, + forwarded_allow_ips='*', + proxy_headers=True + ) From 173ccbc2efc66c3a6703a06db6349b40c245567d Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 17:04:10 -0700 Subject: [PATCH 4/6] Caching config in PromptHubAPI --- src/python/PromptHubAPI/PromptHubAPI.pyproj | 3 +- src/python/PromptHubAPI/app/dependencies.py | 31 +++++++++++++++---- src/python/PromptHubAPI/app/main.py | 10 ++---- .../PromptHubAPI/app/routers/resolve.py | 11 ++----- src/python/PromptHubAPI/run.py | 11 +++++++ 5 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/python/PromptHubAPI/run.py diff --git a/src/python/PromptHubAPI/PromptHubAPI.pyproj b/src/python/PromptHubAPI/PromptHubAPI.pyproj index 4c05075405..d7687e9145 100644 --- a/src/python/PromptHubAPI/PromptHubAPI.pyproj +++ b/src/python/PromptHubAPI/PromptHubAPI.pyproj @@ -4,7 +4,7 @@ 2.0 5d5fc907-72ad-4026-aa8d-db6ba578ae0d . - app/main.py + run.py ..\PythonSDK . Standard Python launcher @@ -33,6 +33,7 @@ + diff --git a/src/python/PromptHubAPI/app/dependencies.py b/src/python/PromptHubAPI/app/dependencies.py index 61be4b0972..cdef71ef15 100644 --- a/src/python/PromptHubAPI/app/dependencies.py +++ b/src/python/PromptHubAPI/app/dependencies.py @@ -2,6 +2,7 @@ Provides dependencies for API calls. """ import logging +import time from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import APIKeyHeader @@ -18,17 +19,20 @@ def get_config() -> Configuration: Configuration Returns the application configuration settings. """ - return __config or Configuration() + global __config -def validate_api_key_header(config: Annotated[Configuration, Depends()], - x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): + start = time.time() + __config = __config or Configuration() + end = time.time() + print(f'Time to load config: {end-start}') + return __config + +def validate_api_key_header(x_api_key: str = Depends(APIKeyHeader(name='X-API-Key'))): """ Validates that the X-API-Key value in the request header matches the key expected for this API. Parameters ---------- - app_config : Configuration - Used for retrieving application configuration settings. x_api_key : str The X-API-Key value in the request header. @@ -38,7 +42,7 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], Otherwise, returns False. """ - result = x_api_key == config.get_value('FoundationaLLM:APIs:PromptHubAPI:APIKey') + result = x_api_key == get_config().get_value('FoundationaLLM:APIs:PromptHubAPI:APIKey') if not result: logging.error('Invalid API key. You must provide a valid API key in the X-API-KEY header.') @@ -46,3 +50,18 @@ def validate_api_key_header(config: Annotated[Configuration, Depends()], status_code = 401, detail = 'Invalid API key. You must provide a valid API key in the X-API-KEY header.' ) + +def handle_exception(exception: Exception, status_code: int = 500): + """ + Handles an exception that occurred while processing a request. + + Parameters + ---------- + exception : Exception + The exception that occurred. + """ + logging.error(exception, stack_info=True, exc_info=True) + raise HTTPException( + status_code = status_code, + detail = str(exception) + ) from exception diff --git a/src/python/PromptHubAPI/app/main.py b/src/python/PromptHubAPI/app/main.py index 2767ec4b44..46799d0766 100644 --- a/src/python/PromptHubAPI/app/main.py +++ b/src/python/PromptHubAPI/app/main.py @@ -2,7 +2,6 @@ Main entry-point for the FoundationaLLM PromptHubAPI. Runs web server exposing the API. """ -import uvicorn from fastapi import FastAPI from app.dependencies import get_config from app.routers import resolve, status @@ -17,9 +16,8 @@ app = FastAPI( title='FoundationaLLM PromptHubAPI', summary='API for retrieving Prompt metadata', - description="""The FoundationaLLM PromptHubAPI is a wrapper around - PromptHub functionality contained in the - foundationallm.core Python SDK.""", + description="""The FoundationaLLM PromptHubAPI is a wrapper around PromptHub + functionality contained in the foundationallm.core Python SDK.""", version='1.0.0', contact={ 'name':'Solliance, Inc.', @@ -50,7 +48,3 @@ async def root(): Returns a JSON object containing a message and value. """ return { 'message': 'FoundationaLLM PromptHubAPI' } - -if __name__ == '__main__': - uvicorn.run('main:app', host='0.0.0.0', port=8642, - reload=True, forwarded_allow_ips='*', proxy_headers=True) diff --git a/src/python/PromptHubAPI/app/routers/resolve.py b/src/python/PromptHubAPI/app/routers/resolve.py index 0d3bb6b352..0275341c90 100644 --- a/src/python/PromptHubAPI/app/routers/resolve.py +++ b/src/python/PromptHubAPI/app/routers/resolve.py @@ -1,13 +1,12 @@ """ The API endpoint for returning the appropriate agent prompt for the specified user prompt. """ -import logging from typing import Optional -from fastapi import APIRouter, Depends, HTTPException, Header, Request +from fastapi import APIRouter, Depends, Header, Request from foundationallm.config import Context from foundationallm.models import AgentHint from foundationallm.hubs.prompt import PromptHubRequest, PromptHubResponse, PromptHub -from app.dependencies import validate_api_key_header +from app.dependencies import handle_exception, validate_api_key_header router = APIRouter( prefix='/resolve', @@ -49,8 +48,4 @@ async def resolve( return PromptHub(config=request.app.extra['config']).resolve(request=prompt_request, user_context=context, hint=agent_hint) return PromptHub(config=request.app.extra['config']).resolve(prompt_request, user_context=context) except Exception as e: - logging.error(e, stack_info=True, exc_info=True) - raise HTTPException( - status_code = 500, - detail = str(e) - ) from e + handle_exception(e) diff --git a/src/python/PromptHubAPI/run.py b/src/python/PromptHubAPI/run.py new file mode 100644 index 0000000000..b130dd70e1 --- /dev/null +++ b/src/python/PromptHubAPI/run.py @@ -0,0 +1,11 @@ +import uvicorn + +if __name__ == '__main__': + uvicorn.run( + 'app.main:app', + host='0.0.0.0', + port=8642, + reload=True, + forwarded_allow_ips='*', + proxy_headers=True + ) From 5a892c7d8862c2e93d1a51c48739080f0d5f0a30 Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 17:07:22 -0700 Subject: [PATCH 5/6] Temporary fix for resolving configuration type --- .../PythonSDK/foundationallm/models/metadata/data_source.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/PythonSDK/foundationallm/models/metadata/data_source.py b/src/python/PythonSDK/foundationallm/models/metadata/data_source.py index 1e42e12441..6ef9ce5116 100644 --- a/src/python/PythonSDK/foundationallm/models/metadata/data_source.py +++ b/src/python/PythonSDK/foundationallm/models/metadata/data_source.py @@ -11,7 +11,8 @@ class DataSource(MetadataBase): configuration: Union[ CSVConfiguration, SQLDatabaseConfiguration, + CXOConfiguration, BlobStorageConfiguration, - SearchServiceConfiguration, - CXOConfiguration] + SearchServiceConfiguration + ] data_description: Optional[str] = None From a0676677a28fd764601ded70c78635954a47cb24 Mon Sep 17 00:00:00 2001 From: kylebunting Date: Sun, 14 Jan 2024 17:12:46 -0700 Subject: [PATCH 6/6] Caching config in GateKeeperIntegration API + removing startup.sh files. --- src/python/AgentHubAPI/AgentHubAPI.pyproj | 1 - src/python/AgentHubAPI/startup.sh | 1 - src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj | 1 - src/python/DataSourceHubAPI/startup.sh | 1 - .../GatekeeperIntegrationAPI.pyproj | 4 ++-- src/python/GatekeeperIntegrationAPI/app/main.py | 5 ----- src/python/GatekeeperIntegrationAPI/run.py | 11 +++++++++++ src/python/GatekeeperIntegrationAPI/startup.sh | 1 - src/python/LangChainAPI/LangChainAPI.pyproj | 1 - src/python/LangChainAPI/startup.sh | 1 - src/python/PromptHubAPI/PromptHubAPI.pyproj | 1 - src/python/PromptHubAPI/startup.sh | 1 - 12 files changed, 13 insertions(+), 16 deletions(-) delete mode 100644 src/python/AgentHubAPI/startup.sh delete mode 100644 src/python/DataSourceHubAPI/startup.sh create mode 100644 src/python/GatekeeperIntegrationAPI/run.py delete mode 100644 src/python/GatekeeperIntegrationAPI/startup.sh delete mode 100644 src/python/LangChainAPI/startup.sh delete mode 100644 src/python/PromptHubAPI/startup.sh diff --git a/src/python/AgentHubAPI/AgentHubAPI.pyproj b/src/python/AgentHubAPI/AgentHubAPI.pyproj index fe8d04ec2d..94eb97e7fc 100644 --- a/src/python/AgentHubAPI/AgentHubAPI.pyproj +++ b/src/python/AgentHubAPI/AgentHubAPI.pyproj @@ -40,7 +40,6 @@ - diff --git a/src/python/AgentHubAPI/startup.sh b/src/python/AgentHubAPI/startup.sh deleted file mode 100644 index f9c45a8039..0000000000 --- a/src/python/AgentHubAPI/startup.sh +++ /dev/null @@ -1 +0,0 @@ -gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app \ No newline at end of file diff --git a/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj b/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj index 33e43f7c64..8db0f2f9b4 100644 --- a/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj +++ b/src/python/DataSourceHubAPI/DataSourceHubAPI.pyproj @@ -42,7 +42,6 @@ - diff --git a/src/python/DataSourceHubAPI/startup.sh b/src/python/DataSourceHubAPI/startup.sh deleted file mode 100644 index f9c45a8039..0000000000 --- a/src/python/DataSourceHubAPI/startup.sh +++ /dev/null @@ -1 +0,0 @@ -gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app \ No newline at end of file diff --git a/src/python/GatekeeperIntegrationAPI/GatekeeperIntegrationAPI.pyproj b/src/python/GatekeeperIntegrationAPI/GatekeeperIntegrationAPI.pyproj index 9d5e859203..0418a3dac1 100644 --- a/src/python/GatekeeperIntegrationAPI/GatekeeperIntegrationAPI.pyproj +++ b/src/python/GatekeeperIntegrationAPI/GatekeeperIntegrationAPI.pyproj @@ -5,7 +5,7 @@ f74cbb5a-97b9-4f68-8077-8bab49c841dc - app/main.py + run.py ..\IntegrationSDK . . @@ -31,6 +31,7 @@ + @@ -40,7 +41,6 @@ - diff --git a/src/python/GatekeeperIntegrationAPI/app/main.py b/src/python/GatekeeperIntegrationAPI/app/main.py index a42e697002..b375ecd842 100644 --- a/src/python/GatekeeperIntegrationAPI/app/main.py +++ b/src/python/GatekeeperIntegrationAPI/app/main.py @@ -2,7 +2,6 @@ Main entry-point for the FoundationaLLM DataSourceHubAPI. Runs web server exposing the API. """ -import uvicorn from fastapi import FastAPI from app.dependencies import get_config from app.routers import analyze, status @@ -42,7 +41,3 @@ async def root(): Returns a JSON object containing a message and value. """ return { 'message': 'FoundationaLLM GatekeeperIntegrationAPI' } - -if __name__ == '__main__': - uvicorn.run('main:app', host='0.0.0.0', port=8042, reload=True, - forwarded_allow_ips='*', proxy_headers=True) diff --git a/src/python/GatekeeperIntegrationAPI/run.py b/src/python/GatekeeperIntegrationAPI/run.py new file mode 100644 index 0000000000..6370201c38 --- /dev/null +++ b/src/python/GatekeeperIntegrationAPI/run.py @@ -0,0 +1,11 @@ +import uvicorn + +if __name__ == '__main__': + uvicorn.run( + 'app.main:app', + host='0.0.0.0', + port=8042, + reload=True, + forwarded_allow_ips='*', + proxy_headers=True + ) diff --git a/src/python/GatekeeperIntegrationAPI/startup.sh b/src/python/GatekeeperIntegrationAPI/startup.sh deleted file mode 100644 index f9c45a8039..0000000000 --- a/src/python/GatekeeperIntegrationAPI/startup.sh +++ /dev/null @@ -1 +0,0 @@ -gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app \ No newline at end of file diff --git a/src/python/LangChainAPI/LangChainAPI.pyproj b/src/python/LangChainAPI/LangChainAPI.pyproj index 5f4c1fb233..e77658fa8b 100644 --- a/src/python/LangChainAPI/LangChainAPI.pyproj +++ b/src/python/LangChainAPI/LangChainAPI.pyproj @@ -37,7 +37,6 @@ - diff --git a/src/python/LangChainAPI/startup.sh b/src/python/LangChainAPI/startup.sh deleted file mode 100644 index 8dc12093c7..0000000000 --- a/src/python/LangChainAPI/startup.sh +++ /dev/null @@ -1 +0,0 @@ -gunicorn -w 4 -k uvicorn.workers.UvicornWorker app.main:app \ No newline at end of file diff --git a/src/python/PromptHubAPI/PromptHubAPI.pyproj b/src/python/PromptHubAPI/PromptHubAPI.pyproj index d7687e9145..d340e8ada7 100644 --- a/src/python/PromptHubAPI/PromptHubAPI.pyproj +++ b/src/python/PromptHubAPI/PromptHubAPI.pyproj @@ -39,7 +39,6 @@ - diff --git a/src/python/PromptHubAPI/startup.sh b/src/python/PromptHubAPI/startup.sh deleted file mode 100644 index f9c45a8039..0000000000 --- a/src/python/PromptHubAPI/startup.sh +++ /dev/null @@ -1 +0,0 @@ -gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app \ No newline at end of file