
    .i}P                       d dl mZ d dlmZmZ d dlZd dlmZmZm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlZd dlmZmZ erd dlmZ d d	lmZmZ dd
Ze
	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd       Ze
	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd       Z	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 	 	 ddZddZ ed      	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d d       Z y)!    )annotations)abcdefaultdictN)TYPE_CHECKINGAnyDefaultDictoverloadconvert_json_to_lines)
set_module)	DataFrameSeries)Iterable)IgnoreRaiseScalarc                F    | d   dk(  s
| d   dk(  r| S | dd } t        |       S )zJ
    Helper function that converts JSON lists to line delimited JSON.
    r   []   r
   )ss    W/var/www/app/trading-bot/venv/lib/python3.12/site-packages/pandas/io/json/_normalize.pyconvert_to_line_delimitsr   %   s4     Q43;1R5C<	!BA ##    c                     y N dsprefixseplevel	max_levels        r   nested_to_recordr$   2   s     r   c                     y r   r   r   s        r   r$   r$   <   s     r   c                   d}t        | t              r| g} d}g }| D ]  }t        j                  |      }|j	                         D ]  \  }	}
t        |	t
              st        |	      }	|dk(  r|	}n||z   |	z   }t        |
t              r|!||k\  r|dk7  r|j                  |	      }
|
||<   d|j                  |	      }
|j                  t        |
|||dz   |              |j                  |        |r|d   S |S )a  
    A simplified json_normalize

    Converts a nested dict into a flat dict ("record"), unlike json_normalize,
    it does not attempt to extract a subset of the data.

    Parameters
    ----------
    ds : dict or list of dicts
    prefix: the prefix, optional, default: ""
    sep : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
    level: int, optional, default: 0
        The number of levels in the json string.

    max_level: int, optional, default: None
        The max depth to normalize.

    Returns
    -------
    d - dict or list of dicts, matching `ds`

    Examples
    --------
    >>> nested_to_record(
    ...     dict(flat1=1, dict1=dict(c=1, d=2), nested=dict(e=dict(c=1, d=2), d=2))
    ... )
    {'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}
    FTr   r   )

isinstancedictcopydeepcopyitemsstrpopupdater$   append)r   r    r!   r"   r#   	singletonnew_dsdnew_dkvnewkeys               r   r$   r$   F   s   X I"dT	F a GGI 	QDAqa%Fz#) a&%%9*<A:		!A$%E&M		!ALL)!VS%!)YOP-	Q. 	e36 ayMr   c                    t        | t              rD| j                         D ]/  \  }}| | | }|s|j                  |      }t	        ||||       1 |S | ||<   |S )a3  
    Main recursive function
    Designed for the most basic use case of pd.json_normalize(data)
    intended as a performance improvement, see #15621

    Parameters
    ----------
    data : Any
        Type dependent on types contained within nested Json
    key_string : str
        New key (with separator(s) in) for data
    normalized_dict : dict
        The new normalized/flattened Json dict
    separator : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
    data
key_stringnormalized_dict	separator)r'   r(   r+   removeprefix_normalize_json)r9   r:   r;   r<   keyvaluenew_keys          r   r>   r>      sz    . $**, 	JC#YKu5G!..y9" /#		  '+
#r   c           
        | j                         D ci c]  \  }}t        |t              r|| }}}t        | j                         D ci c]  \  }}t        |t              s|| c}}di |      }i ||S c c}}w c c}}w )aw  
    Order the top level keys and then recursively go to depth

    Parameters
    ----------
    data : dict or list of dicts
    separator : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

    Returns
    -------
    dict or list of dicts, matching `normalized_json_object`
     r8   )r+   r'   r(   r>   )r9   r<   r4   r5   	top_dict_nested_dict_s         r   _normalize_json_orderedrF      s     #'**,J$!QjD6IAJIJ"#zz|Ctq!z!T/BadC	L )i(<(( KCs   A=A=B
&B
c                    i }t        | t              rt        | |      }|S t        | t              r| D cg c]  }t	        ||       }}|S |S c c}w )a  
    An optimized basic json_normalize

    Converts a nested dict into a flat dict ("record"), unlike
    json_normalize and nested_to_record it doesn't do anything clever.
    But for the most basic use cases it enhances performance.
    E.g. pd.json_normalize(data)

    Parameters
    ----------
    ds : dict or list of dicts
    sep : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

    Returns
    -------
    frame : DataFrame
    d - dict or list of dicts, matching `normalized_json_object`

    Examples
    --------
    >>> _simple_json_normalize(
    ...     {
    ...         "flat1": 1,
    ...         "dict1": {"c": 1, "d": 2},
    ...         "nested": {"e": {"c": 1, "d": 2}, "d": 2},
    ...     }
    ... )
    {'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}

    )r9   r<   r!   )r'   r(   rF   list_simple_json_normalize)r   r!   normalized_json_objectrownormalized_json_lists        r   rJ   rJ      sd    V  "d!8bC!P "! 
B	PRS 6s DSS##!!  Ts   Ac                :   | yt        | t              ry| D ]  }t        |t              r<|D ]6  }t        |t              rt        dt	        |      j
                   d|       Ot        |t              r`t        dt	        |      j
                   d|       y)aD  
    Validate that meta parameter contains only strings or lists of strings.
    Parameters
    ----------
    meta : str or list of str or list of list of str or None
        The meta parameter to validate.
    Raises
    ------
    TypeError
        If meta contains elements that are not strings or lists of strings.
    Nz9All elements in nested meta paths must be strings. Found z: zBAll elements in 'meta' must be strings or lists of strings. Found )r'   r,   rI   	TypeErrortype__name__)metaitemsubitems      r   _validate_metarU     s     |$ dD! !'3/#!!%g!7!7 87+G  D#&d,,-Rx9 r   pandasc                   t        |       	 d	 	 	 	 	 	 	 dfddfdt        | t              r| j                  }nd}t        | t              r| s
t               S t        | t              r| g} nvt        | t        j                        rVt        | t              sFt	        |       } | D ]5  }	t        |	t              rdt        |	      j                   }
t        |
       nt        | ||t        t        |       |      S |Ft        d | D              rt!        |       } t        | |      }|j#                  fd	
      }|S t        |t              s|g}|g }nt        |t              s|g}|D cg c]  }t        |t              r|n|g c}g g t%        t              D cg c]  }j'                  |       c}ddf
d | |i d       t              }|j#                  fd
      }j)                         D ]  \  }}|||z   }||v rt+        d| d      t-        j.                  |t0              }|j2                  dkD  r=t-        j4                  t7        |      ft0              }t9        |      D ]
  \  }}|||<    |j;                        ||<    ||j;                        |_        |S c c}w c c}w )a>  
    Normalize semi-structured JSON data into a flat table.

    This method is designed to transform semi-structured JSON data, such as nested
    dictionaries or lists, into a flat table. This is particularly useful when
    handling JSON-like data structures that contain deeply nested fields.

    Parameters
    ----------
    data : dict, list of dicts, or Series of dicts
        Unserialized JSON objects.
    record_path : str or list of str, default None
        Path in each object to list of records. If not passed, data will be
        assumed to be an array of records.
    meta : list of paths (str or list of str), default None
        Fields to use as metadata for each record in resulting table.
    meta_prefix : str, default None
        String to prefix records with dotted path, e.g. foo.bar.field if
        meta is ['foo', 'bar'].
    record_prefix : str, default None
        String to prefix records with dotted path, e.g. foo.bar.field if
        path to records is ['foo', 'bar'].
    errors : {'raise', 'ignore'}, default 'raise'
        Configures error handling.

        * 'ignore' : will ignore KeyError if keys listed in meta are not
          always present.
        * 'raise' : will raise KeyError if keys listed in meta are not
          always present.
    sep : str, default '.'
        Nested records will generate names separated by sep.
        e.g., for sep='.', {'foo': {'bar': 0}} -> foo.bar.
    max_level : int, default None
        Max number of levels(depth of dict) to normalize.
        if None, normalizes all levels.

    Returns
    -------
    DataFrame
        The normalized data, represented as a pandas DataFrame.

    See Also
    --------
    DataFrame : Two-dimensional, size-mutable, potentially heterogeneous tabular data.
    Series : One-dimensional ndarray with axis labels (including time series).

    Examples
    --------
    >>> data = [
    ...     {"id": 1, "name": {"first": "Coleen", "last": "Volk"}},
    ...     {"name": {"given": "Mark", "family": "Regner"}},
    ...     {"id": 2, "name": "Faye Raker"},
    ... ]
    >>> pd.json_normalize(data)
        id name.first name.last name.given name.family        name
    0  1.0     Coleen      Volk        NaN         NaN         NaN
    1  NaN        NaN       NaN       Mark      Regner         NaN
    2  2.0        NaN       NaN        NaN         NaN  Faye Raker

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> pd.json_normalize(data, max_level=0)
        id        name                        fitness
    0  1.0   Cole Volk  {'height': 130, 'weight': 60}
    1  NaN    Mark Reg  {'height': 130, 'weight': 60}
    2  2.0  Faye Raker  {'height': 130, 'weight': 60}

    Normalizes nested data up to level 1.

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> pd.json_normalize(data, max_level=1)
        id        name  fitness.height  fitness.weight
    0  1.0   Cole Volk             130              60
    1  NaN    Mark Reg             130              60
    2  2.0  Faye Raker             130              60

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> series = pd.Series(data, index=pd.Index(["a", "b", "c"]))
    >>> pd.json_normalize(series)
        id        name  fitness.height  fitness.weight
    a  1.0   Cole Volk             130              60
    b  NaN    Mark Reg             130              60
    c  2.0  Faye Raker             130              60

    >>> data = [
    ...     {
    ...         "state": "Florida",
    ...         "shortname": "FL",
    ...         "info": {"governor": "Rick Scott"},
    ...         "counties": [
    ...             {"name": "Dade", "population": 12345},
    ...             {"name": "Broward", "population": 40000},
    ...             {"name": "Palm Beach", "population": 60000},
    ...         ],
    ...     },
    ...     {
    ...         "state": "Ohio",
    ...         "shortname": "OH",
    ...         "info": {"governor": "John Kasich"},
    ...         "counties": [
    ...             {"name": "Summit", "population": 1234},
    ...             {"name": "Cuyahoga", "population": 1337},
    ...         ],
    ...     },
    ... ]
    >>> result = pd.json_normalize(
    ...     data, "counties", ["state", "shortname", ["info", "governor"]]
    ... )
    >>> result
             name  population    state shortname info.governor
    0        Dade       12345   Florida    FL    Rick Scott
    1     Broward       40000   Florida    FL    Rick Scott
    2  Palm Beach       60000   Florida    FL    Rick Scott
    3      Summit        1234   Ohio       OH    John Kasich
    4    Cuyahoga        1337   Ohio       OH    John Kasich

    >>> data = {"A": [1, 2]}
    >>> pd.json_normalize(data, "A", record_prefix="Prefix.")
        Prefix.0
    0          1
    1          2

    Returns normalized data with columns prefixed with the given string.
    c                   | }	 t        |t              r|D ]  }|t        |      ||   } 	 |S ||   }	 |S # t        $ rD}|rt        d| d      |dk(  rt        j                  cY d}~S t        d| d| d      |d}~ww xY w)zInternal function to pull fieldNzKey zS not found. If specifying a record_path, all elements of data should have the path.ignorez) not found. To replace missing values of z% with np.nan, pass in errors='ignore')r'   rI   KeyErrornpnan)jsspecextract_recordresultfieldeerrorss         r   _pull_fieldz#json_normalize.<locals>._pull_field  s     	$%! +E~&uo-#E]F+(      	1# 1 2  !vv1#Fqc J6 7 	s%   )9 9 	B&B(B.BBc                     | |d      }t        |t              s=t        j                  |      rg }|S t	        dt        |      j                   d|      |S )z
        Internal function to pull field for records, and similar to
        _pull_field, but require to return list. And will raise error
        if has non iterable value.
        T)r_   z(Path must contain list or null, but got z at )r'   rI   pdisnullrO   rP   rQ   )r]   r^   r`   rd   s      r   _pull_recordsz%json_normalize.<locals>._pull_records  sn     Rd; &$'yy  	  #F|445T$C  r   Nz.All items in data must be of type dict, found rH   )indexc              3  ~   K   | ]0  }|j                         D cg c]  }t        |t               c} 2 y c c}w wr   )valuesr'   r(   ).0yxs      r   	<genexpr>z!json_normalize.<locals>.<genexpr>/  s+     GQQXXZ8
1d#8G8s   =8=r!   r#   c                     |  S r   r   rn   record_prefixs    r   <lambda>z json_normalize.<locals>.<lambda>:  s    qc5J r   )columnsr   c           	     p  
 t        | t              r| g} t        |      dkD  rW| D ]Q  }t        
d      D ]&  \  }}|dz   t        |      k(  s ||d         ||<   (  ||d      |dd  ||dz          S y | D ]  } ||d         }|D cg c]"  }t        |t              rt	        |      n|$ }}j                  t        |             t        
d      D ]<  \  }}|dz   t        |      kD  r||   }	n |||d        }	|   j                  |	       > j                  |        y c c}w )Nr   T)strictr   r   r"   rp   )r'   r(   lenzipr$   r/   extend)r9   path	seen_metar"   objvalr?   recsrmeta_val_metard   rh   _recursive_extractlengthsr#   	meta_keys	meta_valsrecordsr!   s             r   r   z*json_normalize.<locals>._recursive_extractM  sr   dD!6Dt9q= W #E9T B CHCqyCH,)4S#b')B	#C #3tAw<ab9ETUIVW  %$S$q'2
 "	  "!T* %QC9E  s4y) #E9T B 4HCqy3s8+#,S>#.sCK#@cN))(34 t$#%s   'D3rx   c                     |  S r   r   rr   s    r   rt   z json_normalize.<locals>.<lambda>p  s    M?1#1F r   zConflicting metadata name z, need distinguishing prefix )dtyper   )F)r]   dict[str, Any]r^   
list | strr_   boolreturnzScalar | Iterable)r]   r   r^   r   r   rI   )r   )r"   intr   None)rU   r'   r   ri   rI   r   r(   r   r   r,   rP   rQ   rO   NotImplementedErrorrJ   anyr$   renamer   joinr+   
ValueErrorr[   arrayobjectndimemptyry   	enumeraterepeat)r9   record_pathrR   meta_prefixrs   rc   r!   r#   ri   rS   msgr`   mr   r4   r5   rk   ir   rd   rh   r   r   r   r   r   s       ````          @@@@@@@@r   json_normalizer   -  s   T 4 FK",>B	:( $

$d{	D$	v	D#,,	'
40E Dz 	%DdD)!$Z0013   n$	% "! 	L!/#>eLLG$GG $DcYGD4u-$]]+J]KFT*"m|d#v8<=1*Q%QA3.=E GG(.I*/03#0I% %< t["A6wF 'FG ! +1"aA;,QC/LM 
 !6*;;?XXs1viv6F#A,  3q	  MM'*q	%+& ||G,MI > 1s   K!K&)r   r,   r   r,   )....)r   r(   r    r,   r!   r,   r"   r   r#   
int | Noner   r   )r   z
list[dict]r    r,   r!   r,   r"   r   r#   r   r   zlist[dict[str, Any]])rC   .r   N)r   dict | list[dict]r    r,   r!   r,   r"   r   r#   r   r   z%dict[str, Any] | list[dict[str, Any]])
r9   r   r:   r,   r;   r   r<   r,   r   r   )r9   r   r<   r,   r   r   )r   )r   r   r!   r,   r   zdict | list[dict] | Any)rR   "str | list[str | list[str]] | Noner   r   )NNNNraiser   N)r9   zdict | list[dict] | Seriesr   zstr | list | NonerR   r   r   
str | Noners   r   rc   r   r!   r,   r#   r   r   r   )!
__future__r   collectionsr   r   r)   typingr   r   r   r	   numpyr[   pandas._libs.writersr   pandas.util._decoratorsr   rV   rf   r   r   collections.abcr   pandas._typingr   r   r   r$   r>   rF   rJ   rU   r   r   r   r   <module>r      s>   #    6 . 
 (
$ 
  
 	
   
 
  
 	
   
  NNN 
N 	N
 N +Nb&
&& $& 	&
 &R)6 2"2"	2" 2"j> H &*/3" $! Z
$Z"Z -Z 	Z
 Z Z 
Z Z Z Zr   