
    (ph                     
   S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKrSSK	r	SSK	J
r
  SSK	Jr  SSK	Jr  SSK	Jr  SrS	rS
rSR#                  \	R$                  \R&                  R(                  \R&                  R*                  5      rSrSrS"S jrS r " S S5      r " S S5      r " S S5      r " S S5      r " S S\
R>                  5      r  " S S5      r! " S S5      r" " S S5      r# " S  S!\RH                  5      r%g)#as  Firebase Realtime Database module.

This module contains functions and classes that facilitate interacting with the Firebase Realtime
Database. It supports basic data manipulation operations, as well as complex queries such as
limit queries and range queries. However, it does not support realtime update notifications. This
module uses the Firebase REST API underneath.
    N)parse)
exceptions)_http_client)
_sseclient)_utils	_databasez[].?#$)$key$value	$priorityz%Firebase/HTTP/{0}/{1}.{2}/AdminPython   FIREBASE_DATABASE_EMULATOR_HOSTc                 v    [         R                  " U[        [        5      nUR	                  U5      n[        X@S9$ )a  Returns a database ``Reference`` representing the node at the specified path.

If no path is specified, this function returns a ``Reference`` that represents the database
root. By default, the returned References provide access to the Firebase Database specified at
app initialization. To connect to a different database instance in the same Firebase project,
specify the ``url`` parameter.

Args:
  path: Path to a node in the Firebase realtime database (optional).
  app: An App instance (optional).
  url: Base URL of the Firebase Database instance (optional). When specified, takes
      precedence over the the ``databaseURL`` option set at app initialization.

Returns:
  Reference: A newly initialized Reference.

Raises:
  ValueError: If the specified path or app is invalid.
clientpath)r   get_app_service_DB_ATTRIBUTE_DatabaseService
get_client	Reference)r   appurlservicer   s        D/var/www/html/venv/lib/python3.13/site-packages/firebase_admin/db.py	referencer   0   s4    ( $$S-9IJG$FF..    c                 0  ^  [        T [        5      (       d  [        SR                  T 5      5      e[	        U 4S j[
         5       5      (       a  [        SR                  T 5      5      eT R                  S5       Vs/ s H  o(       d  M  UPM     sn$ s  snf )z,Parses a path string into a set of segments.z+Invalid path: "{0}". Path must be a string.c              3   ,   >#    U  H	  oT;   v   M     g 7fN ).0chr   s     r   	<genexpr>_parse_path.<locals>.<genexpr>L   s     
9 8": 8s   z6Invalid path: "{0}". Path contains illegal characters./)
isinstancestr
ValueErrorformatany_INVALID_PATH_CHARACTERSsplit)r   segs   ` r   _parse_pathr.   H   sx    dC  FMMdSTT

9 8
999DKKDQS 	S::c?2?CcC?222s   <
B
Bc                   N    \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	Sr
g)	EventR   z>Represents a realtime update event received from the database.c                 Z    Xl         [        R                  " UR                  5      U l        g r   )
_sse_eventjsonloadsdata_dataself	sse_events     r   __init__Event.__init__U   s    #ZZ	/
r   c                      U R                   S   $ )zParsed JSON data of this event.r6   r7   r9   s    r   r6   
Event.dataY        zz&!!r   c                      U R                   S   $ )z9Path of the database reference that triggered this event.r   r>   r?   s    r   r   
Event.path^   rA   r   c                 .    U R                   R                  $ )zEvent type string (put, patch).)r3   
event_typer?   s    r   rE   Event.event_typec   s     )))r   )r7   r3   N)__name__
__module____qualname____firstlineno____doc__r;   propertyr6   r   rE   __static_attributes__r    r   r   r0   r0   R   sF    H0 " " " " * *r   r0   c                   *    \ rS rSrSrS rS rS rSrg)ListenerRegistrationi   zERepresents the addition of an event listener to a database reference.c                     Xl         X l        [        R                  " U R                  S9U l        U R
                  R                  5         g)a  Initializes a new listener with given parameters.

This is an internal API. Use the ``db.Reference.listen()`` method to start a
new listener.

Args:
  callback: The callback function to fire in case of event.
  sse: A transport session to make requests with.
)targetN)	_callback_sse	threadingThread_start_listen_threadstart)r9   callbacksses      r   r;   ListenerRegistration.__init__l   s6     "	 ''t/A/ABr   c                 p    U R                    H&  nU(       d  M  U R                  [        U5      5        M(     g r   )rT   rS   r0   r8   s     r   rW   "ListenerRegistration._start_listen{   s&    IyuY/0 #r   c                 l    U R                   R                  5         U R                  R                  5         g)zStops the event listener represented by this registration

This closes the SSE HTTP connection, and joins the background thread.
N)rT   closerX   joinr?   s    r   r`   ListenerRegistration.close   s"    
 			r   )rS   rT   rX   N)	rG   rH   rI   rJ   rK   r;   rW   r`   rM   r    r   r   rO   rO   i   s    O1r   rO   c                       \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	S r
SS jrS	 rS
 rS rSS jrS rS rS rS rS rS rS rSS jrSS jrSrg)r      z>Reference represents a node in the Firebase realtime database.c                     UR                  S5      U l        SU;   a  UR                  S5      U l        O[        UR                  S5      5      U l        SSR	                  U R                  5      -   U l        g)zCreates a new Reference using the provided parameters.

This method is for internal use only. Use db.reference() to obtain an instance of
Reference.
r   segmentsr   r%   N)get_client	_segmentsr.   ra   _pathurl)r9   kwargss     r   r;   Reference.__init__   sZ     zz(+#ZZ
3DN(F);<DNchht~~66r   c                 D    U R                   (       a  U R                   S   $ g )N)ri   r?   s    r   keyReference.key   s    >>>>"%%r   c                     U R                   $ r   rj   r?   s    r   r   Reference.path   s    }}r   c                 h    U R                   (       a!  [        U R                  U R                   S S S9$ g )Nrn   )r   rf   )ri   r   rh   r?   s    r   parentReference.parent   s(    >>DLL4>>#2;NOOr   c                    U(       a  [        U[        5      (       d  [        SR                  U5      5      eUR	                  S5      (       a  [        SR                  U5      5      eU R
                  S-   U-   n[        U R                  US9$ )a  Returns a Reference to the specified child node.

The path may point to an immediate child of the current Reference, or a deeply nested
child. Child paths must not begin with '/'.

Args:
  path: Path to the child node.

Returns:
  Reference: A database Reference representing the specified child node.

Raises:
  ValueError: If the child path is not a string, not well-formed or begins with '/'.
z>Invalid path argument: "{0}". Path must be a non-empty string.r%   @Invalid path argument: "{0}". Child path must not start with "/"r   )r&   r'   r(   r)   
startswithrj   r   rh   )r9   r   	full_paths      r   childReference.child   s     :dC00PWWX\]_ _??3RYYZ^_a aMMC'$.	9==r   c                    U(       aQ  U(       a  [        S5      eU R                  R                  SU R                  5       SS0S9u  p4XCR	                  S5      4$ U(       a  SOSnU R                  R                  SU R                  5       US	9$ )
a'  Returns the value, and optionally the ETag, at the current location of the database.

Args:
  etag: A boolean indicating whether the Etag value should be returned or not (optional).
  shallow: A boolean indicating whether to execute a shallow read (optional). Shallow
      reads do not retrieve the child nodes of the current database location. Cannot be
      set to True if ``etag`` is also set to True.

Returns:
  object: If etag is False returns the decoded JSON value of the current database location.
  If etag is True, returns a 2-tuple consisting of the decoded JSON value and the Etag
  associated with the current database location.

Raises:
  ValueError: If both ``etag`` and ``shallow`` are set to True.
  FirebaseError: If an error occurs while communicating with the remote database server.
z,etag and shallow cannot both be set to True.rg   zX-Firebase-ETagtrueheadersETagzshallow=trueNparams)r(   rh   headers_and_body_add_suffixrg   body)r9   etagshallowr   r6   r   s         r   rg   Reference.get   s    $  !OPP LL99t'')4E3O : QMGV,,,#*||  (8(8(:6 JJr   c                    [        U[        5      (       d  [        S5      eU R                  R	                  SU R                  5       SU0S9nUR                  S:X  a  gSUR                  5       UR                  R                  S5      4$ )	a  Gets data in this location only if the specified ETag does not match.

Args:
  etag: The ETag value to be checked against the ETag of the current location.

Returns:
  tuple: A 3-tuple consisting of a boolean, a decoded JSON value and an ETag. If the ETag
  specified by the caller did not match, the boolen value will be True and the JSON
  and ETag values would reflect the corresponding values in the database. If the ETag
  matched, the boolean value will be False and the other elements of the tuple will be
  None.

Raises:
  ValueError: If the ETag is not a string.
  FirebaseError: If an error occurs while communicating with the remote database server.
zETag must be a string.rg   zif-none-matchr   i0  )FNNTr   )
r&   r'   r(   rh   requestr   status_coder4   r   rg   )r9   r   resps      r   get_if_changedReference.get_if_changed   sz    " $$$566||##E4+;+;+=Y]G^#_s"$TYY[$,,"2"26":::r   c                 t    Uc  [        S5      eU R                  R                  SU R                  5       USS9  g)am  Sets the data at this location to the given value.

The value must be JSON-serializable and not None.

Args:
  value: JSON-serializable value to be set at this location.

Raises:
  ValueError: If the provided value is None.
  TypeError: If the value is not JSON-serializable.
  FirebaseError: If an error occurs while communicating with the remote database server.
NValue must not be None.putprint=silentr4   r   )r(   rh   r   r   r9   values     r   setReference.set   s9     =677UD$4$4$6U>Zr   c                    [        U[        5      (       d  [        S5      eUc  [        S5      e U R                  R	                  SU R                  5       USU0S9nSX#R                  S5      4$ ! [        R                   aN  nUR                  nUb8  SUR                  ;   a(  UR                  S   nUR                  5       nS	Xv4s SnA$ UeSnAff = f)
a  Conditonally sets the data at this location to the given value.

Sets the data at this location to the given value only if ``expected_etag`` is same as the
ETag value in the database.

Args:
  expected_etag: Value of ETag we want to check.
  value: JSON-serializable value to be set at this location.

Returns:
  tuple: A 3-tuple consisting of a boolean, a decoded JSON value and an ETag. The boolean
  indicates whether the set operation was successful or not. The decoded JSON and the
  ETag corresponds to the latest value in this database location.

Raises:
  ValueError: If the value is None, or if expected_etag is not a string.
  FirebaseError: If an error occurs while communicating with the remote database server.
zExpected ETag must be a string.NzValue must not be none.r   zif-match)r4   r   Tr   F)r&   r'   r(   rh   r   r   rg   r   FailedPreconditionErrorhttp_responser4   )r9   expected_etagr   r   errorr   r   snapshots           r   set_if_unchangedReference.set_if_unchanged
  s    ( --->??=677	ll**t'')
M?Z + \GF 33311 	!//M(V}7L7L-L$,,V4(--/h,,K	s$   >A/ /CACC
CCc                     Uc  [        S5      eU R                  R                  SU R                  5       US9nUR	                  S5      nU R                  U5      $ )a  Creates a new child node.

The optional value argument can be used to provide an initial value for the child node. If
no value is provided, child node will have empty string as the default value.

Args:
  value: JSON-serializable initial value for the child node (optional).

Returns:
  Reference: A Reference representing the newly created child node.

Raises:
  ValueError: If the value is None.
  TypeError: If the value is not JSON-serializable.
  FirebaseError: If an error occurs while communicating with the remote database server.
r   post)r4   name)r(   rh   r   r   rg   r{   )r9   r   outputpush_ids       r   pushReference.push0  sV    " =677""64+;+;+=E"J**V$zz'""r   c                     U(       a  [        U[        5      (       d  [        S5      eSUR                  5       ;   a  [        S5      eU R                  R                  SU R                  5       USS9  g)a:  Updates the specified child keys of this Reference to the provided values.

Args:
  value: A dictionary containing the child keys to update, and their new values.

Raises:
  ValueError: If value is empty or not a dictionary.
  FirebaseError: If an error occurs while communicating with the remote database server.
z.Value argument must be a non-empty dictionary.Nz&Dictionary must not contain None keys.patchr   r   )r&   dictr(   keysrh   r   r   r   s     r   updateReference.updateG  s]     Jud33MNN5::<EFFWd&6&6&8u^\r   c                 X    U R                   R                  SU R                  5       5        g)zDeletes this node from the database.

Raises:
  FirebaseError: If an error occurs while communicating with the remote database server.
deleteN)rh   r   r   r?   s    r   r   Reference.deleteW  s!     	Xt'7'7'9:r   c                 $    U R                  U5      $ )aj  Registers the ``callback`` function to receive realtime updates.

The specified callback function will get invoked with ``db.Event`` objects for each
realtime update received from the database. It will also get called whenever the SDK
reconnects to the server due to network issues or credential expiration. In general,
the OAuth2 credentials used to authorize connections to the server expire every hour.
Therefore clients should expect the ``callback`` to fire at least once every hour, even if
there are no updates in the database.

This API is based on the event streaming support available in the Firebase REST API. Each
call to ``listen()`` starts a new HTTP connection and a background thread. This is an
experimental feature. It currently does not honor the auth overrides and timeout settings.
Cannot be used in thread-constrained environments like Google App Engine.

Args:
  callback: A function to be called when a data change is detected.

Returns:
  ListenerRegistration: An object that can be used to stop the event listener.

Raises:
  FirebaseError: If an error occurs while starting the initial HTTP connection.
)_listen_with_session)r9   rZ   s     r   listenReference.listen_  s    0 ((22r   c                     [        U5      (       d  [        S5      eSnU R                  SS9u  p4U[        :  a6  U" U5      nU R	                  XE5      u  pcnU(       a  U$ US-  nU[        :  a  M6  [        S5      e)a  Atomically modifies the data at this location.

Unlike a normal ``set()``, which just overwrites the data regardless of its previous state,
``transaction()`` is used to modify the existing value to a new value, ensuring there are
no conflicts with other clients simultaneously writing to the same location.

This is accomplished by passing an update function which is used to transform the current
value of this reference into a new value. If another client writes to this location before
the new value is successfully saved, the update function is called again with the new
current value, and the write will be retried. In case of repeated failures, this method
will retry the transaction up to 25 times before giving up and raising a
TransactionAbortedError. The update function may also force an early abort by raising an
exception instead of returning a value.

Args:
  transaction_update: A function which will be passed the current data stored at this
      location. The function should return the new value it would like written. If
      an exception is raised, the transaction will be aborted, and the data at this
      location will not be modified. The exceptions raised by this function are
      propagated to the caller of the transaction method.

Returns:
  object: New value of the current database Reference (only if the transaction commits).

Raises:
  TransactionAbortedError: If the transaction aborts after exhausting all retry attempts.
  ValueError: If transaction_update is not a function.
z&transaction_update must be a function.r   T)r      z)Transaction aborted after failed retries.)callabler(   rg   _TRANSACTION_MAX_RETRIESr   TransactionAbortedError)r9   transaction_updatetriesr6   r   new_datasuccesss          r   transactionReference.transactiony  s    : *++EFFXX4X(
..)$/H"&"7"7"GG4QJE .. &&QRRr   c                     U[         ;   a  [        SR                  U5      5      e[        XR                  U R                  5       S9$ )av  Returns a Query that orders data by child values.

Returned Query can be used to set additional parameters, and execute complex database
queries (e.g. limit queries, range queries).

Args:
  path: Path to a valid child of the current Reference.

Returns:
  Query: A database Query instance.

Raises:
  ValueError: If the child path is not a string, not well-formed or None.
zIllegal child path: {0}order_byr   pathurl)_RESERVED_FILTERSr(   r)   Queryrh   r   )r9   r   s     r   order_by_childReference.order_by_child  s>     $$6==dCDDd<<AQAQASTTr   c                 H    [        SU R                  U R                  5       S9$ )zCreates a Query that orderes data by key.

Returned Query can be used to set additional parameters, and execute complex database
queries (e.g. limit queries, range queries).

Returns:
  Query: A database Query instance.
r	   r   r   rh   r   r?   s    r   order_by_keyReference.order_by_key  s      fT\\4CSCSCUVVr   c                 H    [        SU R                  U R                  5       S9$ )zCreates a Query that orderes data by value.

Returned Query can be used to set additional parameters, and execute complex database
queries (e.g. limit queries, range queries).

Returns:
  Query: A database Query instance.
r
   r   r   r?   s    r   order_by_valueReference.order_by_value  s      ht||TEUEUEWXXr   c                      U R                   U-   $ r   rr   )r9   suffixs     r   r   Reference._add_suffix  s    }}v%%r   Nc                 L   U R                   R                  U R                  5       -   nU(       d  U R                   R                  5       n [        R
                  " X25      n[        X5      $ ! [        R                  R                   a  n[        R                  U5      eS nAff = fr   )rh   base_urlr   create_listener_sessionr   	SSEClientrO   requestsr   RequestException_Clienthandle_rtdb_error)r9   rZ   sessionr   r[   r   s         r   r   Reference._listen_with_session  s    ll##d&6&6&88ll::<G	3&&s4C'66""33 	3++E22	3s   
 A+ +B#	BB#)rh   rj   ri   )FF) )z.jsonr   )rG   rH   rI   rJ   rK   r;   rL   ro   r   ru   r{   rg   r   r   r   r   r   r   r   r   r   r   r   r   r   rM   r    r   r   r   r      s    H7  
    
>0K8;4["$L#.] ;34)SVU&	W	Y&	3r   r   c                   R    \ rS rSrSrS rS rS rS rS r	S r
\S	 5       rS
 rSrg)r   i  a  Represents a complex query that can be executed on a Reference.

Complex queries can consist of up to 2 components: a required ordering constraint, and an
optional filtering constraint. At the server, data is first sorted according to the given
ordering constraint (e.g. order by child). Then the filtering constraint (e.g. limit, range)
is applied on the sorted data to produce the final result. Despite the ordering constraint,
the final result is returned by the server as an unordered collection. Therefore the Query
interface performs another round of sorting at the client-side before returning the results
to the caller. This client-side sorted results are returned to the user as a Python
OrderedDict.
c                     UR                  S5      nU(       a  [        U[        5      (       d  [        S5      eU[        ;  aL  UR                  S5      (       a  [        SR                  U5      5      e[        U5      nSR                  U5      nUR                  S5      U l	        UR                  S5      U l
        X l        S[        R                  " U5      0U l        U(       a  [        SR                  U5      5      eg )	Nr   z)order_by field must be a non-empty stringr%   rx   r   r   orderByz!Unexpected keyword arguments: {0})popr&   r'   r(   r   ry   r)   r.   ra   rh   rj   	_order_byr4   dumps_params)r9   rk   r   rf   s       r   r;   Query.__init__  s    ::j)z(C88HII,,""3''  ",,2F8,<> >"8,Hxx)Hzz(+

9-!!DJJx$89@GGOPP r   c                     [        U[        5      (       a  US:  a  [        S5      eSU R                  ;   a  [        S5      eXR                  S'   U $ )a  Creates a query with limit, and anchors it to the start of the window.

Args:
  limit: The maximum number of child nodes to return.

Returns:
  Query: The updated Query instance.

Raises:
  ValueError: If the value is not an integer, or set_limit_last() was called previously.
r   %Limit must be a non-negative integer.limitToLast&Cannot set both first and last limits.limitToFirstr&   intr(   r   r9   limits     r   limit_to_firstQuery.limit_to_first  sL     %%%DEEDLL(EFF',^$r   c                     [        U[        5      (       a  US:  a  [        S5      eSU R                  ;   a  [        S5      eXR                  S'   U $ )a  Creates a query with limit, and anchors it to the end of the window.

Args:
  limit: The maximum number of child nodes to return.

Returns:
  Query: The updated Query instance.

Raises:
  ValueError: If the value is not an integer, or set_limit_first() was called previously.
r   r   r   r   r   r   r   s     r   limit_to_lastQuery.limit_to_last  sL     %%%DEET\\)EFF&+]#r   c                 h    Uc  [        S5      e[        R                  " U5      U R                  S'   U $ )a+  Sets the lower bound for a range query.

The Query will only return child nodes with a value greater than or equal to the specified
value.

Args:
  start: JSON-serializable value to start at, inclusive.

Returns:
  Query: The updated Query instance.

Raises:
  ValueError: If the value is ``None``.
zStart value must not be None.startAtr(   r4   r   r   )r9   rY   s     r   start_atQuery.start_at   s1     =<=="&**U"3Yr   c                 h    Uc  [        S5      e[        R                  " U5      U R                  S'   U $ )a$  Sets the upper bound for a range query.

The Query will only return child nodes with a value less than or equal to the specified
value.

Args:
  end: JSON-serializable value to end at, inclusive.

Returns:
  Query: The updated Query instance.

Raises:
  ValueError: If the value is ``None``.
zEnd value must not be None.endAtr   )r9   ends     r   end_atQuery.end_at4  s0     ;:;; $

3Wr   c                 h    Uc  [        S5      e[        R                  " U5      U R                  S'   U $ )a  Sets an equals constraint on the Query.

The Query will only return child nodes whose value is equal to the specified value.

Args:
  value: JSON-serializable value to query for.

Returns:
  Query: The updated Query instance.

Raises:
  ValueError: If the value is ``None``.
z Equal to value must not be None.equalTor   r   s     r   equal_toQuery.equal_toH  s1     =?@@"&**U"3Yr   c                     / n[        U R                  5       H0  nUR                  SR                  X R                  U   5      5        M2     SR	                  U5      $ )N{0}={1}&)sortedr   appendr)   ra   )r9   r   ro   s      r   	_querystrQuery._querystr[  sI    $,,'CMM)**3S0ABC (xxr   c                     U R                   R                  SU R                  U R                  S9n[	        U[
        [        45      (       a3  U R                  S:w  a#  [        XR                  5      R                  5       $ U$ )a  Executes this Query and returns the results.

The results will be returned as a sorted list or an OrderedDict.

Returns:
  object: Decoded JSON result of the Query.

Raises:
  FirebaseError: If an error occurs while communicating with the remote database server.
rg   r   r   )
rh   r   rj   r  r&   r   listr   _Sorterrg   )r9   results     r   rg   	Query.getb  s`     ""5$--"OftTl+++0M6>>26688r   )rh   r   r   rj   N)rG   rH   rI   rJ   rK   r;   r   r   r   r   r   rL   r  rg   rM   r    r   r   r   r     s?    
Q"&&((&    r   r   c                       \ rS rSrSrS rSrg)r   is  zGA transaction was aborted aftr exceeding the maximum number of retries.c                 B    [         R                  R                  X5        g r   )r   AbortedErrorr;   )r9   messages     r   r;    TransactionAbortedError.__init__v  s    ((7r   r    N)rG   rH   rI   rJ   rK   r;   rM   r    r   r   r   r   s  s
    Q8r   r   c                   $    \ rS rSrSrS rS rSrg)r
  iz  z'Helper class for sorting query results.c           	         [        U[        5      (       a6  SU l        UR                  5        VVs/ s H  u  p4[	        X4U5      PM     nnnOi[        U[
        5      (       a1  SU l        [        U5       VVs/ s H  u  p4[	        X4U5      PM     nnnO#[        SR                  [        U5      5      5      e[        U5      U l        g s  snnf s  snnf )NTFz'Sorting not supported for "{0}" object.)r&   r   
dict_inputitems
_SortEntryr	  	enumerater(   r)   typer  sort_entries)r9   resultsr   kventriess         r   r;   _Sorter.__init__}  s    gt$$"DO>EmmoNodaz!1oGNG&&#DO>G>PQ>Pdaz!1>PGQGFMMdSZm\]]"7O O Rs   C6Cc                    U R                   (       aF  [        R                  " U R                   Vs/ s H  oR                  UR
                  4PM     sn5      $ U R                   Vs/ s H  oR
                  PM     sn$ s  snf s  snf r   )r  collectionsOrderedDictr  ro   r   )r9   es     r   rg   _Sorter.get  sd    ??**dFWFW+XFWUUAGG,<FW+XYY!%!2!23!2A!233 ,Y3s   !A>&B)r  r  N)rG   rH   rI   rJ   rK   r;   rg   rM   r    r   r   r
  r
  z  s    1	,4r   r
  c                       \ rS rSrSrSrSrSrSrSr	Sr
S	 r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       rS rS rS rS rS rS rSrg)r  i  z;A wrapper that is capable of sorting items in a dictionary.r   r               c                     Xl         X l        US;   a  Xl        O'US:X  a  X l        O[        R	                  X#5      U l        [        R                  U R                  5      U l        g )N)r	   r   r
   )_key_value_indexr  _extract_child_get_index_type_index_type)r9   ro   r   r   s       r   r;   _SortEntry.__init__  sP    	,,K!K$33EDDK%55dkkBr   c                     U R                   $ r   )r*  r?   s    r   ro   _SortEntry.key  s    yyr   c                     U R                   $ r   )r,  r?   s    r   index_SortEntry.index      {{r   c                     U R                   $ r   )r/  r?   s    r   
index_type_SortEntry.index_type  s    r   c                     U R                   $ r   )r+  r?   s    r   r   _SortEntry.value  r6  r   c                 h   Uc  U R                   $ [        U[        5      (       a  U(       d  U R                  $ [        U[        5      (       a  U(       a  U R                  $ [        U[
        [        45      (       a  U R                  $ [        U[        5      (       a  U R                  $ U R                  $ )zAssigns an integer code to the type of the index.

The index type determines how differently typed values are sorted. This ordering is based
on https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-ordered-data
)
_type_noner&   bool_type_bool_false_type_bool_truer   float_type_numericr'   _type_string_type_object)clsr4  s     r   r.  _SortEntry._get_index_type  s     =>>!eT""5'''eT""u&&&ec5\**$$$eS!!###r   c                     UR                  S5      nUnU H+  n[        U[        5      (       a  UR                  U5      nM+    g    U$ )Nr%   )r,   r&   r   rg   )rE  r   r   rf   currentsegments         r   r-  _SortEntry._extract_child  sC    ::c?G'4((!++g.	  
 r   c                    U R                   UR                   p2X#:X  ad  X R                  U R                  4;   a2  U R                  UR                  :w  a  U R                  UR                  p2OU R                  UR                  p2X#:  a  gX#:  a  gg)a:  Compares two _SortEntry instances.

If the indices have the same numeric or string type, compare them directly. Ties are
broken by comparing the keys. If the indices have the same type, but are neither numeric
nor string, compare the keys. In all other cases compare based on the ordering provided
by index types.
rn   r   r   )r8  rB  rC  r4  ro   )r9   otherself_key	other_keys       r   _compare_SortEntry._compare  sw     #oou/?/?) ..0A0ABBtzzUZU`U`G`&*jj%++)&*hh		)r   c                 *    U R                  U5      S:  $ Nr   rO  r9   rL  s     r   __lt___SortEntry.__lt__      }}U#a''r   c                 *    U R                  U5      S:*  $ rR  rS  rT  s     r   __le___SortEntry.__le__      }}U#q((r   c                 *    U R                  U5      S:  $ rR  rS  rT  s     r   __gt___SortEntry.__gt__  rW  r   c                 *    U R                  U5      S:  $ rR  rS  rT  s     r   __ge___SortEntry.__ge__  r[  r   c                 *    U R                  U5      S:H  $ rR  rS  rT  s     r   __eq___SortEntry.__eq__  r[  r   )r,  r/  r*  r+  N)rG   rH   rI   rJ   rK   r=  r?  r@  rB  rC  rD  r;   rL   ro   r4  r8  r   classmethodr.  r-  rO  rU  rY  r]  r`  rc  rM   r    r   r   r  r    s    EJOMLL	C              &  ,()())r   r  c                   X    \ rS rSrSrSrS rSS jrS r\	S 5       r
\	S	 5       rS
 rSrg)r   i  z8Service that maintains a collection of database clients._admin_c                 <   UR                   U l        UR                  R                  S5      nU(       a  X l        OS U l        [
        R                  U5      nX0R                  0 4;  a  [        R                  " USS9U l
        OS U l
        UR                  R                  S[        R                  5      U l        0 U l        [        R                   R                  ["        5      nU(       a,  SU;   a  [%        SR'                  ["        U5      5      eX@l        g S U l        g )NdatabaseURL),:)
separatorshttpTimeoutz//z6Invalid {0}: "{1}". It must follow format "host:port".)
credential_credentialoptionsrg   _db_urlr   _get_auth_override_DEFAULT_AUTH_OVERRIDEr4   r   _auth_overrider   DEFAULT_TIMEOUT_SECONDS_timeout_clientsosenviron_EMULATOR_HOST_ENV_VARr(   r)   _emulator_host)r9   r   db_urlauth_overrideemulator_hosts        r   r;   _DatabaseService.__init__  s    >>/!LDL(;;C@!<!<b AA"&**]z"RD"&D|7[7[\

'=>}$ LSS.?@ @ #0"&Dr   Nc                     Uc  U R                   nU(       a  [        U[        5      (       d  [        SR	                  U5      5      e[
        R                  " U5      nUR                  (       d  [        SR	                  U5      5      eU R                  U5      nU(       a0  [        R                  " 5       nUR                  nSUR                  0nO7U R                  R                  5       nSR	                  UR                  5      n0 nU R                  (       a  U R                  US'   U[         R"                  " USS94nXpR$                  ;  a%  ['        XEU R(                  U5      nXR$                  U'   U R$                  U   $ )z<Creates a client based on the db_url. Clients may be cached.zIInvalid database URL: "{0}". Database URL must be a non-empty URL string.zJInvalid database URL: "{0}". Database URL must be a wellformed URL string.nszhttps://{0}auth_variable_overrideT)	sort_keys)rq  r&   r'   r(   r)   r   urlparsenetloc_get_emulator_configr   EmulatorAdminCredentialsr   	namespacero  get_credentialrt  r4   r   rw  r   rv  )	r9   r|  
parsed_urlemulator_configrn  r   r   client_cache_keyr   s	            r   r   _DatabaseService.get_client  sH   >\\FZ44$fVn. . ^^F+
  $fVn. . 33J?88:J&//HO556F ))88:J$++J,=,=>HF /3/B/BF+,$djj4&HI==0Z4==&IF.4MM*+}}-..r   c                 8   [         R                  " SSS/5      nUR                  S:w  a  [        R	                  U5      u  p4U" X45      $ U R
                  (       aA  SR                  U R
                  5      nUR                  R                  S5      S   nU" X45      $ g)	z;Checks whether the SDK should connect to the RTDB emulator.EmulatorConfigr   r  httpsz
http://{0}.r   N)	r   
namedtupleschemer   _parse_emulator_urlr{  r)   r  r,   )r9   r  r  r   r  s        r   r  %_DatabaseService._get_emulator_config=  s    $//0@:{B[\'"2"F"Fz"RH!(66#**4+>+>?H"))//4Q7I!(66r   c                 l   [         R                  " UR                  5      R                  S5      nUR                  S:w  d   U(       a  [        U5      S:w  d
  US   (       d(  [        SR                  UR                  5       5      5      eUS   nSR                  UR                  UR                  5      nXC4$ )z:Parses emulator URL like http://localhost:8080/?ns=foo-barr  httpr   r   zgInvalid database URL: "{0}". Database URL must be a valid URL to a Firebase Realtime Database instance.z	{0}://{1})
r   parse_qsqueryrg   r  lenr(   r)   geturlr  )rE  r  query_nsr  r   s        r   r  $_DatabaseService._parse_emulator_urlL  s     >>*"2"2377=&x3x=A;MU]^_U`77=vj>O>O>Q7RT T QK	%%j&7&79J9JK""r   c                     UR                   R                  SU R                  5      nX R                  :X  d  Uc  U$ [        U[        5      (       d  [        SR                  U5      5      eU$ )NdatabaseAuthVariableOverridezZInvalid databaseAuthVariableOverride option: "{0}". Override value must be a dict or None.)rp  rg   rs  r&   r   r(   r)   )rE  r   r}  s      r   rr  #_DatabaseService._get_auth_overrideY  sg    (FHbHbc666-:O  -.. ==CVM=RT T r   c                 t    U R                   R                  5        H  nUR                  5         M     0 U l         g r   )rw  valuesr`   r   s     r   r`   _DatabaseService.closed  s)    ]]))+EKKM ,r   )rt  rw  ro  rq  r{  rv  r   )rG   rH   rI   rJ   rK   rs  r;   r   r  re  r  rr  r`   rM   r    r   r   r   r     sH    B&'4#/J 
# 
#  r   r   c                   b   ^  \ rS rSrSrS	U 4S jjrU 4S jrS r\S 5       r	\S 5       r
SrU =r$ )
r   ij  zHTTP client used to make REST calls.

_Client maintains an HTTP session, and handles authenticating HTTP requests along with
marshalling and unmarshalling of JSON data.
c                 f   > [         TU ]  XUS[        0S9  Xl        U(       a  X@l        g0 U l        g)ac  Creates a new _Client from the given parameters.

This exists primarily to enable testing. For regular use, obtain _Client instances by
calling the from_app() class method.

Args:
  credential: A Google credential that can be used to authenticate requests.
  base_url: A URL prefix to be added to all outgoing requests. This is typically the
      Firebase Realtime Database URL.
  timeout: HTTP request timeout in seconds. If set to None connections will never
      timeout, which is the default behavior of the underlying requests library.
  params: Dict of query parameters to add to all outgoing requests.
z
User-Agent)rn  r   timeoutr   N)superr;   _USER_AGENTrn  r   )r9   rn  r   r  r   	__class__s        r   r;   _Client.__init__q  s9     	!lK%@ 	 	B % &fBr   c                 N  >^  SR                  U 4S jT R                   5       5      nUR                  S5      nU(       a  U(       a	  US-   U-   nOUnXCS'    [        [        T ]  " X40 UD6$ ! [        R                  R                   a  n[        R                  U5      eSnAff = f)a;  Makes an HTTP call using the Python requests library.

Extends the request() method of the parent JsonHttpClient class. Handles default
params like auth overrides, and low-level exceptions.

Args:
  method: HTTP method name as a string (e.g. get, post).
  url: URL path of the remote endpoint. This will be appended to the server's base URL.
  **kwargs: An additional set of keyword arguments to be passed into requests API
      (e.g. json, params).

Returns:
  Response: An HTTP response object.

Raises:
  FirebaseError: If an error occurs while making the HTTP call.
r  c              3   b   >#    U  H$  nS R                  UTR                  U   5      v   M&     g7f)r  N)r)   r   )r!   ro   r9   s     r   r#   "_Client.request.<locals>.<genexpr>  s*     XKS))#t{{3/?@@Ks   ,/r   N)
ra   r   rg   r  r   r   r   r   r   r   )r9   methodr   rk   r  extra_paramsr   r  s   `      r   r   _Client.request  s    $ XDKKXXzz(+$s*U2$ x	3$/FvFF""33 	3++E22	3s   A, ,B$
BB$c                 B    [         R                  " U R                  5      $ r   )r   KeepAuthSessionrn  r?   s    r   r   _Client.create_listener_session  s    ))$//::r   c                     UR                   c  [        R                  " U5      $ U R                  UR                   5      n[        R                  " XS9$ )zFConverts an error encountered while calling RTDB into a FirebaseError.)r  )responser   handle_requests_error_extract_error_message)rE  r   r  s      r   r   _Client.handle_rtdb_error  sD     >>!//66,,U^^<++ECCr   c                     Sn UR                  5       n[        U[        5      (       a  UR                  S5      nU(       d)  SR                  UR                  R                  5       5      nU$ ! [         a     N>f = f)aA  Extracts an error message from an error response.

If the server has sent a JSON response with an 'error' field, which is the typical
behavior of the Realtime Database REST API, parses the response to retrieve the error
message. If the server has sent a non-JSON response, returns the full response
as the error message.
Nr   z&Unexpected response from database: {0})r4   r&   r   rg   r(   r)   contentdecode)rE  r  r  r6   s       r   r  _Client._extract_error_message  sq     	==?D$%%((7+ >EEhFVFVF]F]F_`G  		s   6A, ,
A98A9)rn  r   r   )rG   rH   rI   rJ   rK   r;   r   r   re  r   r  rM   __classcell__)r  s   @r   r   r   j  sB    /(3@; D D  r   r   )r%   NN)&rK   r   r4   rx  sysrU   urllibr   r   firebase_adminr   r   r   r   r   r+   r   r)   __version__version_infomajorminorr  r   rz  r   r.   r0   rO   r   r   r  r   r
  r  r   JsonHttpClientr   r    r   r   <module>r     s     	 
     % ' % ! # 3 5<< 0 0 6 68H8H8N8NP : /03* *. DN3 N3b
T Tn8j55 84 4*g) g)Tn nb\l)) \r   