
    _j@                        S r SSKrSSKJrJrJrJrJrJr  SSK	J
r
JrJrJrJrJrJr  SSKJrJrJrJr  SSKJr  SSK	Jr  S	\\\      S
\\   4S jrS\\\4   S
\\\4   4S jrSSSSSSSSS.S\S\\   S\\   S\\\\4      S\\   S\\   S\\   S\\   S\\   S\\   S
\4S jjr S0S\S\S\\   S
\4S jjrSS.S\S\S\\    S
\4S  jjr! S0S\S\S!\\   S\\   S
\\   4
S" jjr"S\S\S
\4S# jr#  S1S\S\S$\S%\\   S
\4
S& jjr$SSSSSSSSSSS'.
S\S\\   S\\   S\\\\4      S\\   S\\   S\\   S\\   S\\   S\\   S$\S%\\   S
\4S( jjr%S\\   S
\\   4S) jr&SSSSSSSS*.S\\   S\\   S\\\\4      S\\   S\\   S\\   S\\   S\\   S
\'4S+ jjr(S2S\\   S,\S
\\\      4S- jjr)    S3S\S\\   S\\   S,\S$\S%\\   S
\\   4S. jjr*S\S\S
\4S/ jr+g)4z4
Batch scraping functionality for Firecrawl v2 API.
    N)OptionalListCallableDictAnyUnion   )BatchScrapeRequestBatchScrapeResponseBatchScrapeJobScrapeOptionsDocumentWebhookConfigPaginationConfig)
HttpClienthandle_response_errorvalidate_scrape_optionsprepare_scrape_options)normalize_document_input)CrawlErrorsResponse	data_listreturnc                     / nU =(       d    /  H?  n[        U[        5      (       d  M  [        U5      nUR                  [	        S0 UD65        MA     U$ )N )
isinstancedictr   appendr   )r   	documentsdoc
normalizeds       O/home/rurouni/.local/lib/python3.13/site-packages/firecrawl/v2/methods/batch.py_parse_batch_scrape_documentsr"      sL     "IBc4  1#6JX3
34      bodyc                 t   U R                  S5      (       d  [        U R                  SS5      5      eU R                  S5      U R                  SS5      U R                  SS5      U R                  S5      U R                  S	5      U R                  S
5      [        U R                  S/ 5      =(       d    / 5      S.$ )NsuccesserrorUnknown error occurredstatus	completedr   totalcreditsUsed	expiresAtnextdatar)   r*   r+   credits_used
expires_atr.   r/   )get	Exceptionr"   )r$   s    r!   #_parse_batch_scrape_status_responser5      s    88I*BCDD ((8$XXk1-'1%/hh{+ -dhhvr.B.HbI r#   optionswebhookappend_to_idignore_invalid_urlsmax_concurrencyzero_data_retentionintegrationidempotency_keyclienturlsr7   r8   r9   r:   r;   r<   r=   r>   c                   [        UUUUUUUUS9n
U R                  U	5      nU R                  SXS9nUR                  (       d  [	        US5        UR                  5       nUR                  S5      (       d  [        UR                  SS5      5      e[        UR                  S5      UR                  S	5      UR                  S
5      =(       d    SS9$ )a#  
Start a batch scrape job for multiple URLs.

Args:
    client: HTTP client instance
    urls: List of URLs to scrape
    options: Scraping options
    
Returns:
    BatchScrapeResponse containing job information
    
Raises:
    FirecrawlError: If the batch scrape operation fails to start
r7   r8   r9   r:   r;   r<   r=   z/v2/batch/scrape)headerszstart batch scraper&   r'   r(   idurlinvalidURLsN)rD   rE   invalid_urls)	prepare_batch_scrape_request_prepare_headerspostokr   jsonr3   r4   r   )r?   r@   r7   r8   r9   r:   r;   r<   r=   r>   request_datarC   responser$   s                 r!   start_batch_scraperO   -   s    8 0!/'/	L %%o6G{{-|{MH ;;h(<= ==?D88I*BCDD88D>HHUOXXm,4 r#   job_idpagination_configc           
      l   U R                  SU 35      nUR                  (       d  [        US5        UR                  5       n[	        U5      nUS   nU(       a  UR
                  OSnU(       a  US   (       a  [        U US   UU5      n[        US   US   US   US	   US
   U(       d  US   US9$ SUS9$ )a7  
Get the status of a batch scrape job.

Args:
    client: HTTP client instance
    job_id: ID of the batch scrape job
    pagination_config: Optional configuration for pagination behavior
    
Returns:
    BatchScrapeJob containing job status and data
    
Raises:
    FirecrawlError: If the status check fails
/v2/batch/scrape/zget batch scrape statusr/   Tr.   r)   r*   r+   r1   r2   Nr0   )r3   rK   r   rL   r5   auto_paginate_fetch_all_batch_pagesr   )r?   rP   rQ   rN   r$   payloadr   rT   s           r!   get_batch_scrape_statusrW   g   s    ( zz-fX67H ;;h(AB ==?D1$7GI 8I%33dM*FO	
	 x +&g^,<($1WV_  8< r#   )request_timeoutnext_urlrX   c          
          U R                  XS9nUR                  (       d  [        US5        UR                  5       n[	        U5      n[        US   US   US   US   US   US   US	   S
9$ )a  
Fetch a single page of batch scrape results using the provided next URL.

Args:
    client: HTTP client instance
    next_url: Opaque next URL from a prior batch scrape status response
    request_timeout: Timeout (in seconds) for the HTTP request

Returns:
    BatchScrapeJob with the page data and next URL (if any)

Raises:
    Exception: If the request fails or returns an error response
)timeoutzget batch scrape status pager)   r*   r+   r1   r2   r.   r/   r0   )r3   rK   r   rL   r5   r   )r?   rY   rX   rN   r$   rV   s         r!   get_batch_scrape_status_pager\      s~    ( zz(z<H;;h(FG==?D1$7Gx +&g^,<(V_V_ r#   initial_documentsc                    UR                  5       nUnSnU(       a  UR                  OSnU(       a  UR                  OSnU(       a  UR                  OSn	[        R
                  " 5       n
U(       a  Ub  Xg:  a   U$ U	b  [        R
                  " 5       U
-
  U	:  a   U$ U R                  U5      nUR                  (       d4  SSKnUR                  S5      nUR                  SSUR                  0S9   U$ UR                  5       n [        U5      nUS    H(  nUb  [        U5      U:  a    OUR!                  U5        M*     Ub  [        U5      U:  a   U$ US   nUS	-  nU(       a  M  U$ ! [         a     U$ f = f)
a&  
Fetch all pages of batch scrape results.

Args:
    client: HTTP client instance
    next_url: URL for the next page
    initial_documents: Documents from the first page
    pagination_config: Optional configuration for pagination limits
    
Returns:
    List of all documents from all pages
r   N	firecrawlzFailed to fetch next pagestatus_code)extrar/   r.      )copy	max_pagesmax_resultsmax_wait_timetime	monotonicr3   rK   logging	getLoggerwarningr`   rL   r5   r4   lenr   )r?   rY   r]   rQ   r   current_url
page_countrd   re   rf   
start_timerN   ri   logger	page_datapage_payloaddocuments                    r!   rU   rU      s   $ "&&(IKJ 0A!++dI3D#//$K7H%33dM!J
!z'>H E %DNN,<z,I]+ZB = ::k*{{&&{3FNN6}hNbNb>cNd. + MMO		>yIL
 %V,H&3y>[+HX&	 - "s9~'D  #6*a
K +N %  	" %	s   E* *
E87E8c                     U R                  SU 35      nUR                  (       d  [        US5        UR                  5       nUR	                  S5      S:H  $ )z
Cancel a running batch scrape job.

Args:
    client: HTTP client instance
    job_id: ID of the batch scrape job to cancel
    
Returns:
    BatchScrapeStatusResponse with updated status
    
Raises:
    FirecrawlError: If the cancellation fails
rS   zcancel batch scraper)   	cancelled)deleterK   r   rL   r3   )r?   rP   rN   r$   s       r!   cancel_batch_scraperw   	  sO    $ }}09:H ;;h(=> ==?D88H,,r#   poll_intervalr[   c                    [         R                  " 5       n [        X5      nUR                  S;   a  U$ U(       a.  [         R                  " 5       U-
  U:  a  [	        SU SU S35      e[         R
                  " U5        Mj  )a  
Wait for a batch scrape job to complete, polling for status updates.

Args:
    client: HTTP client instance
    job_id: ID of the batch scrape job
    poll_interval: Seconds between status checks
    timeout: Maximum seconds to wait (None for no timeout)
    
Returns:
    BatchScrapeStatusResponse when job completes
    
Raises:
    FirecrawlError: If the job fails or timeout is reached
    TimeoutError: If timeout is reached
)r*   failedru   zBatch scrape job z did not complete within z seconds)rg   rh   rW   r)   TimeoutErrorsleep)r?   rP   rx   r[   ro   
status_jobs         r!   wait_for_batch_completionr~   &  s~    , !J
,V<
  DD (:5@!26(:ST[S\\deff 	

=! r#   )
r7   r8   r9   r:   r;   r<   r=   r>   rx   r[   c       
         V    [        U UUUUUUUUU	S9
nUR                  n[        XX5      $ )a  
Start a batch scrape job and wait for it to complete.

Args:
    client: HTTP client instance
    urls: List of URLs to scrape
    options: Scraping options
    poll_interval: Seconds between status checks
    timeout: Maximum seconds to wait (None for no timeout)
    
Returns:
    BatchScrapeStatusResponse when job completes
    
Raises:
    FirecrawlError: If the batch scrape fails to start or complete
    TimeoutError: If timeout is reached
r6   )rO   rD   r~   )r?   r@   r7   r8   r9   r:   r;   r<   r=   r>   rx   r[   startrP   s                 r!   batch_scraper   M  sL    B !/'/'E XXF % r#   c                 F   U (       d  [        S5      e/ nU  H  nU(       a  [        U[        5      (       d  [        SU 35      eUR                  S5      (       d$  UR                  S5      (       d  [        SU 35      eUR	                  UR                  5       5        M     U$ )z
Validate and normalize a list of URLs for batch scraping.

Args:
    urls: List of URLs to validate
    
Returns:
    Validated list of URLs
    
Raises:
    ValueError: If URLs are invalid
zURLs list cannot be emptyzInvalid URL: zhttp://zhttps://z)URL must start with http:// or https://: )
ValueErrorr   str
startswithr   strip)r@   validated_urlsrE   s      r!   validate_batch_urlsr     s     455N*S#..}SE233 y))S^^J-G-GHNOOciik*  r#   rB   c                L   [        U 5      nSU0n	U(       a#  [        U5      n
U
(       a  U	R                  U
5        Ub,  [        U[        5      (       a  X)S'   OUR                  SS9U	S'   Ub  X9S'   Ub  XIS'   Ub  XYS'   Ub  XiS'   Ub  [	        U5      R                  5       U	S	'   U	$ )
z
Prepare a batch scrape request payload.

Args:
    urls: List of URLs to scrape
    options: Scraping options
    
Returns:
    Request payload dictionary
r@   r8   T)exclude_none
appendToIdignoreInvalidURLsmaxConcurrencyzeroDataRetentionr=   )r   r   updater   r   
model_dumpr   )r@   r7   r8   r9   r:   r;   r<   r=   r   rM   scrape_datas              r!   rH   rH     s    * ).N$*N#;L ,W5, gs##&-#&-&8&8d&8&KL#%1\"&,?()")8%&&,?()&)+&6&<&<&>]#r#   
chunk_sizec                 n    / n[        S[        U 5      U5       H  nUR                  XX1-    5        M     U$ )z
Split a large list of URLs into smaller chunks for batch processing.

Args:
    urls: List of URLs to chunk
    chunk_size: Maximum size of each chunk
    
Returns:
    List of URL chunks
r   )rangerl   r   )r@   r   chunksis       r!   
chunk_urlsr     s8     F1c$i,dQ^,- -Mr#   c           	          [        X5      n/ nSnU HA  n	[        U U	UUUS9n
U
R                  (       a  UR                  U
R                  5        US-  nMC     U$ )a  
Process a large batch of URLs by splitting into smaller chunks.

Args:
    client: HTTP client instance
    urls: List of URLs to scrape
    options: Scraping options
    chunk_size: Size of each batch chunk
    poll_interval: Seconds between status checks
    timeout: Maximum seconds to wait per chunk
    
Returns:
    List of all scraped documents
    
Raises:
    FirecrawlError: If any chunk fails
r   )r7   rx   r[   rb   )r   r   r/   extend)r?   r@   r7   r   rx   r[   
url_chunksall_documentscompleted_chunkschunkresults              r!   process_large_batchr     sj    2 D-JM'
 ;;  -A   r#   c                 *   U R                  SU S35      nUR                  (       d  [        US5        UR                  5       nUR                  SU5      nUR                  S/ 5      UR                  SUR                  S/ 5      5      S.n[	        S	0 UD6$ )
z
Get errors for a batch scrape job.

Args:
    client: HTTP client instance
    job_id: ID of the batch scrape job

Returns:
    CrawlErrorsResponse with errors and robots-blocked URLs
rS   z/errorszget batch scrape errorsr/   errorsrobotsBlockedrobots_blocked)r   r   r   )r3   rK   r   rL   r   )r?   rP   rN   r$   rV   r    s         r!   get_batch_scrape_errorsr     s     zz-fXW=>H;;h(AB==?Dhhvt$G++h+!++ow{{CSUW7XYJ ,,,r#   )N)r	   N)d   )Nr   r	   N),__doc__rg   typingr   r   r   r   r   r   typesr
   r   r   r   r   r   r   utilsr   r   r   r   utils.normalizer   r   r"   r   r5   boolintrO   rW   floatr\   rU   rw   r~   r   r   r   rH   r   r   r   r   r#   r!   <module>r      s    = =   g f 6 'Xd3i-@ T(^ d38n c3h & (,37"&*.%)*.!%%)77
s)7 m$	7
 eC./07 3-7 "$7 c]7 "$7 #7 c]7 7z 59111   011 	1p (,	$$$ e_	$
 $V 59	DDD H~D   01	D
 
(^DN--- 
-@ !	$"$"$" $" c]	$"
 $"V (,37"&*.%)*.!%%)!33
s)3 m$	3
 eC./03 3-3 "$3 c]3 "$3 #3 c]3 3 c]3 3ld3i DI B (,37"&*.%)*.!%/
s)/ m$/ eC./0	/
 3-/ "$/ c]/ "$/ #/ 
/dT#Y C $tCy/ ( (,!--
s)- m$- 	-
 - c]- 
(^-`-J - -@S -r#   