o
    ;Di"5                     @   s  d dl mZmZmZ d dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZmZmZ d
d ZG dd deZd"ddZG dd deZG dd deZdd Zdd Zd#ddZ e e_ 		d$ddZ!e!e_!dd Z"d%d d!Z#dS )&    )absolute_importprint_functiondivisionN)JSONEncoder)unlink)NamedTemporaryFile)PY2)pickle)read_source_from_argwrite_source_from_arg)dataTabledictsiterpeekc                 O   s   t | } t| g|R i |S )aB  
    Extract data from a JSON file. The file must contain a JSON array as
    the top level object, and each member of the array will be treated as a
    row of data. E.g.::

        >>> import petl as etl
        >>> data = '''
        ... [{"foo": "a", "bar": 1},
        ... {"foo": "b", "bar": 2},
        ... {"foo": "c", "bar": 2}]
        ... '''
        >>> with open('example.file1.json', 'w') as f:
        ...     f.write(data)
        ...
        74
        >>> table1 = etl.fromjson('example.file1.json', header=['foo', 'bar'])
        >>> table1
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'a' |   1 |
        +-----+-----+
        | 'b' |   2 |
        +-----+-----+
        | 'c' |   2 |
        +-----+-----+

    Setting argument `lines` to `True` will enable to
    infer the document as a JSON lines document. For more details about JSON lines
    please visit https://jsonlines.org/.

        >>> import petl as etl
        >>> data_with_jlines = '''{"name": "Gilbert", "wins": [["straight", "7S"], ["one pair", "10H"]]}
        ... {"name": "Alexa", "wins": [["two pair", "4S"], ["two pair", "9S"]]}
        ... {"name": "May", "wins": []}
        ... {"name": "Deloise", "wins": [["three of a kind", "5S"]]}'''
        ...
        >>> with open('example.file2.json', 'w') as f:
        ...     f.write(data_with_jlines)
        ...
        223
        >>> table2 = etl.fromjson('example.file2.json', lines=True)
        >>> table2
        +-----------+-------------------------------------------+
        | name      | wins                                      |
        +===========+===========================================+
        | 'Gilbert' | [['straight', '7S'], ['one pair', '10H']] |
        +-----------+-------------------------------------------+
        | 'Alexa'   | [['two pair', '4S'], ['two pair', '9S']]  |
        +-----------+-------------------------------------------+
        | 'May'     | []                                        |
        +-----------+-------------------------------------------+
        | 'Deloise' | [['three of a kind', '5S']]               |
        +-----------+-------------------------------------------+

    If your JSON file does not fit this structure, you will need to parse it
    via :func:`json.load` and select the array to treat as the data, see also
    :func:`petl.io.json.fromdicts`.

    .. versionchanged:: 1.1.0

    If no `header` is specified, fields will be discovered by sampling keys
    from the first `sample` objects in `source`. The header will be
    constructed from keys in the order discovered. Note that this
    ordering may not be stable, and therefore it may be advisable to specify
    an explicit `header` or to use another function like
    :func:`petl.transform.headers.sortheader` on the resulting table to
    guarantee stability.

    )r
   JsonView)sourceargskwargs r   E/var/www/Datamplify/venv/lib/python3.10/site-packages/petl/io/json.pyfromjson   s   Hr   c                   @   s   e Zd Zdd Zdd ZdS )r   c                 O   sN   || _ |dd | _|dd | _|dd| _|dd| _|| _|| _d S )Nmissingheadersample  linesF)r   popr   r   r   r   r   r   )selfr   r   r   r   r   r   __init__`   s   
zJsonView.__init__c              	   c   s    | j dU}tstj|dddd}z8| jr&t|| j| jD ]}|V  qnt	j
|g| jR i | j}t|| j| j| jD ]}|V  q>W tsK|  ntsS|  w w W d    d S 1 s_w   Y  d S )Nrbutf-8 Tencodingnewlinewrite_through)r   openr   ioTextIOWrapperr   
iterjlinesr   r   jsonloadr   r   	iterdictsr   detach)r   frowr   r   r   r   __iter__i   s2   

"zJsonView.__iter__N__name__
__module____qualname__r   r0   r   r   r   r   r   _   s    	r   r   c                 C   s"   t | rtnt}|| |||dS )a8  
    View a sequence of Python :class:`dict` as a table. E.g.::

        >>> import petl as etl
        >>> dicts = [{"foo": "a", "bar": 1},
        ...          {"foo": "b", "bar": 2},
        ...          {"foo": "c", "bar": 2}]
        >>> table1 = etl.fromdicts(dicts, header=['foo', 'bar'])
        >>> table1
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'a' |   1 |
        +-----+-----+
        | 'b' |   2 |
        +-----+-----+
        | 'c' |   2 |
        +-----+-----+

    Argument `dicts` can also be a generator, the output of generator
    is iterated and cached using a temporary file to support further
    transforms and multiple passes of the table:

        >>> import petl as etl
        >>> dicts = ({"foo": chr(ord("a")+i), "bar":i+1} for i in range(3))
        >>> table1 = etl.fromdicts(dicts, header=['foo', 'bar'])
        >>> table1
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'a' |   1 |
        +-----+-----+
        | 'b' |   2 |
        +-----+-----+
        | 'c' |   3 |
        +-----+-----+

    If `header` is not specified, `sample` items from `dicts` will be
    inspected to discovery dictionary keys. Note that the order in which
    dictionary keys are discovered may not be stable,

    See also :func:`petl.io.json.fromjson`.

    .. versionchanged:: 1.1.0

    If no `header` is specified, fields will be discovered by sampling keys
    from the first `sample` dictionaries in `dicts`. The header will be
    constructed from keys in the order discovered. Note that this
    ordering may not be stable, and therefore it may be advisable to specify
    an explicit `header` or to use another function like
    :func:`petl.transform.headers.sortheader` on the resulting table to
    guarantee stability.

    .. versionchanged:: 1.7.5

    Full support of generators passed as `dicts` has been added, leveraging
    `itertools.tee`.

    .. versionchanged:: 1.7.11

    Generator support has been modified to use temporary file cache
    instead of `itertools.tee` due to high memory usage.

    )r   r   r   )inspectisgeneratorDictsGeneratorView	DictsView)r   r   r   r   viewr   r   r   	fromdicts}   s   Ar:   c                   @   s   e Zd ZdddZdd ZdS )r8   Nr   c                 C   s   || _ || _|| _|| _d S N)r   _headerr   r   r   r   r   r   r   r   r   r   r      s   
zDictsView.__init__c                 C   s   t | j| j| j| jS r;   )r,   r   r<   r   r   r   r   r   r   r0      s   zDictsView.__iter__Nr   Nr1   r   r   r   r   r8      s    
r8   c                       s6   e Zd Zd fdd	Zdd Zdd Zd	d
 Z  ZS )r7   Nr   c                    s&   t t| |||| d | _d| _d S )Nr   )superr7   r   
_filecache_cachedr=   	__class__r   r   r      s   
zDictsGeneratorView.__init__c                 #   s    j s  j V  js"trtdddd_ntdddd_d}tj}	 |jk rDj| t	
j}j }|V  q)zt| W n
 tyT   Y d S w t fddj D }jj t	j|jd	d
 j  _}|V  q*)NFzwb+r   )deletemodebufsize)rE   rF   	bufferingTc                 3   s    | ]
}  |jV  qd S r;   )getr   .0r.   or   r   r   	<genexpr>   s    z.DictsGeneratorView.__iter__.<locals>.<genexpr>)protocol)r<   _determine_headerrA   r   r   iterr   rB   seekr	   r+   tellnextStopIterationtupledump)r   positionitr/   r   rL   r   r0      s8   


zDictsGeneratorView.__iter__c                    sr   t | j}t  t|| j\}}|| _t|tr|g}|D ]}t|dr1  fdd| D 7  qt	 | _
|S )Nkeysc                       g | ]}| vr|qS r   r   rK   kr   r   r   
<listcomp>       z8DictsGeneratorView._determine_header.<locals>.<listcomp>)rR   r   listr   r   
isinstancedicthasattrr[   rW   r<   )r   rZ   peekrM   r   r_   r   rQ      s   



z$DictsGeneratorView._determine_headerc                 C   s$   | j r| j   t| j j d S d S r;   )rA   closer   namer>   r   r   r   __del__   s   
zDictsGeneratorView.__del__r?   )r2   r3   r4   r   r0   rQ   ri   __classcell__r   r   rC   r   r7      s
    r7   c                 #   s    t | } d u r*t  t|d\}}t|tdr*  fdd D 7  t V  |D ]}t|tfdd D V  q1d S )N   r[   c                    r\   r   r   r]   r_   r   r   r`     ra   ziterjlines.<locals>.<listcomp>c                 3   s$    | ]}| v r | nV  qd S r;   r   rJ   )json_objr   r   r   rN     s   " ziterjlines.<locals>.<genexpr>)rR   rb   r   r*   loadsre   r[   rW   )r.   r   r   rZ   rf   rM   r   )r   rl   r   r   r)     s   



r)   c                 #   s    t | } d u r*t  t||\}}|D ]tdr)  fdd D 7  qt V  |D ]tfdd D V  q1d S )Nr[   c                    r\   r   r   r]   r_   r   r   r`      ra   ziterdicts.<locals>.<listcomp>c                 3   s    | ]	} | V  qd S r;   )rI   rJ   )r   rM   r   r   rN   %  s    ziterdicts.<locals>.<genexpr>)rR   rb   r   re   r[   rW   )r   r   r   r   rZ   rf   r   )r   r   rM   r   r,     s   

r,   c                 O   s,   t t| }t||||g|R i | dS )a  
    Write a table in JSON format, with rows output as JSON objects. E.g.::

        >>> import petl as etl
        >>> table1 = [['foo', 'bar'],
        ...           ['a', 1],
        ...           ['b', 2],
        ...           ['c', 2]]
        >>> etl.tojson(table1, 'example.file3.json', sort_keys=True)
        >>> # check what it did
        ... print(open('example.file3.json').read())
        [{"bar": 1, "foo": "a"}, {"bar": 2, "foo": "b"}, {"bar": 2, "foo": "c"}]



    Setting argument `lines` to `True` will enable to
    infer the writing format as a JSON lines . For more details about JSON lines
    please visit https://jsonlines.org/.

        >>> import petl as etl
        >>> table1 = [['name', 'wins'],
        ...           ['Gilbert', [['straight', '7S'], ['one pair', '10H']]],
        ...           ['Alexa', [['two pair', '4S'], ['two pair', '9S']]],
        ...           ['May', []],
        ...           ['Deloise',[['three of a kind', '5S']]]]
        >>> etl.tojson(table1, 'example.file3.jsonl', lines = True, sort_keys=True)
        >>> # check what it did
        ... print(open('example.file3.jsonl').read())
        {"name": "Gilbert", "wins": [["straight", "7S"], ["one pair", "10H"]]}
        {"name": "Alexa", "wins": [["two pair", "4S"], ["two pair", "9S"]]}
        {"name": "May", "wins": []}
        {"name": "Deloise", "wins": [["three of a kind", "5S"]]}

    Note that this is currently not streaming, all data is loaded into memory
    before being written to the file.

    N)rb   _dicts
_writejson)tabler   prefixsuffixr   r   objr   r   r   tojson(  s   ' rt   Fc                 O   s:   |rt | }nt t| }t||||g|R i | dS )a"  
    Write a table in JSON format, with rows output as JSON arrays. E.g.::

        >>> import petl as etl
        >>> table1 = [['foo', 'bar'],
        ...           ['a', 1],
        ...           ['b', 2],
        ...           ['c', 2]]
        >>> etl.tojsonarrays(table1, 'example.file4.json')
        >>> # check what it did
        ... print(open('example.file4.json').read())
        [["a", 1], ["b", 2], ["c", 2]]

    Note that this is currently not streaming, all data is loaded into memory
    before being written to the file.

    N)rb   r   ro   )rp   r   rq   rr   output_headerr   r   rs   r   r   r   tojsonarraysV  s   
 rv   c           	   	   O   s   | dd}t|i |}t| } | d=}tr$t||||||d ntj|dddd}zt||||||d W |  n|  w W d    d S W d    d S 1 sVw   Y  d S )	Nr   Fwb)r   r    r!   Tr"   )	r   r   r   r&   r   	_writeobjr'   r(   r-   )	r   rs   rq   rr   r   r   r   encoderr.   r   r   r   ro   t  s    
"ro   c                 C   sz   |d ur	| | |r#|D ]}| |D ]}| | q| d qn| |D ]}| | q(|d ur;| | d S d S )N
)write
iterencode)ry   rs   r.   rq   rr   r   recchunkr   r   r   rx     s   
rx   r?   )NNN)NNNF)F)$
__future__r   r   r   r'   r*   r5   json.encoderr   osr   tempfiler   petl.compatr   r	   petl.io.sourcesr
   r   petl.util.baser   r   r   rn   r   r   r   r:   r8   r7   r)   r,   rt   rv   ro   rx   r   r   r   r   <module>   s4   L
E8
+
