U
    TZfI                     @   s   d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZ d dl	m
Z
 d dlmZ G dd deZe Zdd	 Zd
Zed Zdd ZdddZd ddZd!ddZd"ddZd#ddZd$ddZdd ZdS )%    N)Path)validate_coerce_fig_to_dictvalidate_coerce_output_type)
get_module)ImageUriValidatorc                   @   s>   e Zd ZdZdd Zedd Zejdd Zedd Z	d	S )

JsonConfig)jsonorjsonautoc                 C   s
   d| _ d S )Nr
   _default_engineself r   3/tmp/pip-unpacked-wheel-5ksk5baj/plotly/io/_json.py__init__   s    zJsonConfig.__init__c                 C   s   | j S Nr   r   r   r   r   default_engine   s    zJsonConfig.default_enginec                 C   s8   |t jkrtdjt j|d|dkr.|   || _d S )Nz9Supported JSON engines include {valid}
    Received {val})Zvalidvalr	   )r   _valid_engines
ValueErrorformatvalidate_orjsonr   )r   r   r   r   r   r      s    
 c                 C   s   t d}|d krtdd S )Nr	   z-The orjson engine requires the orjson package)r   r   )clsr	   r   r   r   r   %   s    zJsonConfig.validate_orjsonN)
__name__
__module____qualname__r   r   propertyr   setterclassmethodr   r   r   r   r   r      s   

r   c                 C   s   | dkrdS | S dS )zM
    This is used to ultimately *encode* into strict JSON, see `encode`

    )Infinityz	-InfinityNaNNr   )constr   r   r   coerce_to_strict/   s    r#   ))<z\u003c)>z\u003e)/z\u002f))u    z\u2028)u    z\u2029c                 C   s*   | }|D ]\}}||kr| ||}q|S r   )replace)json_strZ_swapoutZunsafe_charZ	safe_charr   r   r   _safeF   s
    r*   Fc                 C   st  t ddd}|dkrtj}|dkr6|dk	r0d}qJd}n|dkrJtd| t d	d
dt dd
dt dd
dt dd
dd}|dkri }|rd|d< nd|d< ddlm} ttj| fd|i|t	S |dkrpt
  |j|jB }|r||jO }z|  } W n tk
r   Y nX zt|j| |ddtW S  tk
rD   Y nX t| dd|d}t|j||ddtS dS )a  
    Convert a plotly/Dash object to a JSON string representation

    Parameters
    ----------
    plotly_object:
        A plotly/Dash object represented as a dict, graph_object, or Dash component

    pretty: bool (default False)
        True if JSON representation should be pretty-printed, False if
        representation should be as compact as possible.

    engine: str (default None)
        The JSON encoding engine to use. One of:
          - "json" for an engine based on the built-in Python json module
          - "orjson" for a faster engine that requires the orjson package
          - "auto" for the "orjson" engine if available, otherwise "json"
        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.

    Returns
    -------
    str
        Representation of input object as a JSON string

    See Also
    --------
    to_json : Convert a plotly Figure to JSON with validation
    r	   TZshould_loadNr
   r   r	   r   Invalid json engine: %szsage.allFZnumpyZpandasz	PIL.Image)sage_allnppdimage   indent),:
separatorsr   )PlotlyJSONEncoderr   )optionutf8)numpy_alloweddatetime_allowedmodules)r   configr   r   Z_plotly_utils.utilsr7   r*   r   dumps
_swap_jsonr   r   ZOPT_NON_STR_KEYSZOPT_SERIALIZE_NUMPYZOPT_INDENT_2to_plotly_jsonAttributeErrordecode_swap_orjson	TypeErrorclean_to_json_compatible)Zplotly_objectprettyenginer	   r<   optsr7   cleanedr   r   r   to_json_plotlyN   s^    



	
 

 rJ   Tc                 C   s:   t | |}|r,|dg D ]}|dd qt|||dS )a  
    Convert a figure to a JSON string representation

    Parameters
    ----------
    fig:
        Figure object or dict representing a figure

    validate: bool (default True)
        True if the figure should be validated before being converted to
        JSON, False otherwise.

    pretty: bool (default False)
        True if JSON representation should be pretty-printed, False if
        representation should be as compact as possible.

    remove_uids: bool (default True)
        True if trace UIDs should be omitted from the JSON representation

    engine: str (default None)
        The JSON encoding engine to use. One of:
          - "json" for an engine based on the built-in Python json module
          - "orjson" for a faster engine that requires the orjson package
          - "auto" for the "orjson" engine if available, otherwise "json"
        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.

    Returns
    -------
    str
        Representation of figure as a JSON string

    See Also
    --------
    to_json_plotly : Convert an arbitrary plotly graph_object or Dash component to JSON
    datauidN)rF   rG   )r   getpoprJ   )figvalidaterF   remove_uidsrG   fig_dicttracer   r   r   to_json   s
    '
rT   c                 C   s   t | ||||d}t|tr&t|}nt|tr6|}nd}|dkrzz|| W dS  tk
rf   Y nX tdj|dn
|| dS )a+  
    Convert a figure to JSON and write it to a file or writeable
    object

    Parameters
    ----------
    fig:
        Figure object or dict representing a figure

    file: str or writeable
        A string representing a local file path or a writeable object
        (e.g. a pathlib.Path object or an open file descriptor)

    pretty: bool (default False)
        True if JSON representation should be pretty-printed, False if
        representation should be as compact as possible.

    remove_uids: bool (default True)
        True if trace UIDs should be omitted from the JSON representation

    engine: str (default None)
        The JSON encoding engine to use. One of:
          - "json" for an engine based on the built-in Python json module
          - "orjson" for a faster engine that requires the orjson package
          - "auto" for the "orjson" engine if available, otherwise "json"
        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.
    Returns
    -------
    None
    )rP   rF   rQ   rG   NzX
The 'file' argument '{file}' is not a string, pathlib.Path object, or file descriptor.
)file)	rT   
isinstancestrr   writerA   r   r   
write_text)rO   rU   rP   rF   rQ   rG   r(   pathr   r   r   
write_json   s0    $    




r[   c                 C   s   t ddd}t| ttfs0tdjt| | d|dkr>tj}|dkrZ|dk	rTd}qnd}n|d	krntd
| |dkrt	
  || }nt| tr| d} t| }|S )a  
    Parse JSON string using the specified JSON engine

    Parameters
    ----------
    value: str or bytes
        A JSON string or bytes object

    engine: str (default None)
        The JSON decoding engine to use. One of:
          - if "json", parse JSON using built in json module
          - if "orjson", parse using the faster orjson module, requires the orjson
            package
          - if "auto" use orjson module if available, otherwise use the json module

        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.

    Returns
    -------
    dict

    See Also
    --------
    from_json_plotly : Parse JSON with plotly conventions into a dict
    r	   Tr+   zr
from_json_plotly requires a string or bytes argument but received value of type {typ}
    Received value: {value})typvalueNr
   r   r,   r-   zutf-8)r   rV   rW   bytesr   r   typer=   r   r   r   loadsrB   r   )r]   rG   r	   Z
value_dictr   r   r   from_json_plotly,  s.     	


ra   Figurec                 C   s$   t | |d}t|}|||d}|S )a  
    Construct a figure from a JSON string

    Parameters
    ----------
    value: str or bytes
        String or bytes object containing the JSON representation of a figure

    output_type: type or str (default 'Figure')
        The output figure type or type name.
        One of:  graph_objs.Figure, 'Figure', graph_objs.FigureWidget, 'FigureWidget'

    skip_invalid: bool (default False)
        False if invalid figure properties should result in an exception.
        True if invalid figure properties should be silently ignored.

    engine: str (default None)
        The JSON decoding engine to use. One of:
          - if "json", parse JSON using built in json module
          - if "orjson", parse using the faster orjson module, requires the orjson
            package
          - if "auto" use orjson module if available, otherwise use the json module

        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.

    Raises
    ------
    ValueError
        if value is not a string, or if skip_invalid=False and value contains
        invalid figure properties

    Returns
    -------
    Figure or FigureWidget
    )rG   )skip_invalid)ra   r   )r]   output_typerc   rG   rR   r   rO   r   r   r   	from_jsonm  s    (re   c                 C   s\   t | t}t | trt| }nt | tr.| }nd}|dk	rD| }n|  }t||||dS )a  
    Construct a figure from the JSON contents of a local file or readable
    Python object

    Parameters
    ----------
    file: str or readable
       A string containing the path to a local file or a read-able Python
       object (e.g. a pathlib.Path object or an open file descriptor)

    output_type: type or str (default 'Figure')
        The output figure type or type name.
        One of:  graph_objs.Figure, 'Figure', graph_objs.FigureWidget, 'FigureWidget'

    skip_invalid: bool (default False)
        False if invalid figure properties should result in an exception.
        True if invalid figure properties should be silently ignored.

    engine: str (default None)
        The JSON decoding engine to use. One of:
          - if "json", parse JSON using built in json module
          - if "orjson", parse using the faster orjson module, requires the orjson
            package
          - if "auto" use orjson module if available, otherwise use the json module

        If not specified, the default engine is set to the current value of
        plotly.io.json.config.default_engine.

    Returns
    -------
    Figure or FigureWidget
    N)rc   rd   rG   )rV   rW   r   	read_textreadre   )rU   rd   rc   rG   Zfile_is_strrZ   r(   r   r   r   	read_json  s    %




   rh   c              	      s  t | tttfr| S t | tr4 fdd|  D S t | ttfrX| rX fdd| D S  dd} dd} di }|d	 }|d
 }|d }|d }|d k	r| |j	krt| S | |j
krt| S |d k	rt| |jjjkrtdS t | |jr^|r| jjdkr|| S | jjdkr0||  S | jjdkrF|  S | jjdkrt|  } nt | |jrtt| S |d k	rN| |jkrd S t | |j|jfrN|r| jjdkr|| jS | jjdkrNt | |jrt & tdt || j  }	W 5 Q R X n|   }	|sJt t!|	D ]}
|	|
 " |	|
< q2|	S z|  } W n t#t$fk
rt   Y nX |sz
| " W S  t#t$fk
r   Y nX nt | t%j%r| S z
|  W S  t$k
r   Y nX t | t&j'rt| S |d k	rt | |j(rt)*| S z| + } W n t$k
r2   Y nX t | trV fdd|  D S t | ttfr~| r~ fdd| D S | S )Nc                    s   i | ]\}}|t |f qS r   rE   .0kvkwargsr   r   
<dictcomp>  s      z,clean_to_json_compatible.<locals>.<dictcomp>c                    s   g | ]}t |f qS r   ri   rk   rm   rn   r   r   
<listcomp>  s     z,clean_to_json_compatible.<locals>.<listcomp>r:   Fr;   r<   r.   r/   r0   r1   nan)biufMUOignorec                    s   i | ]\}}|t |f qS r   ri   rj   rn   r   r   rp   R  s      c                    s   g | ]}t |f qS r   ri   rq   rn   r   r   rr   V  s     ),rV   intfloatrW   dictitemslisttuplerM   ZRRZZZmacoreZmaskedZndarrayZdtypekindZascontiguousarrayZdatetime_as_stringtolistZ
datetime64ZNaTZSeriesZDatetimeIndexvalueswarningscatch_warningssimplefilterFutureWarningarraydtZto_pydatetimerangelen	isoformatrD   rA   datetimedecimalDecimalZImager   Zpil_image_to_urir@   )objro   r:   r;   r<   r.   r/   r0   r1   Z	dt_valuesru   r   rn   r   rE     s    







 


rE   )FN)TFTN)TFTN)N)rb   FN)rb   FN)r   r   r   r   pathlibr   Zplotly.io._utilsr   r   Z_plotly_utils.optional_importsr   Z_plotly_utils.basevalidatorsr   objectr   r=   r#   r?   rC   r*   rJ   rT   r[   ra   re   rh   rE   r   r   r   r   <module>   s(   
`
2
L
A
4
?