
    3filH                         d Z ddlZddlmZmZmZmZmZmZm	Z	 ddl
Z
ddl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 dZ G d	 d
e      Z G d de      Z G d de      Zy)z3Wrapper and Tool for the Google Maps Geocoding API.    N)AnyDictListLiteralOptionalTupleType)AsyncCallbackManagerForToolRunCallbackManagerForToolRun)BaseToolget_from_dict_or_env)	BaseModel
ConfigDictField	SecretStrmodel_validatorz1https://maps.googleapis.com/maps/api/geocode/jsonc                      e Zd ZU dZeed<    ed      Zeed<    ed      Z	eed<    ed      Z
eed<    ed      Zeed<    ed	      Zee   ed
<    ed      Zee   ed<    ed      Zeed<    ed      Zeed<    ed      ZdededdfdZdededdfdZdededdfdZdededdfdZdee   dee   fdZ	 	 	 d+ded
ee   dee   dedeeef   f
dZ	 	 	 d,d ee   d
ee   dee   d!eeeef      deeef   f
d"Z	 	 	 d,ded
ee   dee   d!eeeef      def
d#Zd$edefd%Z  e!d&'      e"d(edefd)              Z#	 	 d-ded
ee   dee   deeef   fd*Z$y).GoogleGeocodingAPIWrapperzWrapper for Google Maps Geocoding API.

    Provides methods for geocoding locations with configurable options for
    address components, geometry, metadata, and navigation points.
    google_api_keyTdefaultinclude_boundsinclude_navigationinclude_metadatainclude_address_componentsenlanguageusregion   max_retries   timeoutforbid)extracleanedresultreturnNc                     | j                   syg d}|j                  dg       D ]X  }|j                  dg       }|j                  d      }|D ].  }||v r	||d   |<   |dk(  s|j                  d      }||d   d	<   0 Z y)
z%Add address components if configured.N)street_numberroutelocalitycountrypostal_codeaddress_componentstypes	long_nameaddressadministrative_area_level_1
short_namestate)r   get)	selfr'   r(   address_types	componentr1   nametype_
state_names	            b/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_google_community/geocoding.py_add_componentsz)GoogleGeocodingAPIWrapper._add_components+   s    ..
  $8"= 	=IMM'2.E==-D =M)04GI&u-;;!*|!<J2<GI&w/=	=    c                     |j                  di       }| j                  r:|j                  d      r|d   |d   d<   |j                  d      r|d   |d   d<   yyy)z#Add geometry details if configured.geometryviewportboundsN)r7   r   r8   r'   r(   rB   s       r>   _add_geometryz'GoogleGeocodingAPIWrapper._add_geometryB   se    ::j"-||J'2::2F
#J/||H%080B
#H- & r@   c                     | j                   rJ|j                  di       }|j                  d      |j                  dg       |j                  d      d|d<   yy)zAdd metadata if configured.rB   place_idr1   location_type)rH   r1   rI   metadataN)r   r7   rE   s       r>   _add_metadataz'GoogleGeocodingAPIWrapper._add_metadataK   sR      zz*b1H"JJz2GR0"*,,"?#GJ !r@   c                     | j                   rL|j                  d      r:|j                  dg       D cg c]  }|d   |j                  dg       d c}|d<   yyyc c}w )z$Add navigation points if configured.navigation_pointslocationrestricted_travel_modes)rN   restrictions
navigationN)r   r7   )r8   r'   r(   points       r>   _add_navigationz)GoogleGeocodingAPIWrapper._add_navigationU   sk    ""vzz2E'F $ZZ(;R@%
  !&j 1$)II.G$L%GL! (G"%s   Aresultsc                 B   g }|D ]  }|sd|j                  dd      id|j                  di       j                  di       id}| j                  ||       | j                  ||       | j                  ||       | j	                  ||       |j                  |        |S )zClean and format results.fullformatted_address rN   rB   )r3   rB   )r7   r?   rF   rK   rS   append)r8   rT   cleaned_resultsr(   r'   s        r>   clean_resultsz'GoogleGeocodingAPIWrapper.clean_results`   s     	,F #FJJ/BB$GH

:r : > >z2 NG   &1w/w/  &1""7+#	,& r@   querymax_resultsc                    	 |j                         sddg dS |j                  d      D cg c]#  }|j                         s|j                         % }}t        |      |kD  r|d| }| j                  |||      }|j	                  d      dk7  r&|j	                  dd      |j	                  d	d
      g dS dt        |j	                  dg             | j                  |j	                  dg             ||xs | j                  |xs | j                  ddS c c}w # t        $ r:}dt        |      g ||xs | j                  |xs | j                  ddcY d}~S d}~ww xY w)a/  Process geocoding request and return results.

        Handles both single and batch geocoding requests with detailed location data.

        Args:
            query: Location(s) to geocode (e.g., `'Eiffel Tower'` or
                `'Times Square, Central Park'`).
            language: Language code for results (e.g., `'en'`, `'fr'`, `'ja'`).
            region: Region bias (e.g., `'us'`, `'fr'`, `'jp'`).
            max_results: Maximum number of results to return.

        Returns:
            status (str): Request status (`'OK'` or error status).
            total_results (int): Number of locations found.
            results (list): Location data with address, geometry, metadata, and
                navigation.
            query_info (dict): Query metadata (original query, language, region).
        ERROREmpty query providedstatusmessagerT   ,Nr\   r   r    rb   OKerror_messagezNo results foundrT   )original_queryr   r    rb   total_resultsrT   
query_info)rb   rc   rT   rk   )
stripsplitlenraw_resultsr7   r[   r   r    	Exceptionstr)	r8   r\   r   r    r]   qqueriesro   es	            r>   rT   z!GoogleGeocodingAPIWrapper.resultsy   sj   2-	;;=%5!  +0++c*:HQaggiqwwyHGH7|k)!,;/**hv + K x(D0)ooh@*@RS!  !$[__Y%C!D--kooi.LM&+ ( 9DMM$3		 	 I4  
	!q6&+ ( 9DMM$3		 	
	sA   D D DDA"D 6AD D 	E#/EEE	locations
componentsc                    |sddg dS g }g }|D ]q  }	 | j                  ||||      }|j                  d      dk(  r|j                  |       n3|j                  ||j                  d      |j                  d      d       s |rdndt        |      | j                  |D 
cg c])  }
|
j                  d
      s|
j                  d
g       d   + c}
      |t        |      t        |      t        |      |xs | j                  |xs | j                  ddS # t        $ r)}	|j                  |dt	        |	      d       Y d	}	~	5d	}	~	ww xY wc c}
w )a  Process multiple locations in batch.

        Args:
            locations: List of locations (e.g., `["Eiffel Tower", "Times Square"]`).
            language: Language code for results.
            region: Region bias.
            components: Component filters (e.g., `{"country": "US"}`).

        Returns:
            status (str): Overall batch status.
            total_results (int): Number of successful results.
            results (list): Location data for successful queries.
            errors (list): Errors encountered with query, status, and message.
            query_info (dict): Batch metadata (total, successful, failed counts).
        r_   zNo locations providedra   )r\   r   r    rv   rb   rf   rg   )r\   rb   rc   NrT   r   )total_queries
successfulfailedr   r    )rb   rj   rT   errorsrk   )	ro   r7   rY   rp   rq   rn   r[   r   r    )r8   ru   r   r    rv   rT   r{   rN   r(   rt   rs              r>   batch_geocodez'GoogleGeocodingAPIWrapper.batch_geocode   sh   , !2  ! 	YHY))"%!)	 *  ::h'4/NN6*MM%-&,jj&:'-zz/'B	Y. &d7 \))29NQQUU9=My"%a(N !$Y!'lf+$5 /DKK
 	
  YGPSTUPVWXXY Os$   A.D!E8E	E	 EE	c                    	 |j                         sddg dS |j                         | j                  j                         |xs | j                  |xs | j                  d}|r)dj                  d |j                         D              |d<   t        | j                        D ]  }	 t        j                  t        || j                        }|j                          |j                         }|j                  d	      d
k(  r|c S || j                  dz
  k(  r5|j                  d	      | j                  |j                  d	            g dc S  	 ddg dS # t        j                   j"                  $ r5}	|| j                  dz
  k(  rddt%        |	       g dcY d}	~	c S Y d}	~	d}	~	ww xY w# t&        $ r}	ddt%        |	       g dcY d}	~	S d}	~	ww xY w)z-Get raw results with improved error handling.r_   r`   rb   rg   rT   r3   keyr   r    |c              3   0   K   | ]  \  }}| d |   yw):N ).0kvs      r>   	<genexpr>z8GoogleGeocodingAPIWrapper.raw_results.<locals>.<genexpr>"  s#      0#'1aqc1#J0s   rv   paramsr$   rb   rf      REQUEST_ERRORzRequest failed: NzProcessing error: zAll retry attempts failed)rl   r   get_secret_valuer   r    joinitemsranger"   requestsr7   GOOGLE_MAPS_API_URLr$   raise_for_statusjson_get_error_message
exceptionsRequestExceptionrq   rp   )
r8   r\   r   r    rv   r   attemptresponsedatart   s
             r>   ro   z%GoogleGeocodingAPIWrapper.raw_results  s   6	;;=%%;!  !;;=**;;=$5 /DKK	F '*xx 0+5+;+;+=0 (|$ !!1!12 '||+FDLL H --/#==?Dxx)T1# D$4$4q$88&*hhx&8-1-D-D $ 2. (*   9F 8
 	
!  **;; $"2"2Q"66&5/?Ax-H')   7  	!#5c!fX!> 	sm   F( BF( %AE F( AEF( 
F( F%0#F F%F( F(  F%%F( (	G1GGGrb   c                 @    dddddddd}|j                  |d	|       S )
z0Get detailed error message based on status code.zNo results found for this queryzAPI key quota exceededzQuery limit exceededz!Request was denied, check API keyzInvalid request parameterszToo many locations in requestzServer error, please try again)ZERO_RESULTSOVER_DAILY_LIMITOVER_QUERY_LIMITREQUEST_DENIEDINVALID_REQUESTMAX_ELEMENTS_EXCEEDEDUNKNOWN_ERRORzAPI Error: )r7   )r8   rb   error_messagess      r>   r   z,GoogleGeocodingAPIWrapper._get_error_messageN  s<     > 8 6A;%D=
 !!&Kx*@AAr@   before)modevaluesc                 *    t        |dd      }||d<   |S )z,Validate that api key exists in environment.r   GOOGLE_MAPS_API_KEYr   )clsr   r   s      r>   validate_environmentz.GoogleGeocodingAPIWrapper.validate_environment[  s)     .$&;
 $2 r@   c                   K   	 |j                         | j                  j                         |xs | j                  xs d|xs | j                  xs dd}t        j                  | j                        }t        j                         4 d{   }|j                  t        ||      4 d{   }|j                          d{   }|j                  d      dk(  r5| j                  |||      cddd      d{    cddd      d{    S |j                  dd      |j                  d	d
      g dcddd      d{    cddd      d{    S 7 7 7 7 d7 U7  7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY w# t        $ r}	ddt        |	       g dcY d}	~	S d}	~	ww xY ww)aN  Geocode query asynchronously.

        Args:
            query: Location(s) to geocode.
            language: Language code for results.
            region: Region bias.

        Returns:
            status (str): Request status.
            results (list): Geocoding results.
            query_info (dict): Request metadata.
        rX   r   )totalNr   rb   rf   r_   rg   zRequest failedr   zAsync request failed: )rl   r   r   r   r    aiohttpClientTimeoutr$   ClientSessionr7   r   r   rT   rp   rq   )
r8   r\   r   r    r   timeout_objsessionr   r   rt   s
             r>   geocode_asyncz'GoogleGeocodingAPIWrapper.geocode_asynce  s    $	 ;;=**;;=$;; 5DKK52	&F "//dllCK,,.  '";;' '  
 
!)0Dxx)T1#||E8VD
 
 
   #'((8W"=)-/CS)T#%
 
 
  
 1


 
 
      	!#9#a&!B 	s7  GB	F& EF& F.E/F2E*E *E*1F=E">FF& E$F& G%E*9FE&F
F& E(F& GF& F E*"F$F& &F(F& *E<	0E31E<	8F?F& 
FF& GF#FF#F& "G#F& &	G/G GGGG)NN
   )NNN)NN)%__name__
__module____qualname____doc__r   __annotations__r   r   boolr   r   r   r   r   rq   r    r"   intr$   r   model_configr   r?   rF   rK   rS   r   r[   r   rT   r}   ro   r   r   classmethodr   r   r   r@   r>   r   r      s     !.ND.$T22"40d0',T':: $D1Hhsm1!$/FHSM/Q'K'$GS$H-L=t =T =d =.CT C4 CD CT 4 D 	t 	T 	d 	T$Z DJ 8 #' $FF 3-F 	F
 F 
c3hFV #' $/3D
9D
 3-D
 	D

 T#s(^,D
 
c3hD
R #' $/3E
E
 3-E
 	E

 T#s(^,E
 
E
NB B B (#$ 3   $ #' $	,, 3-, 	,
 
c3h,r@   r   c                   .    e Zd ZU dZ ed      Zeed<   y)GoogleGeocodeInputz'Input schema for `GoogleGeocodingTool`.zLocations for query.)descriptionr\   N)r   r   r   r   r   r\   rq   r   r   r@   r>   r   r     s    1#9:E3:r@   r   c                      e Zd ZU dZdZeed<   dZeed<   eZ	e
e   ed<   dZeed<    ed	
      Zeed<    ed	
      Zeed<    ed	
      Zeed<    ed
      Zee   ed<    ed
      Zee   ed<    ed       Zeed<   dZed   ed<   	 ddedee   deeeeef      eeef   f   fdZ	 ddedee    deeeeef      eeef   f   fdZ!y)GoogleGeocodingToolzTool for geocoding locations using Google Maps Geocoding API.

    Inherits from [`BaseTool`][langchain_core.tools.BaseTool].

    Supports batch location lookups with detailed address and coordinate information.

    google_geocoder;   zbA geocoding tool for multiple locations. Input: comma-separated locations. Returns: location data.r   args_schema   r]   Tr   r   r   r   r   r   Nr    c                  T    t        t        t        j                  dd                  S )Nr   rX   )r   )r   r   osgetenvr   r@   r>   <lambda>zGoogleGeocodingTool.<lambda>  s      9$RYY/Db%IJ!
 r@   )default_factoryapi_wrappercontent_and_artifactresponse_formatr\   run_managerr)   c                 L   	 |j                  d      D cg c]#  }|j                         s|j                         % }}t        |      | j                  kD  r|d| j                   }t        |      dkD  r3| j                  j                  || j                  | j                        }n| j                  j                  |d   | j                  | j                        }|j                  d      d| j                  j                  |j                  dg             d|j                  d      d	k(  rdnd|j                  d      d	k(  rdndd
d}|j                  d      d	k7  rg d|j                  dd      ifS |d   |fS c c}w # t        $ r}g dt        |      ifcY d}~S d}~ww xY w)a"  Geocode locations.

        Args:
            query: Comma-separated locations to geocode.
            run_manager: Callback manager.

        Returns:
            results: Location data with coordinates and addresses.
            response: Raw response with status and query info.
        rd   Nr   )ru   r   r    r   re   rb   rT   rf   )rx   ry   rz   ri   errorrg   Geocoding failed)rm   rl   rn   r]   r   r}   r   r    ro   r7   r[   rp   rq   )r8   r\   r   locru   rT   ro   rt   s           r>   _runzGoogleGeocodingTool._run  s    	)05C0@PCIIKPIP9~ 0 00%&8(8(89	9~!**88'$-- 9  #..::#A,t{{ ;  *ooh7%&#//==#	26  *++6??8+D+LaRS'2x'@D'H!a# {{8$,GW[[BT%UVVV9%w..9 Q<  	)Q(((	)s9   F E<E<D7F 5F <F 	F#
FF#F#c                 J  K   	 | j                   j                  || j                  | j                         d{   }|j	                  d      dk7  rg d|j	                  dd      ifS |j	                  dg       |fS 7 B# t
        $ r}g dt        |      ifcY d}~S d}~ww xY ww)	a7  Geocode locations asynchronously.

        Args:
            query: Comma-separated locations to geocode.
            run_manager: Async callback manager.

        Returns:
            results: Location data with coordinates and addresses.
            response: Raw response with status and query info.
        re   Nrb   rf   r   rg   r   rT   )r   r   r   r    r7   rp   rq   )r8   r\   r   r(   rt   s        r>   _arunzGoogleGeocodingTool._arun  s     	)++99dmmDKK :  F zz(#t+GVZZAS%TUUU::i,f44  	)Q(((	)sP   B#5A> A<-A> 'B#(A> ;B#<A> >	B BB B#B  B#)N)"r   r   r   r   r;   rq   r   r   r   r   r	   r   r]   r   r   r   r   r   r   r   r   r    r   r   r   r   r   r   r   r   r   r   r
   r   r   r@   r>   r   r     sY    !D# 	"   $6Ki5 K .ND.$T22"40d0#D1Hhsm1!$/FHSM/-2
.K* 
 8NOW34M
 <@/)/) 78/) 
tDcN#T#s(^3	4	/)h AE)) <=) 
tDcN#T#s(^3	4	)r@   r   )r   r   typingr   r   r   r   r   r   r	   r   r   langchain_core.callbacksr
   r   langchain_core.toolsr   langchain_core.utilsr   pydanticr   r   r   r   r   r   r   r   r   r   r@   r>   <module>r      s\    9 	 B B B   * 5 M MI ~	 ~B; ;j)( j)r@   