o
    8i                     @  sj   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
 ddlmZ ddlmZ G dd	 d	ZdS )
z;Runtime API gateway for tenant-aware SaaS request handling.    )annotationsN)Requestjsonify)get_platform_loggerlog_structured)build_request_context)resolve_tenantc                   @  s.   e Zd ZdZdddZdddZdddZdS )
APIGatewayz?Resolve tenant context and dispatch requests into app handlers.returnNonec                 C  s   t d| _d S )Napi_gateway)r   logger)self r   platform/gateway/api_gateway.py__init__   s   zAPIGateway.__init__flask_requestr   app_namestractionc                 C  sz  zt |}t||}W nr ty( } ztdt|ddfW  Y d}~S d}~w tyD } ztdt|ddfW  Y d}~S d}~w ty` } ztdt|ddfW  Y d}~S d}~w ty} } ztdd| ddfW  Y d}~S d}~ww |d	 r|d	 |krtdd
|d	  d| ddfS t| j	d|d |d d |d	 ||j
|j|d|jd
 | |||S )z:Handle one incoming request through the SaaS runtime flow.errorstatusmessagei  N  i  zGateway failure:   app_idzX-App-ID mismatch: header=z path=gateway_request
request_idtenant	tenant_iduser_id)r   r    r   r   methodpathr!   remote_addr)r   r   
ValueErrorr   r   LookupErrorPermissionError	Exceptionr   r   r"   r#   getr$   route_to_app)r   r   r   r   tenant_datacontextexcr   r   r   handle   sJ   """$
zAPIGateway.handler,   dict[str, object]c           
      C  s  t jd| d u rtdd| ddfS z
t d| }W n! tyB } ztdd| d| ddfW  Y d }~S d }~ww t|d	d }|d u rYtdd
| ddfS z|||}W n@ ty } z4t| jd|	dt
|	dtr|	dp~i 	dnd ||t|d tdt|ddfW  Y d }~S d }~ww t
|tr|\}}	t
|trt||	fS ||	fS t
|trt|S |S )Nzapps.r   zUnknown app: r   r   zFailed to load app z: r   handle_requestz$App does not expose handle_request: gateway_app_errorr   r   r    )r   r    r   r   r   )	importlibutil	find_specr   import_moduler(   getattrr   r   r)   
isinstancedictr   tuple)
r   r,   r   r   moduler-   handlerresultpayloadstatus_coder   r   r   r*   9   sD   *&"	


zAPIGateway.route_to_appN)r
   r   )r   r   r   r   r   r   )r,   r/   r   r   r   r   )__name__
__module____qualname____doc__r   r.   r*   r   r   r   r   r	      s
    

$r	   )rB   
__future__r   r2   importlib.utilflaskr   r    platform.logging.platform_loggerr   r    platform.routing.request_contextr    platform.routing.tenant_resolverr   r	   r   r   r   r   <module>   s    