
    Bi B                     2   d Z ddlmZmZ ddlmZ ddlmZmZmZm	Z	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZ ee ed      f   Zee edd	      f   Zee edd
	      f   Zee eddd      f   Zee eddd      f   Zee edd      f   Zee edd      f   Zee edd      f   Zee ed      f   Z G d dee      Z  G d dee      Z! G d de      Z" G d de      Z# G d d e      Z$ G d! d"e      Z% G d# d$e      Z& G d% d&e      Z'y')(a4  
Revised Pydantic v2 models for Napkin AI API.

Changelog:
- Adopted Pydantic v2 features: strict types, field/model validators, Annotated constraints, and BaseModel config.
- Added strong validation for IDs, URLs, emails, language tags, and list bounds with patterns.
- Normalized response envelopes and enhanced error modeling with codes and details.
- Improved serialization settings (from_attributes, ser_json_timedelta/bytes) and schema examples.
- Added docstrings, field descriptions, and test-friendly snippets; redaction for sensitive fields.
- Ensured OpenAPI/JSON Schema compatibility and consistent naming conventions.

Model overview:
- VisualRequest: client request for visual generation, with constraints and PNG-specific rules.
- GeneratedFile: metadata for produced outputs.
- VisualResponse: detailed status with files, timestamps, and error message when present.
- StatusResponse: lightweight progress/status view.
- ErrorResponse: normalized error envelope with code/details and timestamp.
- RateLimitInfo: rate limits from headers with helper properties.
    )datetime	timedelta)Enum)	AnnotatedListOptionalDictAny)
	BaseModelFieldHttpUrl
StrictBoolStrictFloat	StrictInt	StrictStr	SecretStrfield_validatormodel_validator   )
min_lengthi  )r   
max_lengthi'     #   z#^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$r   r   pattern   @   z^[A-Za-z0-9_\-]+$   )geled   i   r   c                   $    e Zd ZdZdZdZdZdZdZy)RequestStatusz!Visual generation request status.pending
processing	completedfailedexpiredN)	__name__
__module____qualname____doc__PENDING
PROCESSING	COMPLETEDFAILEDEXPIRED     -/var/www/html/Napkin-AI-API/src/api/models.pyr$   r$   7   s    +GJIFGr4   r$   c                       e Zd ZdZdZdZy)OutputFormatzSupported output formats.svgpngN)r*   r+   r,   r-   SVGPNGr3   r4   r5   r7   r7   A   s    #
C
Cr4   r7   c                      e Zd ZU dZ edddg      Zeed<    eej                  ddg	      Z
eed
<    edd      Zee   ed<    edd      Zee   ed<    edd      Zee   ed<    edd      Zeed<    edd      Zeed<    edd      Zeed<    edd      Zeed<    edd      Zee   ed<    edd       Zee   ed!<    edd"      Zee   ed#<    edd$dd%&      Zeee      ed'<    edd(      Zee   ed)<    edd*dd%&      Zeee      ed+<    edd,d-.      Z ee!   ed/<    e"d01      d2        Z# e$d'      e%d3               Z& e$d+      e%d4               Z'd-d-d5d6d7ddd8dd9d:d;d<d=d>d-dd?gid@Z(y)AVisualRequestzRequest model for creating a visual.

    Notes:
    - PNG dimensions (width/height) are only allowed when format=png.
    - Lists, when provided, must not be empty and must contain non-empty identifiers.
    .z;The text content to generate visuals from (1..10000 chars).zMachine Learning PipelinedescriptionexamplescontentzDesired output format.r8   defaultr?   r@   formatNz;Optional context preceding the main content (<=5000 chars).rC   r?   context_beforez;Optional context following the main content (<=5000 chars).context_afterzAVisual style ID (built-in or custom, 8..64 chars, [A-Za-z0-9_-]).style_idzen-USz8Language code in BCP 47 format (e.g., en, en-US, fr-FR).languageFz-Enable transparent background for PNG output.transparent_backgroundz&Invert colors in the generated visual.inverted_colorr   z/Number of visual variations to generate (1..4).number_of_visualsz6PNG width in pixels (100..4096, only with format=png).widthz7PNG height in pixels (100..4096, only with format=png).heightz)Reference a single existing visual by ID.	visual_idz;Reference multiple existing visuals by ID (non-empty list).   rC   r?   r   r   
visual_idsz$Query for selecting a single visual.visual_queryz8Queries for selecting multiple visuals (non-empty list).visual_queriesz7Optional bearer token; excluded from serialized output.T)rC   r?   exclude	api_tokenaftermodec                     | j                   t        j                  k7  r#| j                  | j                  t        d      | S )z0Ensure width/height only set when format is PNG.0width and height can only be set when format=png)rD   r7   r;   rM   rN   
ValueErrorselfs    r5   _validate_png_dimensionsz&VisualRequest._validate_png_dimensions   s:     ;;,***zz%)@ !STTr4   c                 <    |t        |      dk(  rt        d      |S )Nr   z(visual_ids must not be empty if providedlenr\   clsvs     r5   _validate_visual_idsz"VisualRequest._validate_visual_ids   s$     =SVq[GHHr4   c                 <    |t        |      dk(  rt        d      |S )Nr   z,visual_queries must not be empty if providedra   rc   s     r5   _validate_visual_queriesz&VisualRequest._validate_visual_queries   s$     =SVq[KLLr4   floatbase64r@   CDQPRVVJCSTPRBBCD5Q6AWRr   )rA   rD   rH   rI   rL   zData flow diagramr9         )rA   rD   rM   rN   rJ   rK   )populate_by_namefrom_attributesser_json_timedeltaser_json_bytesjson_schema_extra))r*   r+   r,   r-   r   rA   LongText__annotations__r7   r:   rD   rF   r   	ShortTextrG   rH   IdStrrI   LangCoderJ   r   rK   rL   PositiveSmallIntrM   PngDimrN   rO   rR   r   rS   rT   rV   r   r   r_   r   classmethodrf   rh   model_configr3   r4   r5   r=   r=   H   s    Q-.GX 
 !  ,FL  +0Q+NHY'  */Q*M8I&  !&W!Hhuo  NHh  */C*J  "'<"NJ  +0E+'  $LE8F   %M FHV  "'?"Ix  ).Q	)Je%  ).:)L(9%  16N	1NHT)_-  &+M&Ix	"  '" # \"  #
 %&  ' !%":# 9 ')*  3#!!.2&+
Lr4   r=   c            	       r   e Zd ZU dZ edd      Zeed<    edd      Ze	e
   ed	<    edd
      Zeed<    edddd      Ze	e   ed<    edd      Ze	e   ed<    edd      Ze	e   ed<    edd      Ze	e   ed<    edd      Ze	e   ed<    eddddd      Ze	e   ed<   dd d!d"d#d$d%d&d'gid(Zy))GeneratedFilez%Metadata for a generated visual file..zUnique file identifier.r?   idNz;URL to download the file (requires Authorization; expires).rE   urlzFile format.rD   zHSuggested filename (optional; may be overridden by Content-Disposition).r   i   rQ   filenamezWidth in pixels (PNG only).rM   zHeight in pixels (PNG only).rN   zFile size in bytes (>=0).
size_byteszFile creation timestamp (UTC).
created_atz%Optional checksum (e.g., SHA256 hex).       z^[A-Fa-f0-9]+$)rC   r?   r   r   r   checksumTr@   z426614174000-wdjvjhwv8z`https://api.napkin.ai/v1/visual/123e4567-e89b-12d3-a456-426614174000/file/426614174000-wdjvjhwv8r8   z
visual.svgi  2025-01-01T12:00:00Z)r   r   rD   r   r   r   ro   rr   )r*   r+   r,   r-   r   r   rv   rt   r   r   r   rD   r7   r   r   rM   ry   rN   r   
BytesCountr   r   r   r{   r3   r4   r5   r}   r}      sF   /-B 
 #QC'	  !"FL 
 %*^	%Hhy!  $1E8F   %2 FHV  (-/(J$  &+4&J"  %*;!%Hhy!   2}# ,"("8	
Lr4   r}   c                      e Zd ZU dZ edd      Zeed<    edd      Ze	ed<    edd      Z
eed	<    ed
d      Zee   ed<    ed
d      Zee   ed<    eedd      Zee   ed<    ed
ddd      Zee   ed<   edefd       Zedefd       Zedefd       Zedefd       Zddd d!d"d#g d$d d%d"d&d'd(d)d*d+d,d-gd$gid.Zy
)/VisualResponsez3Response model for visual creation request outcome..zUnique request identifier.r~   
request_idzCurrent request status.statusz!Request creation timestamp (UTC).r   NzLast update timestamp (UTC).rE   
updated_atz#Request expiration timestamp (UTC).
expires_atz0List of generated files (empty until available).
   )default_factoryr?   r   filesz$Error message if the request failed.r     rQ   errorreturnc                 <    | j                   t        j                  k(  S )z(True if request reached COMPLETED state.)r   r$   r0   r]   s    r5   is_completedzVisualResponse.is_completed9  s     {{m5555r4   c                 <    | j                   t        j                  k(  S )z%True if request reached FAILED state.)r   r$   r1   r]   s    r5   	is_failedzVisualResponse.is_failed>  s     {{m2222r4   c                 <    | j                   t        j                  k(  S )z&True if request reached EXPIRED state.)r   r$   r2   r]   s    r5   
is_expiredzVisualResponse.is_expiredC  s     {{m3333r4   c                 x    | j                   t        j                  t        j                  t        j                  hv S )zBTrue if request is in a terminal state (completed/failed/expired).)r   r$   r0   r1   r2   r]   s    r5   is_terminalzVisualResponse.is_terminalH  s5     {{##  !!
 
 	
r4   Tr@   REQ_abcd1234r&   r   z2025-01-01T12:00:10Z)r   r   r   r   r   r'   2025-01-01T12:00:30ZFILE_abc123z-https://cdn.example.com/files/FILE_abc123.pngr9   rl   rm   iNF )r   r   rD   rM   rN   r   r   )r*   r+   r,   r-   r   r   rv   rt   r   r$   r   r   r   r   r   listr   r   r}   r   r   propertyboolr   r   r   r   r{   r3   r4   r5   r   r     s   =0J  "-FM  !7J  &+2&J"  &+9&J"  "'F"E4 
 "':	"E8I  6d 6 6 34 3 3 4D 4 4 
T 
 
  "0*"8"8 #1)"8"8 #0#R&+%)&)*0	
Lr4   r   c            
          e Zd ZU dZ edd      Zeed<    edd      Ze	ed<    edd	
      Z
ee   ed<    edd
      Zee   ed<    edd
      Zeed<    edd
      Zeed<    edd
      Zee   ed<    edddd      Zee   ed<    edd
      Zeeeeef         ed<    ed      d        Zdd d!d"d#d$d%dd&d'gid(Zy))StatusResponsez?Lightweight response for status polling and progress reporting..zRequest identifier.r~   r   zCurrent status.r   NzProgress percentage (0..100).rE   progresszStatus message (<=5000 chars).messager   zNumber of files ready (>=0).files_readyz%Total number of files expected (>=0).files_totalz#Estimated time remaining, if known.etazError message if failed.r   r   rQ   r   zQRaw files from API (generated_files/files). Client normalizes for download logic.r   rW   rX   c                     | j                   dk  s| j                  dk  rt        d      | j                  | j                   kD  r| j                   dk7  rt        d      | S )Nr   z(files_total and files_ready must be >= 0z%files_ready cannot exceed files_total)r   r   r\   r]   s    r5   _validate_file_countsz$StatusResponse._validate_file_counts  s[    a4#3#3a#7GHHd...43C3Cq3HDEEr4   Tiso8601r@   r   r&   g     @E@zRendering variants...   )r   r   r   r   r   r   )ro   rp   rr   )r*   r+   r,   r-   r   r   rv   rt   r   r$   r   r   PercentFloatr   ru   r   r   r   r   r   r   r   r   r   r	   strr
   r   r   r{   r3   r4   r5   r   r   q  s\   I)J  "%FM  (-3(Hh|$  $)4$GXi   $2K  $;K   %9 C)	  "'.	"E8I  -2g-E8Dc3h() 
 '" #  '"0* $6#$#$	
Lr4   r   c                      e Zd ZU dZ edddg      Zeed<    eddd	g
      Ze	e
e eddd      f      ed<    edd      Ze	e   ed<    edd      Ze	e   ed<    eej"                  d      Zeed<   dddd	ddidddgiiZy) ErrorResponsez'Normalized API error response envelope..zHuman-readable error message.zInvalid width for PNG formatr>   r   Nz5Machine-readable error code (e.g., VALIDATION_ERROR).VALIDATION_ERRORrB   r   r   z^[A-Z0-9_]+$r   codez/Additional error details (field errors, hints).rE   detailsz(Request ID if available for correlation.r   zError timestamp (UTC).)r   r?   	timestamprr   r@   r[   fieldrM   r   r   )r   r   r   r   r   )r*   r+   r,   r-   r   r   NonEmptyStrrt   r   r   r   r   r   dictr   rv   r   utcnowr   r{   r3   r4   r5   r   r     s    1301E;  	K$%		 	(ub/RR	
  $EGXd^  #(>#J    ,Ix  	O. '1"0!7

Lr4   r   c                       e Zd ZU dZ edd      Zeed<    edd      Zeed<    edd      Z	e
ed	<    ed
d      Zeee ed      f      ed<   edefd       ZdddddddgidZy
)RateLimitInfoz5Rate limit information derived from response headers..zRequest limit per window (>=0).r~   limitz+Remaining requests in current window (>=0).	remainingz(When the rate limit window resets (UTC).resetNz&Seconds to wait before retrying (>=0).rE   r   r"   retry_afterr   c                      | j                   dk  S )z.True when no remaining requests are available.r   )r   r]   s    r5   is_exceededzRateLimitInfo.is_exceeded  s     ~~""r4   Tr@   <   z2025-01-01T12:01:00Z   )r   r   r   r   r   )r*   r+   r,   r-   r   r   r   rt   r   r   r   r   r   r   r   r   r   r   r{   r3   r4   r5   r   r     s    ?5E:  "AIz  >E8  @E<@K)Iu{$:;< 
 #T # #
  !"3#%		
Lr4   r   N)(r-   r   r   enumr   typingr   r   r   r	   r
   pydanticr   r   r   r   r   r   r   r   r   r   r   ru   rs   rw   rv   rx   ry   r   r   r   r$   r7   r=   r}   r   r   r   r   r3   r4   r5   <module>r      sn  ( )  7 7   	5A#667i!!EEF	Yu EEF	Q2/UVX 	ub:NOO	 Yq(99: 	9est44	5eqS&99:y%1+-.
C 3 KI K\=I =@XY XvBY BJ*I *Z%I %r4   