Ë
    ~j&  ã                  óF  — d Z ddlmZ ddl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Z G d„ d	e«      Zd
„ Zd9d„Zd:d„Zd;d<d„Zd=d„Zd>d„Zd?d„Zd@d„Zi dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“d$d%“d&d'“d(d)“d*d+“d,d-“d.d/“d0d1“ZdAd2„ZdBd3„Zdd4dd5d6d7œ	 	 	 	 	 	 	 	 	 dCd8„Zy)DuR  
GOLS - D-ID hosted talking-avatar integration
==============================================
Turns a still photo + our generated voice into a realistic talking video
(lips, subtle head/eye motion) via the D-ID API â€” no local GPU needed.

Flow:
  1. Upload the source image      -> POST /images   -> image url
  2. Upload our voice mp3          -> POST /audios   -> audio url
  3. Create a talk (image+audio)   -> POST /talks    -> talk id
  4. Poll until status == "done"   -> GET  /talks/id -> result_url (mp4)
  5. Download the result mp4

Auth: D-ID uses HTTP Basic. Put your key in backend/.env as DID_KEY. Accepts
either the ready-made token from the dashboard ("Basic <token>") or a raw
"email:api_key" pair (auto-encoded here).

Requires the `requests` package (falls back to httpx). Network calls are made by
YOUR backend to api.d-id.com.
é    )ÚannotationsN)ÚOptional)Úcfg)Úlogzhttps://api.d-id.comc                  ó   — e Zd Zy)ÚDIDErrorN)Ú__name__Ú
__module__Ú__qualname__© ó    úp/Users/priyanka/Documents/AI_Agent_Assessment/ai-video-generator-gols-v2-new/backend/app/services/did_service.pyr   r   #   s   „ Ør   r   c                 ób   — 	 dd l } d| fS # t        $ r Y nw xY w	 dd l}d|fS # t        $ r Y yw xY w)Nr   ÚrequestsÚhttpx)NN)r   Ú	Exceptionr   )r   r   s     r   Ú_httpr   (   sO   € ðÛØ˜HÐ%Ð%øÜò ÙðúðÛØ˜ÐÐøÜò ØØðús   ‚
 Š	•š" ¢	.­.c                 óz   — t        t        j                  xs dj                  «       «      xr t	        «       d   d uS )NÚ r   )Úboolr   ÚDID_KEYÚstripr   r   r   r   Ú
is_enabledr   6   s/   € Ü”—‘Ò" ×)Ñ)Ó+Ó,ÒG´³¸±À4Ð1GÐGr   c                 óÈ   — t         j                  xs dj                  «       } d| v r8d| dd  vr1t        j                  | j                  «       «      j                  «       } d| › �S )Nr   Ú:Ú=éýÿÿÿzBasic )r   r   r   Úbase64Ú	b64encodeÚencodeÚdecode)Úkeys    r   Ú_auth_headerr#   :   sX   € Ü�;‰;Ò˜"×
#Ñ
#Ó
%€Cà
ˆc�z�c  R S Ñ)Ü×Ñ˜sŸz™z›|Ó,×3Ñ3Ó5ˆØ�C�5ˆ>Ðr   c                ó.   — t        «       ddœ}| rd|d<   |S )Nzapplication/json)ÚAuthorizationÚacceptzcontent-type)r#   )Újson_ctÚhs     r   Ú_headersr)   B   s!   € Ü&›.Ð4FÑG€AÙØ.ˆˆ.ÑØ€Hr   c           
     óÚ  — t        «       \  }}t        › | › �}|dk(  rh|j                  ||t        d«      d¬«      }|j                  dk\  r+t        d| › d|j                  › d|j                  d d › �«      ‚|j                  «       S |j                  ||t        d«      d¬«      }|j                  dk\  r+t        d| › d|j                  › d|j                  d d › �«      ‚|j                  «       S )	Nr   Té<   )ÚjsonÚheadersÚtimeouté,  zPOST ú -> ú: )r   ÚBASE_URLÚpostr)   Ústatus_coder   Útextr,   )ÚpathÚpayloadÚnameÚlibÚurlÚrs         r   Ú
_post_jsonr<   J   sÝ   € Ü“�I€Dˆ#ÜˆJ�t�fÐ
€CØˆzÒØ�H‰H�S˜w´¸³ÈˆHÓKˆØ�=‰=˜CÒÜ˜U 4 &¨¨Q¯]©]¨O¸2¸a¿f¹fÀTÀc¸l¸^ÐLÓMÐMØ�v‰v‹xˆØ�‰�˜7¬H°T«NÀBˆÓG€AØ‡}�}˜ÒÜ˜˜t˜f D¨¯©¨°r¸!¿&¹&ÀÀ#¸,¸ÐHÓIÐIØ�6‰6‹8€Or   c           
     óü   — t        «       \  }}t        › | › �}|j                  |t        «       d¬«      }|j                  dk\  r+t        d| › d|j                  › d|j                  d d › �«      ‚|j                  «       S )Nr+   )r-   r.   r/   zGET r0   r1   )r   r2   Úgetr)   r4   r   r5   r,   )r6   r8   r9   r:   r;   s        r   Ú	_get_jsonr?   X   st   € Ü“�I€Dˆ#ÜˆJ�t�fÐ
€CØ�‰�œX›Z°ˆÓ4€AØ‡}�}˜ÒÜ˜˜d˜V 4¨¯© °b¸¿¹ÀÀ¸¸ÐGÓHÐHØ�6‰6‹8€Or   c           
     óÖ  — t        «       \  }}t        › |› �}t        j                  j	                  | «      }t        | d«      5 }|||fi}|j                  ||t        «       d¬«      }	ddd«       	j                  dk\  r+t        d|› d|	j                  › d|	j                  dd › �«      ‚|	j                  «       }
|
j                  d	«      }|st        d|› d
|
› �«      ‚|S # 1 sw Y   ŒyxY w)z?Multipart upload a file, return the hosted url D-ID gives back.Úrbéx   )Úfilesr-   r.   Nr/   zupload r0   r1   r:   z: no url in response )r   r2   Úosr6   ÚbasenameÚopenr3   r)   r4   r   r5   r,   r>   )r6   ÚfieldÚendpointr8   r9   r:   ÚfnameÚfhrC   r;   ÚdataÚus               r   Ú_uploadrM   a   sâ   € ä“�I€Dˆ#ÜˆJ�x�jÐ
!€CÜ�G‰G×Ñ˜TÓ"€EÜ	ˆd�DÔ	˜RØ˜ ˜Ð$ˆØ�H‰H�S ¬x«zÀ3ˆHÓGˆ÷ 
ð 	‡}�}˜ÒÜ˜  
¨$¨q¯}©}¨o¸RÀÇÁÀtÈÀ¸~ÐNÓOÐOØ�6‰6‹8€DØ�‰�‹€AÙÜ˜  
Ð*?À¸vÐFÓGÐGØ€H÷ 
Ð	ús   Á$CÃC(c                ó0  — t        «       \  }}|dk(  rk|j                  | dd¬«      5 }|j                  «        t        |d«      5 }|j	                  d«      D ]  }|j                  |«       Œ 	 d d d «       d d d «       y |j                  d| d¬«      5 }|j                  «        t        |d«      5 }|j                  «       D ]  }|j                  |«       Œ 	 d d d «       d d d «       y # 1 sw Y   Œ|xY w# 1 sw Y   y xY w# 1 sw Y   Œ*xY w# 1 sw Y   y xY w)	Nr   Té´   )Ústreamr.   Úwbi    ÚGET)r.   )r   r>   Úraise_for_statusrF   Úiter_contentÚwriterP   Ú
iter_bytes)r:   Úout_pathr8   r9   r;   ÚfÚchunks          r   Ú	_downloadrZ   r   sæ   € Ü“�I€Dˆ#ØˆzÒØ�W‰W�S ¨sˆWÔ3°qØ×ÑÔ Ü�h Ô%¨ØŸ^™^¨DÖ1�EØ—G‘G˜E•Nñ 2÷ &÷ 4Ð3ð �Z‰Z˜˜s¨CˆZÔ0°AØ×ÑÔ Ü�h Ô%¨ØŸ\™\ž^�EØ—G‘G˜E•Nñ ,÷ &÷ 1Ð0÷	 &Ð%ú÷ 4Ð3ú÷ &Ð%ú÷ 1Ð0úsG   §C4Á(C(Á-C4ÂDÂ/'D ÃDÃ(C1	Ã-C4Ã4C=Ä D		ÄDÄDÚen)zen-US-JennyNeuralzen-US-GuyNeuralÚhi)zhi-IN-SwaraNeuralzhi-IN-MadhurNeuralÚmr)zmr-IN-AarohiNeuralzmr-IN-ManoharNeuralÚta)zta-IN-PallaviNeuralzta-IN-ValluvarNeuralÚte)zte-IN-ShrutiNeuralzte-IN-MohanNeuralÚgu)zgu-IN-DhwaniNeuralzgu-IN-NiranjanNeuralÚbn)zbn-IN-TanishaaNeuralzbn-IN-BashkarNeuralÚkn)zkn-IN-SapnaNeuralzkn-IN-GaganNeuralÚml)zml-IN-SobhanaNeuralzml-IN-MidhunNeuralÚpa)úpa-IN-OjasNeuralre   Úur)zur-IN-GulNeuralzur-IN-SalmanNeuralÚes)zes-ES-ElviraNeuralzes-ES-AlvaroNeuralÚfr)zfr-FR-DeniseNeuralzfr-FR-HenriNeuralÚde)zde-DE-KatjaNeuralzde-DE-ConradNeuralÚja)zja-JP-NanamiNeuralzja-JP-KeitaNeuralÚzh)zzh-CN-XiaoxiaoNeuralzzh-CN-YunxiNeuralc                óœ   — t         j                  | xs dj                  «       t         d   «      \  }}|xs dj                  «       dk(  r|S |S )Nr[   r   Úfemale)Ú_DID_VOICESr>   Úlower)ÚlanguageÚgenderÚfemÚmales       r   Ú
_did_voicert   —   sH   € Ü—‘ Ò!1¨T× 8Ñ 8Ó :¼KÈÑ<MÓN�I€CˆØ’<˜R×&Ñ&Ó(¨HÒ4ˆ3Ð>¸$Ð>r   c                 ó  — t        «       d   €ddddœS t        j                  xs dj                  «       sddddœS 	 t	        d«      } | j                  d	«      }d
d
d|› d�|dœS # t        $ r}d
dt        |«      dœcY d}~S d}~ww xY w)zCLive diagnostic: verify the key works and report remaining credits.r   NFõ6   'requests' not installed â€” run: pip install requests)ÚenabledÚokÚdetailr   úDID_KEY not set in backend/.envz/creditsÚ	remainingTu   connected â€” z credits remaining)rw   rx   ry   Úcredits)r   r   r   r   r?   r>   r   Ústr)rK   r{   Úes      r   Úcheckr   œ   s§   € äƒwˆq�zÐØ ¨ØRñTð 	Tä�K‰KÒ˜2×$Ñ$Ô&Ø ¨Ð9ZÑ[Ð[ð@Ü˜Ó$ˆØ—H‘H˜[Ó)ˆ	Ø tØ*¨9¨+Ð5GÐHØ$ñ&ð 	&øô ò @Ø u¼¸A»Ñ?Õ?ûð@ús   ½&A$ Á$	BÁ-BÁ;BÂBrm   r/   g       @)Úscript_textrq   rp   Úpoll_timeoutÚpoll_intervalc               ób  — t        «       d   €yt        j                  xs dj                  «       sy| rt        j
                  j                  | «      sdd| › �fS 	 t        j                  d«       t        | d	d
«      }d}	|r2t        j
                  j                  |«      r	 t        |dd«      }
d|
dœ}	|	€|syd|dd dt        ||«      dœdœ}	t        j                  d|	d   «       t        d||	dddœdœ«      }|j                  d«      }|sdd|› �fS t        j                  d|«       t        j                  «       |z   }t        j                  «       |k  rèt!        d|› �«      }|j                  d «      }|d!k(  ry|j                  d"«      }|sy#t#        ||«       t        j
                  j                  |«      r9t        j
                  j%                  |«      d$kD  rt        j                  d%|«       y&y'|d(v rdd)|j                  d*«      xs |› �fS t        j&                  |«       t        j                  «       |k  rŒèdd+|› d,|› d-�fS # t        $ r!}t        j                  d|«       Y d}~�Œ½d}~ww xY w# t        $ r-}t        j(                  d.|«       dt+        |«      fcY d}~S d}~ww xY w)/a  
    Create a talking video from `image_path`. Tries our uploaded audio first;
    if the account/plan rejects audio scripts, falls back to a D-ID text script
    using a matching Microsoft neural voice.

    Returns (ok: bool, detail: str). On success out_path is written.
    r   N)Frv   r   )Frz   Fzsource image missing: u   [d-id] uploading image â€¦Úimagez/imagesÚaudioz/audios)ÚtypeÚ	audio_urlu6   [d-id] audio upload failed (%s) â€” trying text script)Fz3audio rejected and no script text for text fallbackr5   i¸  Ú	microsoft)r†   Úvoice_id)r†   ÚinputÚprovideru   [d-id] creating talk (%s) â€¦r†   z/talksTÚmp4)ÚstitchÚresult_format)Ú
source_urlÚscriptÚconfigÚidzno talk id in response: u%   [d-id] talk %s queued â€” polling â€¦z/talks/ÚstatusÚdoneÚ
result_url)Fztalk done but no result_urliè  z[d-id] done -> %s)Trx   )Fzdownloaded file empty)ÚerrorÚrejectedztalk failed: r–   ztalk z timed out after Úsz	[d-id] %s)r   r   r   r   rD   r6   Úisfiler   ÚinforM   r   Úwarningrt   r<   r>   Útimer?   rZ   ÚgetsizeÚsleepr–   r}   )Ú
image_pathÚ
audio_pathrW   r€   rq   rp   r�   r‚   Ú	image_urlr�   r‡   r~   ÚcreatedÚtalk_idÚdeadlinerš   r“   r•   s                     r   Úgenerate_talkr¥   ­   s   € ô ƒwˆq�zÐØNÜ�K‰KÒ˜2×$Ñ$Ô&Ø7Ùœ2Ÿ7™7Ÿ>™>¨*Ô5ØÐ.¨z¨lÐ;Ð;Ð;ð7Ü�‰Ð-Ô.Ü˜J¨°Ó;ˆ	ð ˆÙœ"Ÿ'™'Ÿ.™.¨Ô4ðYÜ# J°¸ÓC�	Ø")¸	ÑB�ð ˆ>ÙØSØ$¨{¸5¸DÐ/AØ+6Ü/9¸(ÀFÓ/Kñ#MñNˆFô 	�‰Ð0°&¸±.ÔAô ˜X°iØ28Ø=AØDIñ3Kñ(Ló Mˆð —+‘+˜dÓ#ˆÙØÐ4°W°IÐ>Ð>Ð>ä�‰Ð8¸'ÔBÜ—9‘9“; Ñ-ˆÜ�i‰i‹k˜HÒ$Ü˜w w iÐ0Ó1ˆDØ—X‘X˜hÓ'ˆFØ˜ÒØ!ŸX™X lÓ3�
Ù!Ø?Ü˜* hÔ/Ü—7‘7—>‘> (Ô+´·±·±ÀÓ0IÈDÒ0PÜ—H‘HÐ0°(Ô;Ø%Ø5ØÐ.Ñ.Ø ¨d¯h©h°wÓ.?Ò.GÀ4Ð-HÐIÐIÐIÜ�J‰J�}Ô%ô �i‰i‹k˜HÓ$ð ˜˜g˜YÐ&7¸°~ÀQÐGÐGÐGøôS ò YÜ—‘ÐTÐVW×XÒXûðYûôV ò Ü�	‰	�+˜qÔ!Ø”c˜!“fˆ}Õûðúsp   ÁAI8 Â!I Â3I8 Â8AI8 ÄA;I8 ÆA#I8 Ç5I8 È,I8 É 
I8 É	I5ÉI0É*I8 É0I5É5I8 É8	J.Ê"J)Ê#J.Ê)J.)Úreturnr   )r¦   r}   )F)r'   r   r¦   Údict)r6   r}   r7   r§   r¦   r§   )r6   r}   r¦   r§   )r6   r}   rG   r}   rH   r}   r¦   r}   )r:   r}   rW   r}   r¦   ÚNone)rp   r}   rq   r}   r¦   r}   )r¦   r§   )rŸ   r}   r    r}   rW   r}   r€   zOptional[str]rq   r}   rp   r}   r�   Úintr‚   Úfloat)Ú__doc__Ú
__future__r   r   rD   rœ   Útypingr   Ú
app.configr   Úapp.utils.loggerr   r2   r   r   r   r   r#   r)   r<   r?   rM   rZ   rn   rt   r   r¥   r   r   r   Ú<module>r°      s€  ðñõ* #ã Û 	Û Ý å Ý  à!€ô	ˆyô 	ò
óHóôóóóó"#ð"ØÐ
2ðàÐ
5ðð 	Ð
7ðð 	Ð
9ð	ð
 	Ð
5ðð 	Ð
8ðð 	Ð
9ðð 	Ð
4ðð 	Ð
7ðð 	Ð
2ðð 	Ð
3ðð 	Ð
6ðð 	Ð
5ðð 	Ð
5ðð 	Ð
5ðð  	Ð
7ð!€ó(?ó
@ð$ 37ÀhØ"&Ø&)À#ñIØ"/ðIØ@CðIàðIð !$ðIð ;@ôIr   