
    s~j                       U d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ  ej        e          Z eddg          Z G d de          Z  G d de          Z!dZ"de#d<   d1dZ$e%                    de!d           ed           edd !          fd2d#            Z&e'                    d$           ed           edd !          fd3d(            Z(e'                    d)           ed*d+d,-           ed           edd !          fd4d0            Z)dS )5a  Brief API routes.

POST /api/v1/brief/run
    Body: {"trigger": "schedule"|"manual", "show_id": optional, "run_date": optional}
    Auth: Bearer token from `BRIEF_SERVICE_API_KEYS`.
    Returns: {"status":"processing", ...} synchronously, work runs in background.

GET /api/v1/brief/runs/{brief_run_id}
    Returns the city_briefs_runs row + linked city_briefs row + stage snapshot.

GET /api/v1/briefs
    Recent briefs (one row per show) for inspection.
    )annotationsN)date)Any)UUID)	APIRouterHeaderHTTPExceptionQuery)	BaseModelField)settings)OrchestrateBriefsService)today_in_app_tz)
brief_reporun_repoz/api/v1/briefbrief)prefixtagsc                  P    e Zd ZU  edd          Zded<   dZded<   dZd	ed
<   dS )BriefRunRequestmanualzschedule | manual)defaultdescriptionstrtriggerN
str | Noneshow_idzdate | Nonerun_date)__name__
__module____qualname__r   r   __annotations__r   r        m/Users/abstractioneditor2/ai-workstation/projects/automation/show-city-briefing-agent/app/api/routes_brief.pyr   r   $   sU         57JKKKGKKKKG H      r$   r   c                  v    e Zd ZU ded<    ee          Zded<    ee          Zded<   ded<   d	Zd
ed<   d	S )BriefRunResponser   status)default_factoryzlist[dict[str, Any]]briefsz	list[str]brief_run_ids
started_atNr   error)	r   r    r!   r"   r   listr*   r+   r-   r#   r$   r%   r'   r'   *   sq         KKK#(5#>#>#>F>>>>$uT:::M::::OOOEr$   r'   zOrchestrateBriefsService | None_active_serviceauthorizationr   	x_api_keyreturnNonec                v   d}| r{|                      dd          }t          |          dk    rR|d                                         dk    r4|d                                         r|d                                         }|s|r|                                }|r|t          j        vrt          dd	          dS )
zFAccept either `Authorization: Bearer <token>` or `X-API-Key: <token>`.N       r   beareri  zinvalid or missing API keystatus_codedetail)splitlenlowerstripr   accepted_api_keysr	   )r0   r1   	candidatepartss       r%   _authenticaterC   6   s     I )##C++u::??uQx~~//8;;a@P@P;a((I & &OO%%	 R	)CCC4PQQQQ DCr$   z/run   )response_modelr:   )r   z	X-API-Key)r   aliasbodyc           	     z  K   t          ||           t          j        }|s+t                              d           t          dd          | j        pt                      }t                      }	 |	                    | j
        |           d {V }|                                 d {V  n# |                                 d {V  w xY w|                    dg           }d |D             }t          |                    dd	          |||                    d
d          |                    d                    S )Nz2no BRIEF_SERVICE_API_KEYS configured; refusing runi  zservice not configuredr9   )r   r   r*   c                |    g | ]9}|                     d           t          |                     d                     :S )brief_run_id)getr   ).0bs     r%   
<listcomp>z run_pipeline.<locals>.<listcomp>[   s=    YYYA155CXCXYS~..//YYYr$   r(   okr,    r-   )r(   r*   r+   r,   r-   )rC   r   r@   loggerr-   r	   r   r   r   runr   acloserK   r'   )	rG   r0   r1   acceptedr   servicesummaryr*   r+   s	            r%   run_pipelinerW   C   s\      -+++)H NIJJJ4LMMMM}1 1 1H&((GDL8LLLLLLLLnngnn[[2&&FYYYYYM{{8T**#;;|R00kk'""   s   0"B- -C	z/runs/{brief_run_id}rJ   r   dict[str, Any]c                `  K   t          ||           t          j        |            d {V st          dd          d }                    d          r t          j        d                    d {V }d                             d                              d                              d          fdd	D                                 d
                              d                              d                              d                              d          |dS )Ni  zbrief_run_id not foundr9   r   rJ   	show_dater(   c                <    i | ]}|                     |          S r#   )rK   )rL   krun_rows     r%   
<dictcomp>zfetch_run.<locals>.<dictcomp>w   s1       1gkk!nn   r$   )
hub_lookupprevious_show_lookuphistorical_sales_lookupvoice_profile_loadyoutube_transcriptsperplexity_cityperplexity_newsopenai_fact_checkopenai_generationclaude_rankinghtml_generationvps_deploymenturl_verificationog_verificationr,   completed_atdurationr-   retry_count)rJ   r   rZ   r(   stagesr,   rm   rn   r-   ro   r   )rC   r   fetchr	   rK   r   fetch_by_show)rJ   r0   r1   r   r]   s       @r%   	fetch_runrs   e   sT      -+++N<00000000G N4LMMMME{{9 C .wy/ABBBBBBBB/;;y))[[--++h''    /
    kk,//N33KK
++W%%{{=11%  r$   z/briefs   r6   d   )r   gelelimitintc                   K   t          ||           t          j        |            d {V }t          |          |dS )N)rx   )countr*   )rC   r   recent_briefsr=   )rx   r0   r1   r*   s       r%   r|   r|      sQ       -++++%888888888F[[F333r$   )r0   r   r1   r   r2   r3   )rG   r   r0   r   r1   r   r2   r'   )rJ   r   r0   r   r1   r   r2   rX   )rx   ry   r0   r   r1   r   r2   rX   )*__doc__
__future__r   asynciologgingdatetimer   typingr   uuidr   fastapir   r   r	   r
   pydanticr   r   
app.configr   app.pipeline.orchestratorr   app.pipeline.stagesr   app.repositoriesr   r   	getLoggerr   rQ   routerr   r'   r/   r"   rC   postrW   rK   rs   r|   r#   r$   r%   <module>r      s     # " " " " "                     ; ; ; ; ; ; ; ; ; ; ; ; % % % % % % % %       > > > > > > / / / / / / 1 1 1 1 1 1 1 1		8	$	$	/		:	:	:! ! ! ! !i ! ! !    y    48 7 7 7 7
R 
R 
R 
R V$4#FF !'t 4 4 4"F4{CCC    GFB "## !'t 4 4 4"F4{CCC    $#D IraC000 &t 4 4 4"F4{CCC4 4 4 4 4 4 4r$   