
    SjjS                     R   d Z ddlZddl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mZmZ ddlmZmZmZmZ ddlmZ ded	dfd
Zded	efdZdeee      d	ee   fdZdeeef   d	eeef   fdZ deded	e
fdZ!	 d%dddededee   dee"   d	e	f
dZ#dddededee"   d	e	fdZ$	 d%dddededee   dee   dee"   d	ee   fdZ%deded	e&fdZ'	 	 d&dddedede(dee(   dee"   d	e	fdZ)	 	 d&dddedede(dee(   dee"   d	e	fdZ*deded	efd Z+d!ed"ed	efd#Z,ded	efd$Z-y)'z.
Crawling functionality for Firecrawl v2 API.
    N)OptionalDictAnyList   )CrawlRequestCrawlJobCrawlResponseDocumentCrawlParamsRequestCrawlParamsResponseCrawlParamsDataWebhookConfigCrawlErrorsResponseActiveCrawlsResponseActiveCrawlPaginationConfig)
HttpClienthandle_response_errorvalidate_scrape_optionsprepare_scrape_options)normalize_document_inputrequestreturnc                     | j                   r| j                   j                         st        d      | j                  | j                  dk  rt        d      | j                  t        | j                         yy)z
    Validate crawl request parameters.
    
    Args:
        request: CrawlRequest to validate
        
    Raises:
        ValueError: If request is invalid
    URL cannot be emptyNr   zLimit must be positive)urlstrip
ValueErrorlimitscrape_optionsr   )r   s    M/root/.hermes/venv/lib/python3.12/site-packages/firecrawl/v2/methods/crawl.py_validate_crawl_requestr#      sh     ;;gkk//1.//}} W]]a%7122 ) 6 67 *    c                    t        |        d| j                  i}| j                  r| j                  |d<   | j                  t	        | j                        }|r||d<   | j                  dd      }|j                  dd       |j                  dd       |j                  dd       | j                  It        | j                  t              r| j                  |d<   n| j                  j                  d	      |d<   d
ddddddddddddd}|j                         D ]  \  }}||v s|j                  |      ||<     |j                  |       d|v r)t        |d   t              r|d   j                         |d<   |S )z
    Prepare crawl request for API submission.
    
    Args:
        request: CrawlRequest to prepare
        
    Returns:
        Dictionary ready for API submission
    r   promptNscrapeOptionsT)exclude_noneexclude_unsetr!   webhook)r(   includePathsexcludePathsmaxDiscoveryDepthsitemapignoreQueryParametersdeduplicateSimilarURLscrawlEntireDomainallowExternalLinksallowSubdomainsdelaymaxConcurrencyregexOnFullURLzeroDataRetention)include_pathsexclude_pathsmax_discovery_depthr.   ignore_query_parametersdeduplicate_similar_urlscrawl_entire_domainallow_external_linksallow_subdomainsr4   max_concurrencyregex_on_full_urlzero_data_retentionintegration)r#   r   r&   r!   r   
model_dumppopr*   
isinstancestritemsupdater   )r   datascrape_datarequest_datafield_mappings
snake_case
camel_cases          r"   _prepare_crawl_requestrP   &   s    G$ 7;;D ~~ X ),W-C-CD$/D! %%4t%LL UD!Xt$%t, "goos+%ooDO &oo88d8KDO ('2#:$<2 4-+-2N" #1"6"6"8 <
J%+//
;D<
 	KKD,?!E"=1779]Kr$   	data_listc           
          g }| xs g D ]6  }t        |t              s|j                  t        di t	        |             8 |S )N )rF   dictappendr   r   )rQ   	documentsdoc_datas      r"   _parse_crawl_documentsrX   o   sJ     "IO Mh%XK(@(JKLM r$   response_datac                 Z   | j                  d      st        | j                  dd            | j                  d      | j                  dd      | j                  dd      | j                  dd      | j                  d	      | j                  d
      t        | j                  dg             dS )NsuccesserrorUnknown error occurredstatus	completedr   totalcreditsUsed	expiresAtnextrJ   r^   r_   r`   credits_used
expires_atrc   rJ   )get	ExceptionrX   )rY   s    r"   _parse_crawl_status_responseri   w   s    Y'))'3KLMM  ##H-"&&{A6""7A.%))-;#''4!!&)&}'8'8'DE r$   clientc                 @   t        |      }| j                  d|      }|j                  st        |d       |j	                         }|j                  d      r.|j                  d      |j                  d      d}t        d	i |S t        |j                  dd            )
aP  
    Start a crawl job for a website.
    
    Args:
        client: HTTP client instance
        request: CrawlRequest containing URL and options
        
    Returns:
        CrawlResponse with job information
        
    Raises:
        ValueError: If request is invalid
        Exception: If the crawl operation fails to start
    z	/v2/crawlzstart crawlr[   idr   )rl   r   r\   r]   rS   )rP   postokr   jsonrg   r
   rh   )rj   r   rL   responserY   job_datas         r"   start_crawlrr      s     *'2L{{;5H;;h6MMOM###D) $$U+

 (x(())'3KLMMr$   request_timeoutjob_idpagination_configrt   c          	         | j                  d| |      }|j                  st        |d       |j                         }t	        |      }|d   }|r|j
                  nd}|r>|d   r9|r$|j                  t        |      |j                  k\  st        | |d   |||      }t        |d	   |d
   |d   |d   |d   |s|d   |      S d|      S )aK  
    Get the status of a crawl job.

    Args:
        client: HTTP client instance
        job_id: ID of the crawl job
        pagination_config: Optional configuration for pagination behavior
        request_timeout: Timeout (in seconds) for each individual HTTP request. When auto-pagination 
            is enabled (default) and there are multiple pages of results, this timeout applies to 
            each page request separately, not to the entire operation

    Returns:
        CrawlJob with current status and data

    Raises:
        Exception: If the status check fails
    
/v2/crawl/timeoutzget crawl statusrJ   Trc   Nrs   r^   r_   r`   re   rf   rd   )
rg   rn   r   ro   ri   auto_paginatemax_resultslen_fetch_all_pagesr	   )	rj   ru   rv   rt   rp   rY   payloadrV   r{   s	            r"   get_crawl_statusr      s   2 zzJvh/zIH ;;h(:; MMOM*=9GI 8I%33dM))5	N/;;;$FO+
	 x +&g^,<($1WV_  8< r$   next_urlc          
          | j                  ||      }|j                  st        |d       |j                         }t	        |      }t        |d   |d   |d   |d   |d   |d   |d	   
      S )a  
    Fetch a single page of crawl results using the provided next URL.

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

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

    Raises:
        Exception: If the request fails or returns an error response
    ry   zget crawl status pager^   r_   r`   re   rf   rc   rJ   rd   )rg   rn   r   ro   ri   r	   )rj   r   rt   rp   rY   r   s         r"   get_crawl_status_pager      s    ( zz(Oz<H;;h(?@MMOM*=9Gx +&g^,<(V_V_ r$   initial_documentsc                   |j                         }|}d}|r|j                  nd}|r|j                  nd}	|r|j                  nd}
t	        j
                         }|r|||k\  r	 |S |
t	        j
                         |z
  |
kD  r	 |S | j                  ||      }|j                  s7ddl}|j                  d      }|j                  dd|j                  i       	 |S |j                         }	 t        |      }|d   D ]%  }|	t        |      |	k\  r n|j!                  |       ' |	t        |      |	k\  r	 |S |d	   }|d
z  }|r|S # t        $ r Y |S w xY w)a  
    Fetch all pages of crawl 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
        request_timeout: Optional timeout (in seconds) for the underlying HTTP request

    Returns:
        List of all documents from all pages
    r   Nry   	firecrawlzFailed to fetch next pagestatus_code)extrarJ   rc      )copy	max_pagesr|   max_wait_timetime	monotonicrg   rn   logging	getLoggerwarningr   ro   ri   rh   r}   rU   )rj   r   r   rv   rt   rV   current_url
page_countr   r|   r   
start_timerp   r   logger	page_datapage_payloaddocuments                     r"   r~   r~     s   * "&&(IKJ 0A!++dI3D#//$K7H%33dM!J
!zY'>J G %DNN,<z,I]+ZD ? ::k?:C{{&&{3FNN6}hNbNb>cNd0 - MMO		7	BL
 %V, 	'H&3y>[+HX&		' "s9~'D  #6*a
M P %  	" %	s   +E 	EEc                     | j                  d|       }|j                  st        |d       |j                         }|j	                  d      dk(  S )a  
    Cancel a running crawl job.
    
    Args:
        client: HTTP client instance
        job_id: ID of the crawl job to cancel
        
    Returns:
        bool: True if the crawl was cancelled, False otherwise
        
    Raises:
        Exception: If the cancellation fails
    rx   zcancel crawlr^   	cancelled)deletern   r   ro   rg   )rj   ru   rp   rY   s       r"   cancel_crawlr   \  sK     }}z&23H;;h7MMOMX&+55r$   poll_intervalrz   c                    t        j                         }	 t        | ||      }|j                  dv r|S |,t        j                         |z
  |kD  rt	        d| d| d      t        j
                  |       b)a  
    Wait for a crawl job to complete, polling for status updates.
    
    Args:
        client: HTTP client instance
        job_id: ID of the crawl job
        poll_interval: Seconds between status checks
        timeout: Maximum seconds to wait (None for no timeout)
        request_timeout: Optional timeout (in seconds) for each status request
        
    Returns:
        CrawlJob when job completes
        
    Raises:
        Exception: If the job fails
        TimeoutError: If timeout is reached
    rs   )r_   failedr   z
Crawl job z did not complete within z seconds)r   r   r   r^   TimeoutErrorsleep)rj   ru   r   rz   rt   r   	crawl_jobs          r"   wait_for_crawl_completionr   s  s    2 !J
$+
	 CC DNN$4z$AW#LF83LWIU]^__ 	

=!! r$   c                ^    t        | |      }|j                  }||n|}t        | ||||      S )a  
    Start a crawl job and wait for it to complete.
    
    Args:
        client: HTTP client instance
        request: CrawlRequest containing URL and options
        poll_interval: Seconds between status checks
        timeout: Maximum seconds to wait for the entire crawl job to complete (None for no timeout)
        request_timeout: Timeout (in seconds) for each individual HTTP request, including pagination 
            requests when fetching results. If there are multiple pages, each page request gets this timeout
        
    Returns:
        CrawlJob when job completes
        
    Raises:
        ValueError: If request is invalid
        Exception: If the crawl fails to start or complete
        TimeoutError: If timeout is reached
    rs   )rr   rl   r   )rj   r   r   rz   rt   r   ru   effective_request_timeouts           r"   crawlr     sH    8 FG,I\\F 4C3NT[ %1 r$   c                 ^   |j                   r|j                   j                         st        d      |j                  r|j                  j                         st        d      |j                   |j                  d}| j	                  d|      }|j
                  st        |d       |j                         }|j                  d      rL|j                  di       }i }dd	d
dddddddddd}d|v r)|d   }t        |t              rt        d%i ||d<   n||d<   |j                         D ]  \  }	}
|	|v s|	dk(  r||	   ||	   }i }ddddddd}|j                         D ]  \  }}||v s||   ||<    d|v r-|d   }t        |t              rdd lm}  ||!      |d<   n||d<   |j                         D ]  \  }}||vs|dk7  s|||<    |||
<   ||	   ||
<    |j                         D ]  \  }}||vs|||<    d"|v r|d"   |d"<   t!        d%i |S t#        |j                  d#d$            )&al  
    Get crawl parameters from LLM based on URL and prompt.
    
    Args:
        client: HTTP client instance
        request: CrawlParamsRequest containing URL and prompt
        
    Returns:
        CrawlParamsData containing suggested crawl options
        
    Raises:
        ValueError: If request is invalid
        Exception: If the operation fails
    r   zPrompt cannot be empty)r   r&   z/v2/crawl/params-previewzcrawl params previewr[   rJ   r8   r9   r:   r.   r;   r<   r=   r>   r?   r@   r!   rB   )r+   r,   r-   r.   r/   r0   r1   r2   r3   r5   r'   r7   r*   r'   include_tagsexclude_tagsonly_main_contentwait_forskip_tls_verificationremove_base64_images)includeTagsexcludeTagsonlyMainContentwaitForskipTlsVerificationremoveBase64Imagesformatsr   )ScrapeFormats)r   r   r\   r]   rS   )r   r   r   r&   rm   rn   r   ro   rg   rF   rT   r   rH   listtypesr   r   rh   )rj   r   rL   rp   rY   params_dataconverted_paramsrM   webhook_datarO   rN   scrape_opts_dataconverted_scrape_optsscrape_field_mappingsscrape_camelscrape_snakeformats_datar   keyvalues                       r"   crawl_params_previewr     s     ;;gkk//1.//>>!5!5!7122 {{..L {{5|DH ;;h(>? MMOM##''3 ++!6 %>&@!6"81/-!6
  #&y1L,-.;.Kl.K +.: +&4&:&:&< $	K"J
[(0[5L5X'2:'>$,.)'5'5+>#-/F.D-) 7L6Q6Q6S a2l'+;;BRS_B`1,?a
 !$44'7	'B%lD9=?LUa?b1)<?K1)< '7&<&<&> ?
U&;;y@P9>1#6? 4I$Z03>z3J$Z0I$	KN &++- 	.JC.((- %	.
 %*7	*BY'2!122))'3KLMMr$   http_clientcrawl_idc                 `   | j                  d| d      }|j                  st        |d       	 |j                         }|j                  d|      }|j                  dg       |j                  d|j                  dg             d}t	        di |S # t
        $ r}t        d	|       d
}~ww xY w)a-  
    Get errors from a crawl job.
    
    Args:
        http_client: HTTP client for making requests
        crawl_id: The ID of the crawl job
        
    Returns:
        CrawlErrorsResponse containing errors and robots blocked URLs
        
    Raises:
        Exception: If the request fails
    rx   z/errorszcheck crawl errorsrJ   errorsrobotsBlockedrobots_blocked)r   r   z'Failed to parse crawl errors response: NrS   )rg   rn   r   ro   r   rh   )r   r   rp   bodyr   
normalizedes          r"   get_crawl_errorsr   C  s     H:W=>H;;h(<=
G}}((64( kk(B/%kk/7;;GWY[;\]

 #0Z00 GA!EFFGs   A!B 	B-B((B-c                 :   | j                  d      }|j                  st        |d       |j                         }|j                  d      st	        |j                  dd            |j                  dg       }g }|D ]u  }t        |t              s|j                  |j                  d      |j                  d|j                  d	            |j                  d
      |j                  d      d       w t        d|D cg c]  }t        di | c}      S c c}w )z
    Get a list of currently active crawl jobs.
    
    Args:
        client: HTTP client instance
        
    Returns:
        ActiveCrawlsResponse containing a list of active crawl jobs
        
    Raises:
        Exception: If the request fails
    z/v2/crawl/activezget active crawlsr[   r\   r]   crawlsrl   teamIdteam_idr   options)rl   r   r   r   T)r[   r   rS   )
rg   rn   r   ro   rh   rF   rT   rU   r   r   )rj   rp   r   	crawls_innormalized_crawlscncs          r"   get_active_crawlsr   c  s     zz,-H;;h(;<==?D88I*BCDD2&I a$$eeDk55155+;<uuU|55+	&   Rc5dBk6GB6G5dee5ds   >D
)N)r   N).__doc__r   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   utilsr   r   r   r   utils.normalizer   r#   rT   rP   rX   rG   ri   rr   floatr   r   r~   boolr   intr   r   r   r   r   rS   r$   r"   <module>r      s    , ,    g f 68\ 8d 8*FL FT FRhtCy&9 d8n S#X 4S>  N
  N\  Nm  NL 59>
 (,>>>   01>
 e_> >J (,	$$$ e_	$
 $V 59	H (,HHH H~H   01	H e_H 
(^HV6 6S 6T 64 !	+" (,+"+"+" +" c]	+" e_+" +"b !	) (,))) ) c]	) e_) )XsN sN6H sN_ sNlG* G G@S G@ fj  f-A  fr$   