11import logging
2+ from http import HTTPStatus
3+ from http .client import HTTPException
24from typing import Optional , Dict
35import uuid
46
57from fastapi import APIRouter , Body , Header , Request
68
7- from consts .exceptions import UnauthorizedError
9+ from consts .exceptions import UnauthorizedError , LimitExceededError , SignatureValidationError
810from services .northbound_service import (
911 NorthboundContext ,
1012 get_conversation_history ,
@@ -51,25 +53,28 @@ async def _parse_northbound_context(request: Request) -> NorthboundContext:
5153 request_body = ""
5254
5355 validate_aksk_authentication (request .headers , request_body )
54- except Exception as e :
55- raise UnauthorizedError (f"AK/SK authentication failed: { str (e )} " )
56+ except (UnauthorizedError , LimitExceededError , SignatureValidationError ) as e :
57+ raise e
58+ except Exception :
59+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error: cannot parse northbound context" )
60+
5661
5762 # 2. Parse JWT token
5863 auth_header = _get_header (request .headers , "Authorization" )
5964 if not auth_header :
60- raise UnauthorizedError ( " No authorization header found. Cannot authenticate. " )
65+ raise HTTPException ( status_code = HTTPStatus . UNAUTHORIZED , detail = "Unauthorized: No authorization header found" )
6166
6267 # Use auth_utils to parse JWT token
6368 try :
6469 user_id , tenant_id = get_current_user_id (auth_header )
6570
6671 if not user_id :
67- raise UnauthorizedError ( "Missing user_id in JWT token" )
72+ raise HTTPException ( status_code = HTTPStatus . UNAUTHORIZED , detail = "Unauthorized: missing user_id in JWT token" )
6873 if not tenant_id :
69- raise UnauthorizedError ( "No related tenant_id found with user_id in JWT token" )
74+ raise HTTPException ( status_code = HTTPStatus . UNAUTHORIZED , detail = "Unauthorized: unregistered user_id in JWT token" )
7075
71- except Exception as e :
72- raise UnauthorizedError ( f"Error occurred when parsing JWT: { str ( e ) } " )
76+ except Exception :
77+ raise HTTPException ( status_code = HTTPStatus . INTERNAL_SERVER_ERROR , detail = "Internal Server Error: cannot parse JWT token " )
7378
7479 request_id = _get_header (request .headers , "X-Request-Id" ) or str (uuid .uuid4 ())
7580
@@ -94,38 +99,84 @@ async def run_chat(
9499 query : str = Body (..., embed = True ),
95100 idempotency_key : Optional [str ] = Header (None , alias = "Idempotency-Key" ),
96101):
97- ctx : NorthboundContext = await _parse_northbound_context (request )
98- return await start_streaming_chat (
99- ctx = ctx ,
100- external_conversation_id = conversation_id ,
101- agent_name = agent_name ,
102- query = query ,
103- idempotency_key = idempotency_key ,
104- )
102+ try :
103+ ctx : NorthboundContext = await _parse_northbound_context (request )
104+ return await start_streaming_chat (
105+ ctx = ctx ,
106+ external_conversation_id = conversation_id ,
107+ agent_name = agent_name ,
108+ query = query ,
109+ idempotency_key = idempotency_key ,
110+ )
111+ except UnauthorizedError :
112+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
113+ except LimitExceededError :
114+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
115+ except SignatureValidationError :
116+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
117+ except Exception :
118+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
119+
105120
106121
107122@router .get ("/chat/stop/{conversation_id}" )
108123async def stop_chat_stream (request : Request , conversation_id : str ):
109- ctx : NorthboundContext = await _parse_northbound_context (request )
110- return await stop_chat (ctx = ctx , external_conversation_id = conversation_id )
124+ try :
125+ ctx : NorthboundContext = await _parse_northbound_context (request )
126+ return await stop_chat (ctx = ctx , external_conversation_id = conversation_id )
127+ except UnauthorizedError :
128+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
129+ except LimitExceededError :
130+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
131+ except SignatureValidationError :
132+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
133+ except Exception :
134+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
111135
112136
113137@router .get ("/conversations/{conversation_id}" )
114138async def get_history (request : Request , conversation_id : str ):
115- ctx : NorthboundContext = await _parse_northbound_context (request )
116- return await get_conversation_history (ctx = ctx , external_conversation_id = conversation_id )
139+ try :
140+ ctx : NorthboundContext = await _parse_northbound_context (request )
141+ return await get_conversation_history (ctx = ctx , external_conversation_id = conversation_id )
142+ except UnauthorizedError :
143+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
144+ except LimitExceededError :
145+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
146+ except SignatureValidationError :
147+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
148+ except Exception :
149+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
117150
118151
119152@router .get ("/agents" )
120153async def list_agents (request : Request ):
121- ctx : NorthboundContext = await _parse_northbound_context (request )
122- return await get_agent_info_list (ctx = ctx )
154+ try :
155+ ctx : NorthboundContext = await _parse_northbound_context (request )
156+ return await get_agent_info_list (ctx = ctx )
157+ except UnauthorizedError :
158+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
159+ except LimitExceededError :
160+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
161+ except SignatureValidationError :
162+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
163+ except Exception :
164+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
123165
124166
125167@router .get ("/conversations" )
126168async def list_convs (request : Request ):
127- ctx : NorthboundContext = await _parse_northbound_context (request )
128- return await list_conversations (ctx = ctx )
169+ try :
170+ ctx : NorthboundContext = await _parse_northbound_context (request )
171+ return await list_conversations (ctx = ctx )
172+ except UnauthorizedError :
173+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
174+ except LimitExceededError :
175+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
176+ except SignatureValidationError :
177+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
178+ except Exception :
179+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
129180
130181
131182@router .put ("/conversations/{conversation_id}/title" )
@@ -135,14 +186,24 @@ async def update_convs_title(
135186 title : str ,
136187 idempotency_key : Optional [str ] = Header (None , alias = "Idempotency-Key" ),
137188):
138- ctx : NorthboundContext = await _parse_northbound_context (request )
139- result = await update_conversation_title (
140- ctx = ctx ,
141- external_conversation_id = conversation_id ,
142- title = title ,
143- idempotency_key = idempotency_key ,
144- )
145- from fastapi .responses import JSONResponse
146-
147- headers_out = {"Idempotency-Key" : result .get ("idempotency_key" , "" ), "X-Request-Id" : ctx .request_id }
148- return JSONResponse (content = result , headers = headers_out )
189+ try :
190+ ctx : NorthboundContext = await _parse_northbound_context (request )
191+ result = await update_conversation_title (
192+ ctx = ctx ,
193+ external_conversation_id = conversation_id ,
194+ title = title ,
195+ idempotency_key = idempotency_key ,
196+ )
197+ from fastapi .responses import JSONResponse
198+
199+ headers_out = {"Idempotency-Key" : result .get ("idempotency_key" , "" ), "X-Request-Id" : ctx .request_id }
200+ return JSONResponse (content = result , headers = headers_out )
201+
202+ except UnauthorizedError :
203+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: AK/SK authentication failed" )
204+ except LimitExceededError :
205+ raise HTTPException (status_code = HTTPStatus .TOO_MANY_REQUESTS , detail = "Too Many Requests: rate limit exceeded" )
206+ except SignatureValidationError :
207+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = "Unauthorized: invalid signature" )
208+ except Exception :
209+ raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "Internal Server Error" )
0 commit comments