Ë
    ÿ�jk8  ã                   óX  — d Z ddlZddlZddlZddlZddlmZmZ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 dd	lmZ dd
lmZ ddlmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-  ej\                  e/«      Z0 eddg¬«      Z1 ejd                  e3«      ji                  «       jj                  jj                  dz  dz  Z6 ejd                  e3«      ji                  «       jj                  jj                  dz  dz  Z7 ejd                  e3«      ji                  «       jj                  jj                  dz  dz  Z8 G d„ de«      Z9 G d„ de«      Z:de;de;de;ddfd „Z<de;de;de;fd!„Z=e1j}                  d"«       ed#«       ed$«       ed$«      dfde;d%e?d&e?d'e
fd(„«       Z@e1j}                  d)«       ed#«       ed$«      dfde;d&e?d'e
fd*„«       ZAe1j…                  d+«      de;fd,„«       ZCe1j…                  d-«      dSde;d.eDfd/„«       ZEe1j…                  d0«      de;fd1„«       ZFe1j…                  d2«      	 	 dTde;d3e;d.eDd4eDfd5„«       ZGe1j‘                  d2«      de;fd6„«       ZIe1j…                  d7«      	 	 	 dUde;d8e;d3e;d9e;d.eDf
d:„«       ZJe1j…                  d;«      	 	 	 dVde;d<e;d8e;d3e;d9e;d.eDfd=„«       ZKe1j…                  d>e¬?«      d@„ «       ZLe1j…                  dAe¬?«      dB„ «       ZMe1j}                  dC«      dDe:fdE„«       ZNe1j…                  dF«      dG„ «       ZOe1j}                  dH«       ed#«       ed«       ed$«       ed#«      fde;dIe;dJe?dKefdL„«       ZPe1j…                  dM«      dNe;de;fdO„«       ZQe1j…                  dP«      dNe;de;fdQ„«       ZRe1j‘                  dP«      dNe;de;fdR„«       ZSy)Wz:The merchant-facing surface for the product pairing graph.é    N)Ú	APIRouterÚFileÚFormÚHTTPExceptionÚResponseÚ
UploadFile)ÚFileResponseÚHTMLResponse)Ú	BaseModel)ÚOperationalError©Úbuild_catalog)Ú
import_csv)ÚCsvFormatError)Újobs)ÚQuotaExceededError©Úpair_tenant)Údelete_all_productsÚdelete_product)Údisconnect_all_sources)Úrecord)Úget_productÚlist_anchorsÚlist_categoriesÚlist_pairingsÚlist_productsÚpairings_forz/catalogÚcatalog)ÚprefixÚtagsÚstaticzcatalog_admin.htmlúsample_products.csvzchat_ui.htmlc                   óD   — e Zd ZU eed<   eed<   eed<   eed<   dZeed<   y)Ú
DecisionInÚ
anchor_keyÚneighbor_keyÚ	pair_typeÚdecisionNÚ
decided_by)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__r*   © ó    ú./var/www/html/strategist-ai/app/api/catalog.pyr%   r%   %   s!   … ØƒOØÓØƒNØƒMØ€J�Ôr1   r%   c                   ó(   — e Zd ZU eed<   ee   ed<   y)ÚDecideInÚ	tenant_idÚ	decisionsN)r+   r,   r-   r.   r/   Úlistr%   r0   r1   r2   r4   r4   -   s   … ØƒNØ�JÑÔr1   r4   Újob_idr5   ÚkindÚreturnc              ƒ   ó<  ‡ ‡‡‡K  — ˆ fd„Š	 t         j                  j                  ˆˆˆfd„«      ƒ d{  –—† }t        j                  ‰ |¬«      ƒ d{  –—†  y7 Œ$7 Œ# t
        $ rV}t        j                  d|‰|j                  «       t        j                  ‰ |j                  ¬«      ƒ d{  –—†7   Y d}~yd}~wt        $ rV}t        j                  d|‰d¬	«       t        j                  ‰ t        |«      j                  ¬«      ƒ d{  –—†7   Y d}~yd}~ww xY w­w)
zFRuns a blocking job off the event loop, reporting progress as it goes.c                 ó4   •— t        j                  ‰| |«       y ©N)r   Útick)ÚpercentÚstepr8   s     €r2   Úprogressz_run.<locals>.progress4   s   ø€ ô
 	�	‰	�&˜' 4Õ(r1   c                  ó   •—  ‰ ‰‰¬«      S )N)rA   r0   )ÚfnrA   r5   s   €€€r2   ú<lambda>z_run.<locals>.<lambda>=   s   ø€ ‘B�y¨8Ô4€ r1   N)Úresultz"%s job stopped by quota for %s: %s©Úerrorz%s job failed for %sT©Úexc_info)ÚanyioÚ	to_threadÚrun_syncr   Úfinishr   ÚloggerÚinfoÚmessageÚ	ExceptionrG   Útyper+   )r8   r5   r9   rC   rE   ÚexrA   s   `` `  @r2   Ú_runrT   2   sÆ   ûè ø€ ô)ð;Ü—‘×/Ñ/Ý4ó6÷ 6ˆä�k‰k˜&¨Ô0×0Ñ0ð6øà0ùÜò 4ô 	�‰Ð8¸$À	È2Ï:É:ÔVÜ�k‰k˜&¨¯
©
Ô3×3Ö3ûÜò ;Ü�‰Ð+¨T°9ÀtˆÔLÜ�k‰k˜&¬¨R«×(9Ñ(9Ô:×:Ö:ûð;üs|   †D�'A ´AµA ÁAÁA ÁDÁA ÁA Á	DÁ&AB7Â,B/Â-B7Â2DÂ7DÃADÄ	DÄ
DÄDÄDÄDc           	   ƒ   óä  K  — 	 t        j                  | |«      ƒ d{  –—† }	 t        j                  t        || ||«      «       |S 7 Œ(# t         j                  $ r ‚ t        $ rB}t        j                  d|| d¬«       t        dddt        |«      j                  dœ¬	«      ‚d}~ww xY w# t        $ r; t        j                  d
|| d¬«       t        j                  |d¬«      ƒ d{  –—†7   ‚ w xY w­w)a  Takes the lock and schedules the work, or releases the lock trying.

    The window between create() and create_task() is small but real: an
    exception in it once left a tenant locked out of enrichment with no job
    running and nothing to release it until the TTL expired.
    Nz,Job store unavailable starting %s job for %sTrH   é÷  Újob_store_unavailablez5Could not reach the job store. Try again in a moment.©rG   rP   Úcause©Ústatus_codeÚdetailz Could not schedule %s job for %sÚSchedulingFailedrF   )r   ÚcreateÚJobAlreadyRunningÚDbUnavailablerN   rG   r   rR   r+   ÚasyncioÚcreate_taskrT   rQ   rM   )r5   r9   rC   r8   rS   s        r2   Ú	start_jobrc   J   sï   è ø€ ð)Ü—{‘{ 9¨dÓ3×3ˆðÜ×ÑœD ¨°D¸"Ó=Ô>ð €Mð- 4ùÜ×!Ñ!ò ØÜò 
)ô
 	�‰ÐCÀTÈ9Ø"ð 	ô 	$ä¨Ø,ØNÜ˜"“X×&Ñ&ñ5(ô )ð 	)ûð
)ûô ò Ü�‰Ð7¸¸yØ"ð 	ô 	$ä�k‰k˜&Ð(:Ô;×;Ñ;Øð	üsU   ‚C0„A �AžA £!B) ÁC0ÁA ÁB&Á$=B!Â!B&Â&C0Â)<C-Ã%C(Ã&C-Ã-C0z/build.FÚforceÚwaitÚresponsec              ƒ   ó  ‡ ‡‡K  — dˆfd„	Š|r,	 t         j                  j                  ˆˆ fd„«      ƒ d{  –—† S 	 t        ‰ d
‰«      ƒ d{  –—† }d|_        |ddœS 7 Œ&# t        $ r}t	        d|j
                  ¬«      ‚d}~wt        $ r=}t        j                  d‰ d¬«       t	        d	t        |«      j                  ¬«      ‚d}~ww xY w7 Œ~# t        j                  $ r}t	        dd|j                  dœ¬«      ‚d}~ww xY w­w)zÛSync, enrich and pair as one job -- the whole pipeline behind one button.

    The lock covers the entire build rather than each stage, so a second press
    cannot start pairing while the first is still enriching.
    Nc                 ó    •— t        | |‰¬«      S )N)rA   rd   r   )ÚtenantrA   rd   s     €r2   Úrunzbuild_endpoint.<locals>.runs   s   ø€ Ü˜V¨h¸eÔDÐDr1   c                  ó   •—  ‰ ‰«      S r=   r0   )rj   r5   s   €€r2   rD   z build_endpoint.<locals>.<lambda>x   s   ø€ ¹#¸i».€ r1   é’  rZ   zBuild failed for %sTrH   éö  Úbuildé™  Úalready_running©rG   r8   éÊ   Úqueued©r8   Ústatusr=   )rJ   rK   rL   r   r   rP   rQ   rN   rG   rR   r+   rc   r   r_   r8   r[   )r5   rd   re   rf   rS   r8   Úrunningrj   s   ``     @r2   Úbuild_endpointrw   k   sö   úè ø€ õEñ ð	KÜŸ™×1Ñ1Ô2HÓI×IÐIðCÜ  ¨G°SÓ9×9ˆð
 €HÔØ¨Ñ1Ð1ð JùÜ!ò 	DÜ¨C¸¿
¹
ÔCÐCûÜò 	KÜ�L‰LÐ.°	ÀDˆLÔIÜ¨C¼¸R»×8IÑ8IÔJÐJûð	Kúð
 :ùÜ×!Ñ!ò CÜ¨Ø&°'·.±.ñ5Bô Cð 	CûðCüsx   …	D�&A µA¶A ¹D»C ÁC
ÁC ÁDÁA Á	CÁ'A>Á>CÂ
8CÃCÃDÃ
C ÃC>ÃC9Ã9C>Ã>Dz/pairc              ƒ   ó¶  ‡ K  — |r+	 t         j                  j                  ˆ fd„«      ƒ d {  –—† S 	 t        ‰ dt        «      ƒ d {  –—† }d|_        |ddœS 7 Œ*# t        $ r=}t        j                  d‰ d¬«       t        dt        |«      j                  ¬«      ‚d }~ww xY w7 Œ[# t        j                  $ r}t        dd	|j                  d
œ¬«      ‚d }~ww xY w­w)Nc                  ó   •— t        ‰ «      S r=   r   ©r5   s   €r2   rD   zpair_endpoint.<locals>.<lambda>�   s   ø€ ¼+ÀiÓ:P€ r1   zPairing failed for %sTrH   rm   rZ   Úpairro   rp   rq   rr   rs   rt   )rJ   rK   rL   rQ   rN   rG   r   rR   r+   rc   r   r   r_   r8   r[   )r5   re   rf   rS   r8   rv   s   `     r2   Úpair_endpointr|   ‰   sÖ   øè ø€ ñ ð	KÜŸ™×1Ñ1Ó2PÓQ×QÐQð
CÜ  ¨F´KÓ@×@ˆð
 €HÔØ¨Ñ1Ð1ð RùÜò 	KÜ�L‰LÐ0°)ÀdˆLÔKÜ¨C¼¸R»×8IÑ8IÔJÐJûð	Kúð
 AùÜ×!Ñ!ò CÜ¨Ø&°'·.±.ñ5Bô Cð 	CûðCüsl   ƒC‡%A ¬A­A °C²B$ ÁB"ÁB$ ÁCÁA Á	BÁ"8BÂBÂCÂ"B$ Â$CÂ7CÃCÃCz/jobs/{job_id}c           	   ƒ   ó  K  — 	 t        j                  | «      ƒ d {  –—† }|€t        d	d
¬«      ‚|S 7 Œ# t        $ rA}t        j	                  d| d¬«       t        dddt        |«      j                  dœ¬«      ‚d }~ww xY w­w)Nz$Job store unavailable reading job %sTrH   rV   rW   z,Could not reach the job store. Keep polling.rX   rZ   é”  zJob not found)r   Úgetr`   rN   rG   r   rR   r+   )r8   ÚstaterS   s      r2   Újob_status_endpointr�       s…   è ø€ ð
)Ü—h‘h˜vÓ&×&ˆð €}Ü¨°OÔDÐDØ€Lð 'ùÜò )ô 	�‰Ð;¸VÈdˆÔSÜ¨Ø,ØEÜ˜"“X×&Ñ&ñ5(ô )ð 	)ûð)üs0   ‚B„4 œ2�4 ¡B²4 ´	A>½<A9Á9A>Á>Bz/jobsÚlimitc              ƒ   óJ   K  — t        j                  | |«      ƒ d {  –—† S 7 Œ­wr=   )r   Úrecent)r5   r‚   s     r2   Úrecent_jobs_endpointr…   ´   s   è ø€ ä—‘˜Y¨Ó.×.Ð.Ð.ús   ‚#œ!�#z/categoriesc              ƒ   ód   ‡ K  — t         j                  j                  ˆ fd„«      ƒ d {  –—† S 7 Œ­w)Nc                  ó   •— t        ‰ «      S r=   )r   rz   s   €r2   rD   z%categories_endpoint.<locals>.<lambda>»   s   ø€ ´/À)Ó2L€ r1   ©rJ   rK   rL   rz   s   `r2   Úcategories_endpointr‰   ¹   s#   øè ø€ ä—‘×)Ñ)Ó*LÓM×MÐMÐMús   ƒ&0©.ª0z	/productsÚcategoryÚoffsetc              ƒ   óp   ‡ ‡‡‡K  — t         j                  j                  ˆˆˆˆ fd„«      ƒ d {  –—† S 7 Œ­w)Nc                  ó"   •— t        ‰‰ ‰‰¬«      S )N)rŠ   r‚   r‹   )r   )rŠ   r‚   r‹   r5   s   €€€€r2   rD   z#products_endpoint.<locals>.<lambda>Â   s   ø€ ”˜i°(À%ÐPVÔW€ r1   rˆ   )r5   rŠ   r‚   r‹   s   ````r2   Úproducts_endpointrŽ   ¾   s1   ûè ø€ ô —‘×)Ñ)ÞWóY÷ Yð Yð Yús   †)6¯4°6c              ƒ   óh   ‡ K  — ˆ fd„}t         j                  j                  |«      ƒ d{  –—† S 7 Œ­w)aZ  Wipes every product, pairing, and embedding for a tenant, and
    disconnects every source it had connected -- a source left connected
    would just get silently re-crawled on the next build, repopulating
    exactly what this just deleted. Reconnecting a source (POST
    /sources/website, etc.) is what makes the next build add anything again.c                  ó:   •— t        ‰«      } t        ‰«      | d<   | S )NÚsources_disconnected)r   r   )Úcountsr5   s    €r2   Ú_wipez+delete_all_products_endpoint.<locals>._wipeÌ   s"   ø€ Ü$ YÓ/ˆÜ)?À	Ó)JˆÐ%Ñ&Øˆr1   Nrˆ   )r5   r“   s   ` r2   Údelete_all_products_endpointr”   Å   s)   øè ø€ ôô —‘×)Ñ)¨%Ó0×0Ð0Ð0ús   ƒ(2«0¬2z/pairings/anchorsru   Úscorec              ƒ   óÄ   ‡ ‡‡‡‡K  — 	 t         j                  j                  ˆˆˆˆˆ fd„«      ƒ d{  –—† S 7 Œ# t        $ r}t	        dt        |«      ¬«      ‚d}~ww xY w­w)a"  Products with matches, and how many of each state they hold.

    Backs a review screen that shows one product at a time -- a merchant thinks
    in products, so a flat list of every pair across the catalogue is not
    something they can work through.

    status   pending | approved | rejected | auto | all
    score    high | medium | low
    category a product category to narrow to

    Every anchor carries the full breakdown regardless of the filter, so a
    screen can show "4 pending, 2 approved" without asking again per product.
    c                  ó$   •— t        ‰‰‰‰ ‰¬«      S )N)r‚   ru   rŠ   r•   )r   )rŠ   r‚   r•   ru   r5   s   €€€€€r2   rD   z"anchors_endpoint.<locals>.<lambda>ç   s   ø€ ”L °%ÀØ*2¸%ôA€ r1   Né¦  rZ   ©rJ   rK   rL   Ú
ValueErrorr   r.   )r5   ru   rŠ   r•   r‚   rS   s   ````` r2   Úanchors_endpointr›   Ô   sY   üè ø€ ð"=Ü—_‘_×-Ñ-÷AóB÷ Bð 	Bð Bùô ò =Ü¨´C¸³GÔ<Ð<ûð=üs1   ‡A ‰)9 ²7³9 ¶A ·9 ¹	AÁAÁAÁA z	/pairingsr&   c              ƒ   óÈ   ‡ ‡‡‡‡‡K  — 	 t         j                  j                  ˆˆˆˆˆˆ fd„«      ƒ d{  –—† S 7 Œ# t        $ r}t	        dt        |«      ¬«      ‚d}~ww xY w­w)z¦The matches themselves, filtered the same way as the anchor list.

    Pass anchor_key for one product's review screen; leave it off for the whole
    catalogue.
    c                  ó&   •— t        ‰‰‰ ‰‰‰¬«      S )N)r‚   r&   ru   rŠ   r•   )r   )r&   rŠ   r‚   r•   ru   r5   s   €€€€€€r2   rD   z#pairings_endpoint.<locals>.<lambda>ù   s   ø€ ”M )°5ÀZØ)/¸(È%ôQ€ r1   Nr˜   rZ   r™   )r5   r&   ru   rŠ   r•   r‚   rS   s   `````` r2   Úpairings_endpointrž   î   s_   ýè ø€ ð=Ü—_‘_×-Ñ-÷Qð QóR÷ Rð 	Rð Rùô ò =Ü¨´C¸³GÔ<Ð<ûð=üs1   ˆA"Š*; ´9µ; ¸A"¹; »	AÁAÁAÁA"z/admin)Úresponse_classc               ƒ   ó²   K  — 	 t        t        j                  «       «      S # t        $ r* t        j                  dt        d¬«       t        dd¬«      ‚w xY w­w)Nz#Could not read the admin page at %sTrH   éô  zadmin page unavailablerZ   )r
   Ú
ADMIN_PAGEÚ	read_textÚOSErrorrN   rG   r   r0   r1   r2   Ú
admin_pager¥      sW   è ø€ ðNÜœJ×0Ñ0Ó2Ó3Ð3øÜò NÜ�‰Ð:¼JØ"ð 	ô 	$ä¨Ð4LÔMÐMðNüó   ‚A„!  A¡3AÁAz/democ               ƒ   ó²   K  — 	 t        t        j                  «       «      S # t        $ r* t        j                  dt        d¬«       t        dd¬«      ‚w xY w­w)Nz"Could not read the demo page at %sTrH   r¡   zdemo page unavailablerZ   )r
   Ú	DEMO_PAGEr£   r¤   rN   rG   r   r0   r1   r2   Ú	demo_pager©     sW   è ø€ ðMÜœI×/Ñ/Ó1Ó2Ð2øÜò MÜ�‰Ð9¼9Ø"ð 	ô 	$ä¨Ð4KÔLÐLðMür¦   z/pairings/decideÚpayloadc              ƒ   ó  ‡ ‡K  — ‰ j                   D �cg c]  }|j                  «       ‘Œ c}Š	 t        j                  j	                  ˆˆ fd„«      ƒ d {  –—† }d|iS c c}w 7 Œ# t
        $ r}t        dt        |«      ¬«      ‚d }~ww xY w­w)Nc                  ó0   •— t        ‰j                  ‰ «      S r=   )r   r5   )r6   rª   s   €€r2   rD   z!decide_endpoint.<locals>.<lambda>  s   ø€ ”F˜7×,Ñ,¨iÓ8€ r1   r˜   rZ   Úrecorded)r6   Ú
model_dumprJ   rK   rL   rš   r   r.   )rª   Údr­   rS   r6   s   `   @r2   Údecide_endpointr°     s{   ùè ø€ à)0×):Ñ):Ö; A�—‘•Ò;€Ið=ÜŸ™×1Ñ1Ü8ó:÷ :ˆð ˜Ð!Ð!ùò <ð:ùäò =Ü¨´C¸³GÔ<Ð<ûð=üsD   „B“AªB®&A$ ÁA"ÁA$ Á	BÁ"A$ Á$	BÁ-BÂBÂBz/sample.csvc               ƒ   ó.   K  — t        t        dd¬«      S ­w)Nztext/csvr#   )Ú
media_typeÚfilename)r	   Ú
SAMPLE_CSVr0   r1   r2   Úsample_csv_endpointrµ   $  s   è ø€ äœ
¨zØ!6ô8ð 8ùs   ‚z/import/csvÚcurrencyÚdry_runÚfilec              ƒ   óì  ‡ ‡‡‡‡K  — ‰j                  «       ƒ d {  –—† }|j                  dd¬«      Š	 t        j                  j	                  ˆˆˆˆ ˆfd„«      ƒ d {  –—† S 7 ŒF7 Œ# t
        $ r}t        dt        |«      ¬«      ‚d }~wt        $ r}t        d|j                  ¬«      ‚d }~wt        $ r=}t        j                  d‰ d	¬
«       t        dt        |«      j                  ¬«      ‚d }~ww xY w­w)Nzutf-8Úreplace)Úerrorsc                  ó8   •— t        ‰‰‰j                  ‰ ‰¬«      S )N)r·   )r   r³   )r¶   r·   r¸   r5   Útexts   €€€€€r2   rD   z%import_csv_endpoint.<locals>.<lambda>3  s   ø€ ”J˜y¨$°·±¸xÐQXÔY€ r1   r˜   rZ   rl   zCSV import failed for %sTrH   rm   )ÚreadÚdecoderJ   rK   rL   r   r   r.   r   rP   rQ   rN   rG   rR   r+   )r5   r¶   r·   r¸   ÚbodyrS   r½   s   ````  @r2   Úimport_csv_endpointrÁ   +  sÏ   üè ø€ ð —‘“×€DØ�;‰;�w yˆ;Ó1€DðGÜ—_‘_×-Ñ-ßYó[÷ [ð 	[ð øð[ùäò =Ü¨´C¸³GÔ<Ð<ûÜò @ô ¨°B·J±JÔ?Ð?ûÜò GÜ�‰Ð/°ÀTˆÔJÜ¨´D¸³H×4EÑ4EÔFÐFûðGüs\   ‡C4›A"œC4´)A& ÁA$ÁA& Á!C4Á$A& Á&	C1Á/BÂC1ÂB(Â(C1Â48C,Ã,C1Ã1C4z%/products/{product_key:path}/pairingsÚproduct_keyc              ƒ   óh   ‡ ‡K  — t         j                  j                  ˆ ˆfd„«      ƒ d {  –—† S 7 Œ­w)Nc                  ó   •— t        ‰‰ «      S r=   )r   ©rÂ   r5   s   €€r2   rD   z+product_pairings_endpoint.<locals>.<lambda>D  s   ø€ ´,¸yÈ+Ó2V€ r1   rˆ   rÅ   s   ``r2   Úproduct_pairings_endpointrÆ   B  s#   ùè ø€ ä—‘×)Ñ)Ô*VÓW×WÐWÐWús   „'2«0¬2z/products/{product_key:path}c              ƒ   óŠ   ‡ ‡K  — t         j                  j                  ˆ ˆfd„«      ƒ d {  –—† }|€t        dd¬«      ‚|S 7 Œ­w)Nc                  ó   •— t        ‰‰ «      S r=   )r   rÅ   s   €€r2   rD   z"product_endpoint.<locals>.<lambda>I  s   ø€ ´[ÀÈKÓ5X€ r1   r~   úProduct not foundrZ   ©rJ   rK   rL   r   )rÂ   r5   Úproducts   `` r2   Úproduct_endpointrÌ   G  s=   ùè ø€ ä—O‘O×,Ñ,Ô-XÓY×Y€GØ€Ü¨Ð4GÔHÐHØ€Nð Zús   „'A«A¬Ac              ƒ   ó�   ‡ ‡K  — t         j                  j                  ˆ ˆfd„«      ƒ d {  –—† }|st        dd¬«      ‚‰ ddœS 7 Œ­w)Nc                  ó   •— t        ‰‰ «      S r=   )r   rÅ   s   €€r2   rD   z)delete_product_endpoint.<locals>.<lambda>Q  s   ø€ ´^ÀIÈ{Ó5[€ r1   r~   rÉ   rZ   Údeleted)rÂ   ru   rÊ   )rÂ   r5   Úremoveds   `` r2   Údelete_product_endpointrÑ   O  sA   ùè ø€ ä—O‘O×,Ñ,Ô-[Ó\×\€GÙÜ¨Ð4GÔHÐHØ&°)Ñ<Ð<ð ]ús   „'A«A¬A)é   )Né2   r   )ÚpendingNNrÓ   )NrÔ   NNéd   )TÚ__doc__ra   ÚloggingÚpathlibrJ   Úfastapir   r   r   r   r   r   Úfastapi.responsesr	   r
   Úpydanticr   Úpsycopg2r   r`   Úapp.services.catalog.buildr   Úapp.services.catalog.csv_importr   Úapp.services.catalog.csv_sourcer   Úapp.services.infrar   Úapp.services.infra.quotasr   Úapp.services.pairing.jobr   Úapp.services.catalog.productsr   r   Úapp.services.catalog.sourcesr   Úapp.services.pairing.decisionsr   Úapp.services.pairing.queriesr   r   r   r   r   r   Ú	getLoggerr+   rN   ÚrouterÚPathÚ__file__ÚresolveÚparentr¢   r´   r¨   r%   r4   r.   rT   rc   ÚpostÚboolrw   r|   r   r�   Úintr…   r‰   rŽ   Údeleter”   r›   rž   r¥   r©   r°   rµ   rÁ   rÆ   rÌ   rÑ   r0   r1   r2   ú<module>rñ      sÑ  ðÙ @Û Û Û ã ß N× Nß 8Ý Ý 6å 4Ý 6Ý :Ý #Ý 8Ý 0ß MÝ ?Ý 1÷÷ ð
 
ˆ×	Ñ	˜8Ó	$€á	˜*¨I¨;Ô	7€ð ˆW�\‰\˜(Ó#×+Ñ+Ó-×4Ñ4×;Ñ;¸hÑFÐI]Ñ]€
ØˆW�\‰\˜(Ó#×+Ñ+Ó-×4Ñ4×;Ñ;¸hÑFÐI^Ñ^€
ØˆG�L‰L˜Ó"×*Ñ*Ó,×3Ñ3×:Ñ:¸XÑEÈÑV€	ô�ô ô ˆyô  ð
;�sð ; sð ;°#ð ;¸dó ;ð0˜sð ¨#ð °có ðB ‡�ˆXÓÙ*.¨s«)Á4ÈÃ;Ù&*¨5£kÈñ2 Cð 2¸Dð 2Ø#ð2Ø=Eò2ó ð2ð: ‡�ˆWÓÙ)-¨c«ÁÀeÃØ-1ñ2 3ð 2¸$ð 2Ø"*ò2ó ð2ð, ‡�ÐÓð cò ó ðð& ‡�ˆGÓñ/¨#ð /°cò /ó ð/ð ‡�ˆMÓðN¨ò Nó ðNð ‡�ˆKÓØOQØ+,ñY sð Y°cð YÈð YØ%(òYó ðYð ‡�ˆ{Óð
1°#ò 
1ó ð
1ð ‡�ÐÓ Ø9BØ>BØ(*ñ= cð =°3ð =Ø%(ð=Ø8;ð=à"%ò=ó !ð=ð2 ‡�ˆKÓØ>BØEIØ<?ñ= sð =¸ð =Ø$'ð=Ø?Bð=à#&ð=à69ò=ó ð=ð" ‡�ˆH \€Ó2ñNó 3ðNð ‡�ˆG L€Ó1ñMó 2ðMð ‡�ÐÓ ð" 8ò "ó !ð"ð ‡�ˆMÓñ8ó ð8ð ‡�ˆ]ÓÙ/3°C«yÉ$ÈtË*Ù.2°5«kÙ15°c³ñG¨ð GÀCð GØ'+ðGà$.òGó ðGð, ‡�Ð3Ó4ðX°ð XÀò Xó 5ðXð ‡�Ð*Ó+ð¨ð ¸ò ó ,ðð ‡�Ð-Ó.ð=¨sð =¸sò =ó /ñ=r1   