o
    QDib                     @  sp  d dl mZ d dlm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mZ ddlmZmZmZ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 ddlmZ ddlmZ ddl m!Z! ddl"m#Z# erd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. ddl/m0Z0 ddl1m2Z2 ddlm3Z3 ej4dddG dd dee#dZ5d%d#d$Z6dS )&    )annotations)Pool)TYPE_CHECKINGAnyClassVarDictListOptionalUnionN)Self   )errorsfieldshelperssettings)	Checklist)FrictionlessException)Metadata)platform)ReportResource)system)Transformer   )Factory)types)Dataset)Detector)ControlDialect)IOnProgressIOnRow)Pipeline)TableResource)PublishResultTF)kw_onlyreprc                      s:  e Zd ZU dZejdddZded< 	 dZded< 	 ejdd	d
Z	ded< 	 dZ
ded< 	 dZded< 	 dZded< 	 dZded< 	 dZded< 	 dZded< 	 ejedZded< 	 ejedZded< 	 ejedZded< 	 ejedZded< 	 dZded< 	 dZded< 	 dZded< 	 ejedZded< 	 dZd ed!< 	 ejdd"d
Zd#ed$< 	 ejdd%d
Zd&ed'< 	  fd(d)Zedd+d,Zejdd.d,Zedd/d0Z edd1d2Z!dd6d7Z"dd:d;Z#dd<d=Z$dd>d?Z%ddAdBZ&ddDdEZ'ddHdIZ(ddJdKZ)dLdM Z*dNdO Z+ddPddSdTZ,	dddUddYdZZ-dd[gfdd]d^Z.d_d` Z/ddaddcddZ0e1	dddPddfdgZ2dddddhddpdqZ3dddddddrdd{d|Z4dddZ5	dddde6j7ddddZ8d fddZ9ddddZ:dZ;e<j=Z>ddgde6j?dde6j@dddiddiddiddiddddiddiddidddddddiddiddidddddddiddiddiddiddiddddddidddiddiddidddidddZAe1dddZBe1dddZCe1d fddZDe1d fddZEe1d fddZF fddZG  ZHS )Packageu  Package representation

    This class is one of the cornerstones of of Frictionless framework.
    It manages underlaying resource and provides an ability to describe a package.

    ```python
    package = Package(resources=[Resource(path="data/table.csv")])
    package.get_resoure('table').read_rows() == [
        {'id': 1, 'name': 'english'},
        {'id': 2, 'name': '中国人'},

    NF)defaultr&   Optional[Any]sourceOptional[Control]controlbasepath)r)   aliasOptional[str]	_basepathnamezClassVar[Union[str, None]]typetitledescriptionhomepageprofile)factoryzList[Dict[str, Any]]licensessourcescontributors	List[str]keywordsimageversioncreatedzList[Resource]	resourceszOptional[Dataset]datasetdialectzOptional[Dialect]_dialectdetectorzOptional[Detector]	_detectorc                   s<   | j D ]}| |_| jr| j|_| jr| j|_qt   d S N)rA   packagerD   rC   rF   rE   super__attrs_post_init__selfresource	__class__ U/var/www/Datamplify/venv/lib/python3.10/site-packages/frictionless/package/package.pyrJ      s   
zPackage.__attrs_post_init__returnc                 C  s   | j r| j S | jr| jjS dS )zq
        A basepath of the package
        The normpath of the resource is joined `basepath` and `/path`
        N)r1   rB   r.   rL   rP   rP   rQ   r.      s
   zPackage.basepathvaluec                 C  s
   || _ d S rG   )r1   )rL   rT   rP   rP   rQ   r.         
c                 C     dd | j D S )Return names of resourcesc                 S     g | ]
}|j d ur|j qS rG   r2   .0rM   rP   rP   rQ   
<listcomp>       z*Package.resource_names.<locals>.<listcomp>rA   rS   rP   rP   rQ   resource_names      zPackage.resource_namesc                 C  rV   )rW   c                 S  rX   rG   )pathrZ   rP   rP   rQ   r\      r]   z*Package.resource_paths.<locals>.<listcomp>r^   rS   rP   rP   rQ   resource_paths   r`   zPackage.resource_pathsrM   Union[Resource, str]r   c                 C  s0   t |trtj|| jd}| j| | |_|S )zAdd new resource to the package)r.   )
isinstancestrr   from_descriptorr.   rA   appendrH   rK   rP   rP   rQ   add_resource   s
   
zPackage.add_resourcere   boolc                 C  s    | j D ]
}|j|kr dS qdS )zCheck if a resource is presentTF)rA   r2   rL   r2   rM   rP   rP   rQ   has_resource   s
   

zPackage.has_resourcec                 C  s.   | j D ]}|j|krt|tjjr dS qdS )z$Check if a table resource is presentTF)rA   r2   rd   r   frictionless_resourcesr$   rj   rP   rP   rQ   has_table_resource   s   

zPackage.has_table_resourcec                 C  s:   | j D ]}|j|kr|  S qtjd| dd}t|)zGet resource by name
resource "z" does not existnote)rA   r2   r   PackageErrorr   rL   r2   rM   errorrP   rP   rQ   get_resource   s   

zPackage.get_resourcer$   c                 C  s8   |  |}t|tjjr|S tjd| dd}t|)z/Get table resource by name (raise if not table)rn   z" is not tabularro   )rt   rd   r   rl   r$   r   rq   r   rr   rP   rP   rQ   get_table_resource   s
   
zPackage.get_table_resourceOptional[Resource]c                 C  sP   |j sJ | |j r!| |j }| j|}|| j|< | |_|S | | dS )zSet resource by nameN)r2   rk   rt   rA   indexrH   rh   )rL   rM   prev_resourcerw   rP   rP   rQ   set_resource   s   

zPackage.set_resource
descriptortypes.IDescriptorc                 C  sF   |  |}| j|}| }|| t|}| |_|| j|< |S )zUpdate resource)rt   rA   rw   to_descriptorupdater   rf   rH   )rL   r2   rz   rx   resource_indexresource_descriptornew_resourcerP   rP   rQ   update_resource   s   



zPackage.update_resourcec                 C  s   |  |}| j| |S )zRemove resource by name)rt   rA   removerj   rP   rP   rQ   remove_resource  s   
zPackage.remove_resourcec                 C  s
   g | _ dS )zRemove all the resourcesNr^   rS   rP   rP   rQ   clear_resources  rU   zPackage.clear_resourcesc                 C  sr   t | jt t| jkr5g }t| jD ]#\}}|j}||d }|dkr/d||f | j| _|| qd S d S )Nr   z%s%s)lenr_   set	enumeraterA   r2   countrg   )rL   
seen_namesrw   rM   r2   r   rP   rP   rQ   deduplicate_resoures  s   zPackage.deduplicate_resouresstatsr   Nonec                C  s   | j D ]}|j|d qdS )zgInfer metadata

        Parameters:
            stats: stream files completely and infer stats
        r   N)rA   infer)rL   r   rM   rP   rP   rQ   r     s   
zPackage.infer)r-   targetr   r%   c                C  sB   t j||dd}|std| d||  }|std|S )a'  Publish package to any supported data portal

        Parameters:
            target (string): url e.g. "https://github.com/frictionlessdata/repository-demo" of target[CKAN/Github...]
            control (dict): Github control

        Returns:
            Any: Response from the target
        T)r-   	packagifyzNot supported target: z or controlzNot supported action)r   create_adapterr   write_packageto_copy)rL   r   r-   adapterra   rP   rP   rQ   publish(  s   zPackage.publishra   specc                   s>   g }| j D ]}i   |  | fdd|D  q|S )zFlatten the package

        Parameters
            spec (str[]): flatten specification

        Returns:
            any[]: flatten package
        c                   s   g | ]}  |qS rP   )get)r[   propcontextrP   rQ   r\   K  s    z#Package.flatten.<locals>.<listcomp>)rA   r}   r|   rg   )rL   r   resultrM   rP   r   rQ   flatten>  s   	
zPackage.flattenc                 C  s   | j D ]}|  qdS )zDereference underlaying metadata

        If some of underlaying metadata is provided as a string
        it will replace it by the metadata object
        N)rA   dereferencerK   rP   rP   rQ   r   P  s   

zPackage.dereferencedetailedr   c                C  s4   i }| j D ]}t|tjjr|j|d||j< q|S )a  Analyze the resources of the package

        This feature is currently experimental, and its API may change
        without warning.

        Parameters:
            detailed? (bool): detailed analysis

        Returns:
            dict: dict of resource analysis

        r   )rA   rd   r   rl   r$   analyzer2   )rL   r   analysisrM   rP   rP   rQ   r   [  s   
zPackage.analyzeoptionsc                K  s*   t j|fd|d|}t|tsJ |S )a  Describe the given source as a package

        Parameters:
            source (any): data source
            stats? (bool): if `True` infer resource's stats
            **options (dict): Package constructor options

        Returns:
            Package: data package

        rH   )r3   r   )r   describerd   r(   )clsr+   r   r   metadatarP   rP   rQ   r   p  s   zPackage.describe)r2   filterprocess
limit_rowsr   Optional[types.IFilterFunction]r    Optional[types.IProcessFunction]r   Optional[int]types.ITabularDatac          	      C  sT   i }|du r	| j n| |g}|D ]}t|tjjr'|j|||d}|| q|S )a  Extract rows

        Parameters:
            filter: row filter function
            process: row processor function
            limit_rows: limit amount of rows to this number

        Returns:
            extracted rows indexed by resource name

        N)r   r   r   )rA   rt   rd   r   rl   r$   extractr}   )	rL   r2   r   r   r   datarA   resitemrP   rP   rQ   r     s   
zPackage.extract)r2   faston_rowon_progressuse_fallbackqsv_pathdatabase_urlr   r   Optional[IOnRow]r   Optional[IOnProgress]r   r   c                C  sV   g }|d u r	| j n| |g}	|	D ]}
t|
tjjr(||
j||||||d q|S )N)r   r   r   r   r   r   )rA   rt   rd   r   rl   r$   extendrw   )rL   r   r2   r   r   r   r   r   namesrA   rM   rP   rP   rQ   rw     s    
zPackage.indexrL   pipeliner#   c                 C  s   t  }|| |S )zTransform package

        Parameters:
            source (any): data source
            steps (Step[]): transform steps
            **options (dict): Package constructor options

        Returns:
            Package: the transform result
        )r   transform_package)rL   r   transformerrP   rP   rQ   	transform  s   zPackage.transform)r2   parallelr   limit_errors	checklistOptional[Checklist]r   r   intc             
   C  sx  t  }g }|du r| jn| |g}tdd |D }	|p t }z| jdd W n tyE }
 ztj	|j
|
 dW  Y d}
~
S d}
~
ww |rJ|	r]|D ]}|j|||d}|| qLnWt L}g }|D ],}i }i |d< | |d d	< |j|d d
< i |d< ||d d< ||d d< || qe|t|}|D ]
}|t| qW d   n1 sw   Y  tj|j
|dS )a7  Validate package

        Parameters:
            checklist? (checklist): a Checklist object
            parallel? (bool): run in parallel if possible. Parallel execution
            is not possible if foreign keys are used in a resource schema.

        Returns:
            Report: validation report

        Nc                 s  s    | ]
}|j o
|j jV  qd S rG   )schemaforeign_keys)r[   r   rP   rP   rQ   	<genexpr>  s    
z#Package.validate.<locals>.<genexpr>T)validate)timer   )r   r   r   rM   rz   r.   r   r   r   )r   reports)r   TimerrA   rt   anyr   r|   r   r   from_validationr   	to_errorsr   rg   r   r.   map_validate_parallelrf   from_validation_reports)rL   r   r2   r   r   r   timerr   rA   with_foreign_keys	exceptionrM   reportpooloptions_poolr   report_descriptorsreport_descriptorrP   rP   rQ   r     sT   
 
zPackage.validater   c                   s*   t  jddd | jD | j| jd|S )zCreate a copy of the packagec                 S  s   g | ]}|  qS rP   )r   rZ   rP   rP   rQ   r\     s    z#Package.to_copy.<locals>.<listcomp>)rA   r.   rB   NrP   )rI   r   rA   r.   rB   )rL   r   rN   rP   rQ   r     s   zPackage.to_copyc              
   C  s`   t jj }|| }|r.z	t|| W |S  ty- } ztt	j
t|d|d}~ww |S )aF  Generate ERD(Entity Relationship Diagram) from package resources
        and exports it as .dot file

        Based on:
        - https://github.com/frictionlessdata/frictionless-py/issues/1118

        Parameters:
            path (str): target path

        Returns:
            path(str): location of the .dot file
        ro   N)r   frictionless_formatserd	ErdMapperr   r   
write_file	Exceptionr   r   rq   re   )rL   ra   mappertextexcrP   rP   rQ   to_er_diagram$  s   
zPackage.to_er_diagramrH   objectstring)r3   patternarray)r2   ra   r4   )r3   
properties)r3   items)r4   ra   email)r4   ra   r   organisationrole)r2   r3   r4   r5   r6   r7   r9   r:   r;   r=   r>   r?   r@   rA   )r3   requiredr   c                 C  s
   t |S rG   )r   select_package_class)r   r3   rP   rP   rQ   metadata_select_classy  rU   zPackage.metadata_select_classc                 C  s   |dkrt S d S )NrA   r   )r   r2   rP   rP   rQ   metadata_select_property_class}  s   z&Package.metadata_select_property_classc                   s\   t  | |dd  |dd }t|tr(|r*t|d tr,|d |d< d S d S d S d S )Nz$frictionlessprofilesr   r7   )rI   metadata_transformpoprd   listre   )r   rz   r   rN   rP   rQ   r     s   zPackage.metadata_transformc                 #  s   t t |}|r|E d H  d S tjsLdg}|D ]1}||}t|t r(|n|g}|D ]}|rJt|trJt	|sJt
jd| ddV    d S q-qg }|d D ]}	t|	trdd|	v rd||	d  qRt|tt|krxd}
t
j|
dV  |d}|rtjdd	}||\}}
|
rd
}
t
j|
dV  |dg D ]}|ds|dsd| }
t
j|
dV  qdD ]0}||g D ]'}|drtjddd}||d\}}
|
rd| d}
t
j|
dV  qq|d}|r|dvr|dkrd}tj||| jdE d H  |dg }|dkr+|D ]}	|	dd dkr)d}
t
j|
dV  qdD ]}||v rDd| d| d}
t
j|
dV  q-d S )Nr7   zpath "z" is not safero   rA   r2   z%names of the resources are not uniquer@   rY   z*property "created" is not valid "datetime"r9   ra   z#license requires "path" or "name": )r;   r:   r   )r2   formatz
property "z[].email" is not valid "email")zdata-packagetabular-data-packagezfiscal-data-packagezBhttps://specs.frictionlessdata.io/schemas/fiscal-data-package.json)r7   error_classr   ztabular-data-resourcezWprofile "tabular-data-package" requires all the resources to be "tabular-data-resource")missingValuesr   "z$" should be set as "resource.schema.)r   rI   metadata_validater   trustedr   rd   re   r   is_safe_pathr   rq   dictrg   r   r   r   DatetimeField	read_cellStringFieldr   metadata_Error)r   rz   metadata_errorskeyskeyrT   r   r   r_   rM   rp   r@   field_r2   r7   rA   rN   rP   rQ   r     s   





	

zPackage.metadata_validatec                   s   t  jd|dd|S )NT)rz   with_basepathrP   )rI   metadata_import)r   rz   r   rN   rP   rQ   r    s   zPackage.metadata_importc                   s   t   }|S rG   )rI   metadata_export)rL   rz   rN   rP   rQ   r    s   
zPackage.metadata_export)rR   r0   )rT   r0   )rR   r<   )rM   rc   rR   r   )r2   re   rR   ri   )r2   re   rR   r   )r2   re   rR   r$   )rM   r   rR   rv   )r2   re   rz   r{   rR   r   )r   ri   rR   r   rG   )r   r   r-   r,   rR   r%   )r   r<   )r   ri   )r+   r*   r   ri   r   r   )
r2   r0   r   r   r   r   r   r   rR   r   )r   re   r2   r0   r   ri   r   r   r   r   r   ri   r   r0   rR   r<   )rL   r(   r   r#   )rL   r(   r   r   r2   r0   r   ri   r   r   r   r   )r   r   rR   r   )ra   r0   rR   re   )r3   r0   )r2   re   )rz   r{   )rz   r{   r   r   )I__name__
__module____qualname____doc__attrsr  r+   __annotations__r-   r1   r2   r3   r4   r5   r6   r7   r   r9   r:   r;   r=   r>   r?   r@   rA   rB   rD   rF   rJ   propertyr.   setterr_   rb   rh   rk   rm   rt   ru   ry   r   r   r   r   r   r   r   r   r   classmethodr   r   rw   r   r   DEFAULT_LIMIT_ERRORSr   r   r   metadata_typer   rq   r   NAME_PATTERNTYPE_PATTERNmetadata_profiler   r   r   r   r  r  __classcell__rP   rP   rN   rQ   r(      s4  
 	








!
H	

;Nr(   )	metaclassr   r{   rR   c                 C  s8   | d }| d }t jdi |}|jdi |}| S )NrM   r   rP   )r   rf   r   r|   )r   resource_optionsvalidate_optionsrM   r   rP   rP   rQ   r     s
   r   )r   r{   rR   r{   )7
__future__r   multiprocessingr   typingr   r   r   r   r   r	   r
   r  typing_extensionsr    r   r   r   r   r   r   r   r   r   r   r   r   r   rM   r   r   r   r   r8   r   r   catalogr   rE   r   rC   r   r    indexerr!   r"   r   r#   rA   r$   r%   definer(   r   rP   rP   rP   rQ   <module>   s@    $     V