o
    xi                    @  s
  U d Z ddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
Z
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mZmZ ddlmZ ddlmZ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'm(Z(m)Z)m*Z* ddl+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1Z1ddl1m2Z2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z>m?Z?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZF ddlGmHZH ddlImJZJmKZKmLZL ddlMmNZO ddlPmQZQ ddlRmSZS ddlTm*ZU ddlTmVZV ddlWmXZXmYZY dd lZm[Z[ dd!l\m]Z]m^Z^ dd"l_m`Z`maZambZb dd#lcmdZdmeZemfZfmgZg dd$lhmiZimjZj dd%lkmlZl dd&lmmnZnmoZompZpmqZqmrZrmsZs d'd(ltmuZu d'd)lvmwZwmxZxmyZy d'd*lzm{Z{m|Z| d'd+l}m~Z~ d'd,lmZmZ d'd-lmZ d'd.lmZ d'd/lmZ d'd0lmZ d'd1lmZ d'd2lmZmZmZmZ d'd3lmZ d'd4lmZ d'd5lmZ d'd6lmZ es Zdd7lmZ e  e%rdd8lmZ dd9l=mZ d'd:lmZmZ d'd;lmZ d'd<lzmZmZ eeZd=Zd>ed?< G d@dA dAZG dBdC dCeUZeVe dS )DzArtifact class.    )annotationsN)deque)IteratorSequence)ExecutorThreadPoolExecutoras_completed)copy)asdictreplace)	timedelta)filterfalse)PathPurePosixPath)IOTYPE_CHECKINGAnyCallableFinalLiteralType)quoteurljoinurlparse)NonNegativeInt)
data_typesenv)oneunique_list)	from_json)nameof)normalize_exceptions)ArtifactCollectionArtifactFilesRun)
gql_compat)WBValue)	CommError)UnsupportedError)	termerrortermlogtermwarn)wandb_internal_pb2)
Deprecated)wandb_setup)r   )TypeRegistry)retry	telemetry)warn_and_record_deprecation)check_existssystem_preferred_path)B64MD5b64_to_hex_idmd5_file_b64)FilePathStrLogicalPathStrPathURIStr)generate_fast_idgenerate_id)MailboxHandle)alias_is_version_indexartifact_to_json
fsync_openjson_dumps_saferuri_from_pathvendor_setup   )make_storage_policy)org_info_from_entityresolve_org_entity_nameserver_supports)ensure_loggedensure_not_finalized)ArtifactDownloadLogger)artifact_instance_cache$artifact_instance_cache_by_client_id)ArtifactManifest)ArtifactManifestEntry)ArtifactManifestV1)ArtifactState)ArtifactTTL)ArtifactNotLoggedErrorTooFewItemsErrorTooManyItemsErrorWaitTimeoutError)get_staging_dir)_GCSIsADirectoryError)make_http_session)should_multipart_download)gql)Iterable)RetryingClient)ArtifactFragmentArtifactMembershipFragmentFileWithUrlConnection)FullArtifactPathLinkArtifactFieldsi   z
Final[int]_MBc                   @  sn  e Zd ZdZedZeej	 					d8d9ddZ
d:ddZed;ddZed<ddZedd d=d"d#Zed>d'd(Zedd)d?d-d.Zddd/d@d2d3ZedAd4d5ZedBd6d7Zeed:d8d9Zeed:d:d;Zed:d<d=Zed:d>d?Zeed:d@dAZeedCdCdDZeed:dEdFZeed:dGdHZed:dIdJZed:dKdLZ eed:dMdNZ!eedCdOdPZ"edDdQdRZ#eedEdTdUZ$eedAdVdWZ%ed:dXdYZ&eed:dZd[Z'dFd]d^Z(dFd_d`Z)dFdadbZ*edBdcddZ+e+j,dGdeddZ+edHdgdhZ-e-j,dIdidhZ-edJdkdlZ.e.j,dKdodlZ.eedLdqdrZ/e/j,edMdtdrZ/eedLdudvZ0e0j,edNdxdvZ0edBdydzZ1e1j,dOd|dzZ1edDd}d~Z2edBddZ3ed:ddZ4edPddZ5dPddZ6ed:ddZ7edQddZ8eed:ddZ9eedQddZ:eed:ddZ;eed:ddZ<eedRddZ=dSddZ>dDddZ?dDddZ@		dTdUddZAdVddZBdWdXddZCdYddZDeEdSddZFdZddZGdZddZHd[ddZId\ddZJeKjLeM	d]d^ddZNeM					d_d`ddʄZOeM				dadbdd̈́ZPeM			dcddddքZQeM	dedfddڄZR				dadgddބZSeMdhddZTdiddZUediddZVed[ddZWdjddZXdkddZYe					dldmddZZ			dndoddZ[				dpdqddZ\drddZ]	dsdtdd Z^edWduddZ_edWdvddZ`edWdwddZae	dxdyddZbdzd{ddZcd|ddZdd}ddZeeded~ddZfeEded~ddZgeEdWdddZhedSdd ZieEdSd!d"Zjedd$d%Zkedd'd(Zledd*d+Zmendd.d/ZodRd0d1ZpdEd2d3Zqdd6d7ZrdS (  Artifacta  Flexible and lightweight building block for dataset and model versioning.

    Construct an empty W&B Artifact. Populate an artifacts contents with methods that
    begin with `add`. Once the artifact has all the desired files, you can call
    `run.log_artifact()` to log it.

    Args:
        name (str): A human-readable name for the artifact. Use the name to identify
            a specific artifact in the W&B App UI or programmatically. You can
            interactively reference an artifact with the `use_artifact` Public API.
            A name can contain letters, numbers, underscores, hyphens, and dots.
            The name must be unique across a project.
        type (str): The artifact's type. Use the type of an artifact to both organize
            and differentiate artifacts. You can use any string that contains letters,
            numbers, underscores, hyphens, and dots. Common types include `dataset` or
            `model`. Include `model` within your type string if you want to link the
            artifact to the W&B Model Registry.
            Note that some types reserved for internal use and cannot be set by users.
            Such types include `job` and types that start with `wandb-`.
        description (str | None) = None: A description of the artifact. For Model or
            Dataset Artifacts, add documentation for your standardized team model or
            dataset card. View an artifact's description programmatically with the
            `Artifact.description` attribute or programmatically with the W&B App UI.
            W&B renders the description as markdown in the W&B App.
        metadata (dict[str, Any] | None) = None: Additional information about an artifact.
            Specify metadata as a dictionary of key-value pairs. You can specify no more
            than 100 total keys.
        incremental: Use `Artifact.new_draft()` method instead to modify an
            existing artifact.
        use_as: Deprecated.

    Returns:
        An `Artifact` object.
    zwandb-artifactsNFnamestrtypedescription
str | Nonemetadatadict[str, Any] | Noneincrementalbooluse_asstorage_regionreturnNonec                 C  s  ddl m} ddlm}	m}
m} td|std||r(t	| |s(t
d d | _d | _i | _i | _d | _t | _d | _d | _td| _td| _d | _d | _|	|| _d | _d | _d | _|| _d | _d | _d	| _ |
||| _!|| _"||| _#d | _$d
| _%d	| _&g | _'g | _(g | _)g | _*d | _+|| _,|d urt-t.d
ddd d | _/t0j1| _2d | _3d | _4t5t6|dd| _7d | _8d | _9d | _:d | _;d	| _<d | _=g | _>d | _?| t@| j< d S )Nr   )InternalArtifactrE   )validate_artifact_namevalidate_artifact_typevalidate_metadataz^[a-zA-Z0-9_\-.]+$zeArtifact name may only contain alphanumeric characters, dashes, underscores, and dots. Invalid name: z$Using experimental arg `incremental`   FT)artifact__init_use_aszW`use_as` argument is deprecated and does not affect the behaviour of `wandb.Artifact()`featuremessage)region)storage_policy)A&wandb.sdk.artifacts._internal_artifactrt   _validatorsru   rv   rw   rematch
ValueError
isinstancer+   _client_tmp_dir_added_objs_added_local_paths_save_handleset_download_roots_base_id_idr<   
_client_id_sequence_client_id_entity_project_name_version_source_entity_source_project_source_name_source_version_source_artifact_is_link_type_description	_metadata_ttl_duration_seconds_ttl_is_inherited_ttl_changed_aliases_saved_aliases_tags_saved_tags_distributed_id_incrementalr2   r-   _use_asrR   PENDING_state_size_digestrQ   rF   	_manifest_commit_hash_file_count_created_at_updated_at_final_history_step_linked_artifacts_fetch_file_urls_decoratedrN   )selfrg   ri   rj   rl   rn   rp   rq   rt   ru   rv   rw    r   P/home/ubuntu/.local/lib/python3.10/site-packages/wandb/sdk/artifacts/artifact.py__init__   s~   




zArtifact.__init__c                 C  s   d| j p| j dS )Nz
<Artifact >)idrg   r   r   r   r   __repr__   s   zArtifact.__repr__artifact_idclientr^   Artifact | Nonec                 C  s   ddl m}m} ddlm} t| }r|S t|}|j|d|id}|	|}	|	j
 }
d u r2d S |
j}|j}|r>|jjnd}|rE|jnd}|j d|
j }||||d}| ||
|S )	NrE   ARTIFACT_BY_ID_GQLArtifactByIDrc   r   variable_values :vprefixprojectrg   )
_generatedr   r   r   rc   rM   getr\   executemodel_validateartifactartifact_sequencer   entityrg   version_index_from_attrs)clsr   r   r   r   rc   cached_artifactgql_opdataresultr   src_collectionsrc_projectentity_nameproject_namerg   pathr   r   r   _from_id   s    
zArtifact._from_idr   rc   c                C  s   ddl m}m} t|tjstdt|}|j|j	|j
d}|j||d}||}|j	 }	s>d|j	d|j}
t|
|	j }sY|j d|j	 }d	|j
d
|}
t|
| j|||dS )NrE   )ARTIFACT_MEMBERSHIP_BY_NAME_GQLArtifactMembershipByNamezQuerying for the artifact collection membership is not supported by this version of wandb server. Consider updating to the latest version.r   r   rg   r   project z not found under entity /zartifact membership  not found in targetr   )r   r   r   rI   pb&PROJECT_ARTIFACT_COLLECTION_MEMBERSHIPr(   r\   r   r   rg   r   r   r   artifact_collection_membership_from_membership)r   r   r   r   r   r   gql_varsr   r   r   msg
membershipentity_projectr   r   r   _membership_from_name  s"   


zArtifact._membership_from_name)enable_trackingr   c                C  s   ddl m}m} t|tjr| j||dS |j|j|j	|d}t
|}|j||d}||}	|	j }
sBd|jd|j}t||
j }s]|j d|j }d	|j	d
|}t|| |||S )NrE   )ARTIFACT_BY_NAME_GQLArtifactByNamer   r   )r   r   rg   enableTrackingr   r   z not found in entity r   z	artifact r   )r   r   r   rI   r   r   r   r   r   rg   r\   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   
_from_name:  s&   


zArtifact._from_namer   r`   r   c           
   	   C  s   ddl m} |j }r|j }r|j }std||jr3|jdkr3td|d|j d| d t||j	j|jd	}|j
 }	sLtd
| d| j||	||dS )NrE   is_artifact_registry_projectz7Missing artifact collection project in GraphQL responsemodel-registryzzThis model registry has been migrated and will be discontinued. Your request was redirected to the corresponding artifact z\ in the new registry. Please update your paths to point to the migrated registry directly, 'r   z'.)r   r   	Artifact z not found in responser   )r   r   artifact_collectionrg   r   r   wandbr+   r   r   r   to_strr   )
r   r   r   r   r   
collectionrg   proj
new_targetr   r   r   r   r   \  s.   

	
zArtifact._from_membershipr   src_artr_   !ArtifactMembershipFragment | Nonec                C  s\   | ddd}||_ |j|_|j|_|j|_|j||d |  |j	d us'J |t
|j	< |S )Nplaceholder)ri   r   )r   r   r   r   r   rg   r   _assign_attrsfinalizer   rM   )r   r   r   r   r   r   r   r   r   r     s   
zArtifact._from_attrs)r   is_linkr  bool | Nonec                  s  ddl m}m} |j| _|j}|j}|r|jjnd| _	|r |jnd| _
|j d|j | _d|j | _| jp9| j	| _| jp@| j
| _| jpG| j| _|du rk| j| j	kph| j| j
kph| jdd | jdd k| _n|| _|jj| _|j| _|rd	d
 |jD }n"|jr| j| j| jdd  fdd
|jD }ng }ttt|}	ttt|}
z	t|	ttd}W n3 ty   |r|j }durd| }nd|j }Y n ty   dt|	 d|	}t |dw || _!d| jv r| jn| j d| | _t"|
| _#t"|
| _$dd
 |j%D | _&t"| j&| _'||j(| _)||j*| _+|j,| _-t.|j/| _0|j1| _2|j3| _4d| _5|j6| _7|j8| _9|j:| _;|j<| _=|j>| _?dS )z<Update this Artifact's attributes using the server response.rE   )rw   validate_ttl_duration_secondsr   r   vN:r   c                 S     g | ]}|j qS r   alias.0ar   r   r   
<listcomp>      z*Artifact._assign_attrs.<locals>.<listcomp>c                   sF   g | ]}|j   r! j r!jjkr!jkr! jkr|jqS r   )r   r   r   rg   r  r  
alias_coll
alias_projr   r   r   r   r   r    s    

)	too_shorttoo_longz(Expected at most one version alias, got : c                 S  r
  r   rg   )r  tagr   r   r   r    r  )@r   rw   r  r   r   r   r   r   rg   r   r   r   r   r   r   r   r   splitr   artifact_typer   rj   r   aliaseslistfilterr?   r   r   rU   rV   lenr   r   r	   r   r   tagsr   r   rl   r   ttl_duration_secondsr   ttl_is_inheritedr   rR   stater   sizer   digestr   r   commit_hashr   
file_countr   
created_atr   
updated_atr   history_stepr   )r   r   r   r  rw   r  r   r   r  version_aliasesother_aliasesversionm_version_indexr   r   r  r   r    s   	



"

zArtifact._assign_attrsc                 C  sn   t | jdd | j}| j|_| j|_| j|_| j|_| j|_	| j
|_
| j|_| j|_t| j |_|S )a  Create a new draft artifact with the same content as this committed artifact.

        Modifying an existing artifact creates a new artifact version known
        as an "incremental artifact". The artifact returned can be extended or
        modified and logged as a new version.

        Returns:
            An `Artifact` object.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        r	  r   )rf   source_namer  ri   r   r   r   r   r   r   r   rj   r   rl   r   rO   from_manifest_jsonmanifestto_manifest_jsonr   )r   r   r   r   r   	new_draft  s   zArtifact.new_draftc                 C  s    |   rdS | jdusJ | jS )zThe artifact's ID.N)is_draftr   r   r   r   r   r   +  s   zArtifact.idc                 C     | j dusJ | j S )zThe name of the entity that the artifact collection belongs to.

        If the artifact is a link, the entity will be the entity of the linked artifact.
        N)r   r   r   r   r   r   3     zArtifact.entityc                 C  r5  )zThe name of the project that the artifact collection belongs to.

        If the artifact is a link, the project will be the project of the linked artifact.
        N)r   r   r   r   r   r   =  r6  zArtifact.projectc                 C     | j S )a  The artifact name and version of the artifact.

        A string with the format `{collection}:{alias}`. If fetched before an artifact is
        logged/saved, the name won't contain the alias.
        If the artifact is a link, the name will be the name of the linked artifact.
        )r   r   r   r   r   rg   G  s   zArtifact.namec                 C     | j  d| j d| j S )zThe entity/project/name of the artifact.

        If the artifact is a link, the qualified name will be the qualified name of the
        linked artifact path.
        r   r   r   r   r   r   qualified_nameQ  s   zArtifact.qualified_namec                 C  r5  )zThe artifact's version.

        A string with the format `v{number}`.
        If this is a link artifact, the version will be from the linked collection.
        N)r   r   r   r   r   r-  Z  s   zArtifact.versionr"   c                 C  <   | j  }du rtd| jdd }t|| j| j|| jS )a  The collection this artifact is retrieved from.

        A collection is an ordered group of artifact versions.
        If this artifact is retrieved from a collection that it is linked to,
        return that collection. Otherwise, return the collection
        that the artifact version originates from.

        The collection that an artifact originates from is known as
        the source sequence.
        NClient not initializedr	  r   )r   RuntimeErrorrg   r  r"   r   r   ri   r   r   	base_namer   r   r   r   e  s   zArtifact.collectionc                 C  r5  )z.The name of the entity of the source artifact.N)r   r   r   r   r   source_entityy     zArtifact.source_entityc                 C  r5  )z/The name of the project of the source artifact.N)r   r   r   r   r   source_project  r@  zArtifact.source_projectc                 C  r7  )zThe artifact name and version of the source artifact.

        A string with the format `{source_collection}:{alias}`. Before the artifact
        is saved, contains only the name since the version is not yet known.
        )r   r   r   r   r   r/       zArtifact.source_namec                 C  r8  )zDThe source_entity/source_project/source_name of the source artifact.r   )r?  rA  r/  r   r   r   r   source_qualified_name  s   zArtifact.source_qualified_namec                 C  r5  )zVThe source artifact's version.

        A string with the format `v{number}`.
        N)r   r   r   r   r   source_version  r6  zArtifact.source_versionc                 C  r:  )z~The artifact's source collection.

        The source collection is the collection that the artifact was logged from.
        Nr;  r	  r   )r   r<  r/  r  r"   r?  rA  ri   r=  r   r   r   source_collection  s   zArtifact.source_collectionc                 C  r7  )zBoolean flag indicating if the artifact is a link artifact.

        True: The artifact is a link artifact to a source artifact.
        False: The artifact is a source artifact.
        )r   r   r   r   r   r    rB  zArtifact.is_linklist[Artifact]c                 C  s   | j s|  | _| jS )zReturns a list of all the linked artifacts of a source artifact.

        If this artifact is a link artifact (`artifact.is_link == True`),
        it will return an empty list.

        Limited to 500 results.
        )r  _fetch_linked_artifactsr   r   r   r   r   linked_artifacts  s   

zArtifact.linked_artifactsc              
   C  s   ddl m} | js| S | jdu rG| j }du rtdz|| j| j| jd}| j	||d| _W | jS  t
yF } z	td| j |d}~ww | jS )zReturns the source artifact, which is the original logged artifact.

        If this artifact is a source artifact (`artifact.is_link == False`),
        it will return itself.
        rE   r   NClient is not initializedr   r   z4Unable to fetch source artifact for linked artifact )r   rc   r  r   r   r   r?  rA  r/  r   	Exceptionrg   )r   rc   r   r   er   r   r   source_artifact  s.   

zArtifact.source_artifactc                 C  r7  )z?The artifact's type. Common types include `dataset` or `model`.)r   r   r   r   r   ri        zArtifact.typec                 C  sz   ddl m} z| jj}W n
 ty   Y dS w | js| |S || jr)| |S | j	dks3| jdkr8| 
|S | |S )zq
        Constructs the URL of the artifact.

        Returns:
            str: The URL of the artifact.
        rE   r   r   modelr   )r   r   r   app_urlAttributeErrorr  _construct_standard_urlr   _construct_registry_urlr   _construct_model_registry_url)r   r   base_urlr   r   r   url  s   	




zArtifact.urlrT  c                 C  s^   t || j| j| j| jj| jgsdS t|| j d| j dt| j dt| jj d| j 	S )Nr   r   z/artifacts/)	allr   r   r   r   rg   r   r   r   )r   rT  r   r   r   rQ    s   
2z Artifact._construct_standard_urlc              
   C  s   ddl m} t|| j| j| jj| jgsdS zt| j	| jj
j}W n ttfy-   Y dS w t| j d| j d| jj dd}t|d| d|| j d| d	| j S )
NrE   )remove_registry_prefixr   r   safezorgs/z
/registry/z?selectionPath=&view=membership&version=)r   rW  rV  r   r   r   rg   r   rG   r   organizationrP  r   r   r   r-  )r   rT  rW  org_nameselection_pathr   r   r   rR    s,   	"z Artifact._construct_registry_urlc                 C  sb   t || j| j| jj| jgsdS t| j d| j d| jj dd}t|| j d| d| j S )Nr   r   rX  z/registry/model?selectionPath=rZ  )rV  r   r   r   rg   r   r   r   )r   rT  r]  r   r   r   rS  *  s    	z&Artifact._construct_model_registry_urlc                 C  r7  )zA description of the artifact.)r   r   r   r   r   rj   =  rM  zArtifact.descriptionc                 C  s   | j rtd || _dS )a  Set the description of the artifact.

        For model or dataset Artifacts, add documentation for your
        standardized team model or dataset card. In the W&B UI the
        description is rendered as markdown.

        Editing the description will apply the changes to the source artifact
        and all linked artifacts associated with it.

        Args:
            description: Free text that offers a description of the artifact.
        zEditing the description of this linked artifact will edit the description for the source artifact and it's linked artifacts as well.N)r  r   r+   r   )r   rj   r   r   r   rj   B  s
   
dictc                 C  r7  )z_User-defined artifact metadata.

        Structured data associated with the artifact.
        )r   r   r   r   r   rl   V     zArtifact.metadatac                 C  *   ddl m} | jrtd ||| _dS )a  User-defined artifact metadata.

        Metadata set this way will eventually be queryable and plottable in the UI; e.g.
        the class distribution of a dataset.

        Note: There is currently a limit of 100 total keys.
        Editing the metadata will apply the changes to the source artifact
        and all linked artifacts associated with it.

        Args:
            metadata: Structured data associated with the artifact.
        rE   )rw   z~Editing the metadata of this linked artifact will edit the metadata for the source artifact and it's linked artifacts as well.N)r   rw   r  r   r+   r   )r   rl   rw   r   r   r   rl   ^  s   timedelta | Nonec                 C  sF   | j r|  s
| jrttt|  d| | jdu rdS t| jdS )aW  The time-to-live (TTL) policy of an artifact.

        Artifacts are deleted shortly after a TTL policy's duration passes.
        If set to `None`, the artifact deactivates TTL policies and will be not
        scheduled for deletion, even if there is a team default TTL.
        An artifact inherits a TTL policy from
        the team default if the team administrator defines a default
        TTL and there is no custom policy set on an artifact.

        Raises:
            ArtifactNotLoggedError: Unable to fetch inherited TTL if the
            artifact has not been logged or saved.
        z.ttlN)seconds)r   r4  r   rT   r    ri   r   r   r   r   r   r   ttlt  s
   
zArtifact.ttlrc  timedelta | ArtifactTTL | Nonec                 C  s   | j dkr	td| jrtdd| _t|tr)|tjkr"d| _dS td| d| _|du r5d| _dS |	 dkrDtd	|	  t
|	 | _dS )
aE  The time-to-live (TTL) policy of an artifact.

        Artifacts are deleted shortly after a TTL policy's duration passes.
        If set to `None`, the artifact has no TTL policy set and it is not
        scheduled for deletion. An artifact inherits a TTL policy from
        the team default if the team administrator defines a default
        TTL and there is no custom policy set on an artifact.

        Args:
            ttl: The duration as a positive `datetime.timedelta` that represents
                how long the artifact will remain active from its creation.

        zwandb-historyz.Cannot set artifact TTL for type wandb-historyzdCannot set TTL for link artifact. Unlink the artifact first then set the TTL for the source artifactTzUnhandled ArtifactTTL enum FNr   z/Artifact TTL Duration has to be positive. ttl: )ri   r   r  r   r   rS   INHERITr   r   total_secondsint)r   rc  r   r   r   rc    s&   




	list[str]c                 C  r7  )a  List of one or more semantically-friendly references or

        identifying "nicknames" assigned to an artifact version.

        Aliases are mutable references that you can programmatically reference.
        Change an artifact's alias with the W&B App UI or programmatically.
        See [Create new artifact versions](https://docs.wandb.ai/guides/artifacts/create-a-new-artifact-version)
        for more information.
        )r   r   r   r   r   r    s   zArtifact.aliasesr  c                 C  s   ddl m} ||| _dS )z.Set the aliases associated with this artifact.rE   )validate_aliasesN)r   ri  r   )r   r  ri  r   r   r   r    s   c                 C  r7  )z;List of one or more tags assigned to this artifact version.)r   r   r   r   r   r     s   zArtifact.tagsr   c                 C  r`  )zSet the tags associated with this artifact.

        Editing tags will apply the changes to the source artifact
        and all linked artifacts associated with it.
        rE   )validate_tagszgEditing tags will apply the changes to the source artifact and all linked artifacts associated with it.N)r   rj  r  r   r+   r   )r   r   rj  r   r   r   r     s   c                 C  r7  )zWThe distributed ID of the artifact.

        <!-- lazydoc-ignore: internal -->
        r   r   r   r   r   distributed_id  r_  zArtifact.distributed_idrl  c                 C  s
   || _ d S Nrk  )r   rl  r   r   r   rl    s   
c                 C  r7  )zwBoolean flag indicating if the artifact is an incremental artifact.

        <!-- lazydoc-ignore: internal -->
        )r   r   r   r   r   rn     r_  zArtifact.incrementalc                 C  s   t tdddd | jS )zDeprecated.T)artifact__use_asz.The use_as property of Artifact is deprecated.rz   )r2   r-   r   r   r   r   r   rp     s
   zArtifact.use_asc                 C  s   | j jS )zIThe status of the artifact. One of: "PENDING", "COMMITTED", or "DELETED".)r   valuer   r   r   r   r#    s   zArtifact.staterO   c                 C  s   | j du r
|  | _ | j S )zThe artifact's manifest.

        The manifest lists all of its contents, and can't be changed once the artifact
        has been logged.
        N)r   _fetch_manifestr   r   r   r   r1     s   

zArtifact.manifestc                 C  s   ddl m}m} | j }du rtdt|}d| ji}|j||d}||}|j	 }rT|j
 }	rTt }
|
|	jj}W d   n1 sGw   Y  tt|jS td)z1Fetch, parse, and load the full ArtifactManifest.rE   )FETCH_ARTIFACT_MANIFEST_GQLFetchArtifactManifestN+Client not initialized for artifact queriesr   r   z!Failed to fetch artifact manifest)r   rq  rr  r   r<  r\   r   r   r   r   current_manifestrZ   r   file
direct_urlrO   r0  r   contentr   )r   rq  rr  r   r   r   r   r   r   r1  sessionresponser   r   r   rp    s   

zArtifact._fetch_manifestc                 C  $   | j du r| jdur| jS | j S )zThe logical digest of the artifact.

        The digest is the checksum of the artifact's contents. If an artifact has the
        same digest as the current `latest` version, then `log_artifact` is a no-op.
        N)r   r   r1  r%  r   r   r   r   r%  -  s
   zArtifact.digestrg  c                 C  rz  )zlThe total size of the artifact in bytes.

        Includes any references tracked by this artifact.
        N)r   r   r1  r$  r   r   r   r   r$  >  s
   zArtifact.sizec                 C  r5  )z3The hash returned when this artifact was committed.N)r   r   r   r   r   r&  Q  r@  zArtifact.commit_hashc                 C  r5  )z+The number of files (including references).N)r   r   r   r   r   r'  X  r@  zArtifact.file_countc                 C  r5  )z(Timestamp when the artifact was created.N)r   r   r   r   r   r(  _  r@  zArtifact.created_atc                 C  s   | j dusJ | jp| j S )z,The time when the artifact was last updated.N)r   r   r   r   r   r   r)  f  s   zArtifact.updated_at
int | Nonec                 C  s   | j du rdS td| j d S )a  The nearest step which logged history metrics for this artifact's source run.

        Examples:
        ```python
        run = artifact.logged_by()
        if run and (artifact.history_step is not None):
            history = run.sample_history(
                min_step=artifact.history_step,
                max_step=artifact.history_step + 1,
                keys=["my_metric"],
            )
        ```
        Nr   rE   )r   maxr   r   r   r   r*  m  s   
zArtifact.history_stepc                 C  s
   d| _ dS )aW  Finalize the artifact version.

        You cannot modify an artifact version once it is finalized because the artifact
        is logged as a specific artifact version. Create a new artifact version
        to log more data to an artifact. An artifact is automatically finalized
        when you log the artifact with `log_artifact`.
        TN)r   r   r   r   r   r    s   
zArtifact.finalizec                 C  s   | j tju S )zCheck if artifact is not saved.

        Returns:
            Boolean. `False` if artifact is saved. `True` if artifact is not saved.
        )r   rR   r   r   r   r   r   r4    s   zArtifact.is_draftc                 C  s
   | j d uS rm  )r   r   r   r   r   _is_draft_save_started  s   
zArtifact._is_draft_save_startedr   settingswandb.Settings | Nonec              	   C  s   | j tjur
|  S | jr%t }d|j_W d   n1 s w   Y  t	
 j }r3||  dS |du r=tjdd}tj| j|pE| jd|d+}| jrhtj|d}d|j_W d   n1 scw   Y  ||  W d   dS 1 sxw   Y  dS )a  Persist any changes made to the artifact.

        If currently in a run, that run will log this artifact. If not currently in a
        run, a run of type "auto" is created to track this artifact.

        Args:
            project: A project to use for the artifact in the case that a run is not
                already in context.
            settings: A settings object to use when initializing an automatic run. Most
                commonly used in testing harness.
        TNtrue)silentauto)r   r   job_typer~  )run)r   rR   r   _updater   r1   contextr{   artifact_incrementalr.   	singletonmost_recent_active_runlog_artifactr   Settingsinitr   r   )r   r   r~  telr  r   r   r   save  s.   


"zArtifact.savesave_handleMailboxHandle[pb.Result]c                 C  s   || _ || _d S rm  )r   r   )r   r  r   r   r   r   _set_save_handle  s   
zArtifact._set_save_handletimeoutc              
   C  s   |   r>| jdu rtt| j| z	| jj|d}W n ty+ } ztd|d}~ww |jj	}|j
r8t|j
| |j | S )zIf needed, wait for this artifact to finish logging.

        Args:
            timeout: The time, in seconds, to wait.

        Returns:
            An `Artifact` object.
        Nr  zAArtifact upload wait timed out, failed to fetch Artifact response)r4  r   rT   r    waitwait_orTimeoutErrorrW   ry  log_artifact_responseerror_messager   _populate_after_saver   )r   r  r   rK  ry  r   r   r   r    s$   	

zArtifact.waitc           	      C  st   ddl m}m} | j }d u rtdt|}|j|d|id}||}|j }s1t	d|| j
|dd d S )	NrE   r   rs  r   r   z"Unable to fetch artifact with id: F)r  )r   r   r   r   r<  r\   r   r   r   r   r  )	r   r   r   r   r   r   r   r   r   r   r   r   r    s   

zArtifact._populate_after_savec              
   C  sb  ddl m}m}m} ddlm}m} | j }du rtd| j	| j
| jdd }}}	t| jt| j}
}||||	d}| j||
 |d	 | j|
| |d	 t| j| _t| jt| j}}t|}|| j| jt| j|  d
d ||| D dd ||| D d}d| i}|j||d}||j}|r|j }st d| !| d| _"dS )z/Persists artifact changes to the wandb backend.rE   )UPDATE_ARTIFACT_GQLUpdateArtifactUpdateArtifactInput)rc   rj  N-Client not initialized for artifact mutationsr	  r   r   r   c                 S     g | ]}d |iqS tagNamer   r  tr   r   r   r        z$Artifact._update.<locals>.<listcomp>c                 S  r  r  r   r  r   r   r   r    r  )r   rj   rl   r!  tags_to_addtags_to_deleteinputr   z'Unable to parse updateArtifact responseF)#r   r  r  r  r   rc   rj  r   r<  r   r   rg   r  r   r   r  _add_aliases_delete_aliasesr	   r   r   r\   r   rj   rB   rl   _ttl_duration_seconds_to_gql
model_dumpr   r   r   r   r   r  r   )r   r  r  r  rc   rj  r   r   r   r   old_aliasesnew_aliasesr   old_tagsnew_tagsr   	gql_inputr   r   r   r   r   r   r   r    s6    

zArtifact._updatealias_namesset[str]c              
        ddl m}m} | j }d u rtd|rd|j|j|jd  fdd|D }t|}|| j	|d}d|
 i}	z
|j||	d	 W d S  tyc }
 zd
t|dkrSdnd d|}t||
d }
~
ww d S )NrE   )ADD_ALIASES_GQLAddAliasesInputr  
entityNameprojectNameartifactCollectionNamec                      g | ]
}i  d |iqS r  r   r  rg   target_propsr   r   r  *      z)Artifact._add_aliases.<locals>.<listcomp>r   r  r  r   z"You do not have permission to add %at least one of the following aliasesthe following aliasz to this artifact: )r   r  r  r   r<  r   r   rg   r\   r   r  r   r'   r  )r   r  r   r  r  r   alias_inputsr   r  r   rK  r   r   r  r   r    2   
zArtifact._add_aliasesc              
     r  )NrE   )DELETE_ALIASES_GQLDeleteAliasesInputr  r  c                   r  r  r   r  r  r   r   r  E  r  z,Artifact._delete_aliases.<locals>.<listcomp>r  r  r   z%You do not have permission to delete r  r  z from this artifact: )r   r  r  r   r<  r   r   rg   r\   r   r  r   r'   r  )r   r  r   r  r  r   r  r   r  r   rK  r   r   r  r   r  8  r  zArtifact._delete_aliasesWBValue | Nonec                 C  s
   |  |S )a`  Get the WBValue object located at the artifact relative `name`.

        Args:
            name: The artifact relative name to get.

        Returns:
            W&B object that can be logged with `run.log()` and visualized in the W&B UI.

        Raises:
            ArtifactNotLoggedError: If the artifact isn't logged or the run is offline.
        )r   r   rg   r   r   r   __getitem__U  s   
zArtifact.__getitem__itemr&   rP   c                 C  s   |  ||S )a  Add `item` to the artifact at path `name`.

        Args:
            name: The path within the artifact to add the object.
            item: The object to add.

        Returns:
            The added manifest entry

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
            artifact version because it is finalized. Log a new artifact
            version instead.
        )add)r   rg   r  r   r   r   __setitem__c  s   zArtifact.__setitem__xmodeencodingIterator[IO]c              
   c  s    d|v}| j du rt | _ tj| j j|d}t|j	j
ddd zt|||}|V  W d   n1 s:w   Y  W n, tyQ   td|d| tyl } ztdtt| d	| d
  d}~ww | j||dd|d dS )ag  Open a new temporary file and add it to the artifact.

        Args:
            name: The name of the new file to add to the artifact.
            mode: The file access mode to use to open the new file.
            encoding: The encoding used to open the new file.

        Returns:
            A new file object that can be written to. Upon closing, the file
            is automatically added to the artifact.

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
            artifact version because it is finalized. Log a new artifact
            version instead.
        r  Nr   T)parentsexist_okzFile with name z already exists at z"Failed to open the provided file (r  z&). Please provide the proper encoding.	immutable)rg   policy
skip_cache	overwrite)r   tempfileTemporaryDirectoryosr   joinrg   lstripr   parentmkdirrA   FileExistsErrorr   UnicodeEncodeErrorr)   r    ri   add_file)r   rg   r  r  r  r   frK  r   r   r   new_filet  s.   



zArtifact.new_filemutable
local_pathis_tmpr  r  &Literal['mutable', 'immutable'] | Noner  c                 C  s   t j|std|t|pt j|}t|}|r>t j|\}}	|	d}
t|dd |
d< t j	|d	|
}| j
||||||dS )a  Add a local file to the artifact.

        Args:
            local_path: The path to the file being added.
            name: The path within the artifact to use for the file being added.
                Defaults to the basename of the file.
            is_tmp: If true, then the file is renamed deterministically to avoid
                collisions.
            skip_cache: If `True`, do not copy files to the cache
                after uploading.
            policy: By default, set to "mutable". If set to "mutable",
                create a temporary copy of the file to prevent corruption
                during upload. If set to "immutable", disable
                protection and rely on the user not to delete or change the
                file.
            overwrite: If `True`, overwrite the file if it already exists.

        Returns:
            The added manifest entry.

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
                artifact version because it is finalized. Log a new artifact
                version instead.
            ValueError: Policy must be "mutable" or "immutable"
        zPath is not a file: .N   r   )r%  r  r  r  )r  r   isfiler   r9   basenamer7   r  r6   r  _add_local_file)r   r  rg   r  r  r  r  r%  	file_path	file_namefile_name_partsr   r   r   r    s"   $
zArtifact.add_filemergec                   s  t j|std|tdtd| ddd t }t }|p$d}t j	|dd	D ]'\}	}
}|D ]}t j
|	|}t jj||d
}t j
||}|||f q3q,d fdd}d}tj|}||| |  |
  tdt |  dd dS )a  Add a local directory to the artifact.

        Args:
            local_path: The path of the local directory.
            name: The subdirectory name within an artifact. The name you
                specify appears in the W&B App UI nested by artifact's `type`.
                Defaults to the root of the artifact.
            skip_cache: If set to `True`, W&B will not copy/move files to
                the cache while uploading
            policy: By default, "mutable".
                - mutable: Create a temporary copy of the file to prevent
                    corruption during upload.
                - immutable: Disable protection, rely on the user not to delete
                    or change the file.
            merge: If `False` (default), throws ValueError if a file was already added
                in a previous add_dir call and its content has changed. If `True`,
                overwrites existing files with changed content. Always adds new files
                and never removes files. To replace an entire directory, pass a name
                when adding the directory using `add_dir(local_path, name=my_prefix)`
                and call `remove(my_prefix)` to remove the directory, then add it again.

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
                artifact version because it is finalized. Log a new artifact
                version instead.
            ValueError: Policy must be "mutable" or "immutable"
        zPath is not a directory: zAdding directory to artifact (r  z)... F)newliner   T)followlinksstartlogical_pthrh   physical_pthrr   rs   c                   s   j | | d d S )N)rg   r   r  r  r  )r  )r  r  r  r  r   r  r   r   add_manifest_file  s   
z+Artifact.add_dir.<locals>.add_manifest_file   zDone. %.1fsr   N)r  rh   r  rh   rr   rs   )r  r   isdirr   r*   r   time	monotonicr   walkr  relpathappendmultiprocessingdummyPoolstarmapclose)r   r  rg   r  r  r  
start_timepathslogical_rootdirpath_	filenamesfnamephysical_pathlogical_pathr  num_threadspoolr   r  r   add_dir  s.   $	zArtifact.add_dirTuriArtifactManifestEntry | strStrPath | Nonechecksummax_objectsSequence[ArtifactManifestEntry]c           	      C  s   |durt |}t|tr| }nt|tr|}tt|}|js&td| jj	j
| t||||d}|D ]}| j| q6|S )a[  Add a reference denoted by a URI to the artifact.

        Unlike files or directories that you add to an artifact, references are not
        uploaded to W&B. For more information,
        see [Track external files](https://docs.wandb.ai/guides/artifacts/track-external-files).

        By default, the following schemes are supported:

        - http(s): The size and digest of the file will be inferred by the
          `Content-Length` and the `ETag` response headers returned by the server.
        - s3: The checksum and size are pulled from the object metadata.
          If bucket versioning is enabled, then the version ID is also tracked.
        - gs: The checksum and size are pulled from the object metadata. If bucket
          versioning is enabled, then the version ID is also tracked.
        - https, domain matching `*.blob.core.windows.net`
        - Azure: The checksum and size are be pulled from the blob metadata.
          If storage account versioning is enabled, then the version ID is
          also tracked.
        - file: The checksum and size are pulled from the file system. This scheme
          is useful if you have an NFS share or other externally mounted volume
          containing files you wish to track but not necessarily upload.

        For any other scheme, the digest is just a hash of the URI and the size is left
        blank.

        Args:
            uri: The URI path of the reference to add. The URI path can be an object
                returned from `Artifact.get_entry` to store a reference to another
                artifact's entry.
            name: The path within the artifact to place the contents of this reference.
            checksum: Whether or not to checksum the resource(s) located at the
                reference URI. Checksumming is strongly recommended as it enables
                automatic integrity validation. Disabling checksumming will speed up
                artifact creation but reference directories will not iterated through so
                the objects in the directory will not be saved to the artifact.
                We recommend setting `checksum=False` when adding reference objects,
                in which case a new version will only be created if the reference URI
                changes.
            max_objects: The maximum number of objects to consider when adding a
                reference that points to directory or bucket store prefix.
                By default, the maximum number of objects allowed for Amazon S3,
                GCS, Azure, and local files is 10,000,000. Other URI schemas
                do not have a maximum.

        Returns:
            The added manifest entries.

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
            artifact version because it is finalized. Log a new artifact
            version instead.
        Nz?References must be URIs. To reference a local file, use file://)rg   r  r  )r9   r   rP   ref_urlrh   r   schemer   r1  r~   store_referencer;   	add_entry)	r   r  rg   r  r  uri_strrU  manifest_entriesentryr   r   r   add_reference   s*   <


zArtifact.add_referenceobjr:   c                 C  s.  t |}|d}tjtjtjtjtjtjtj	tj
tjtjtjtjtjtjf}t||s7td|j d| t|}|| jv rG| j| d S | }|dur\| |t||d S || }||}| j|}	|st|	durt|	S |rtj| j j!t"t| |}
tj#|
\}}tj$|dd t%|
d	d
d}t&j'||dd W d   n1 sw   Y  n)|rd	nd}| j(||d
d}t&j'||dd |j!}
W d   n1 sw   Y  | )|
||}	||	f| j|< |j*du r|+| |	j |rt,-t. t/|
 W d   |	S 1 sw   Y  |	S )a  Add wandb.WBValue `obj` to the artifact.

        Args:
            obj: The object to add. Currently support one of Bokeh, JoinedTable,
                PartitionedTable, Table, Classes, ImageMask, BoundingBoxes2D,
                Audio, Image, Video, Html, Object3D
            name: The path within the artifact to add the object.
            overwrite: If True, overwrite existing objects with the same file
                path if applicable.

        Returns:
            The added manifest entry

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
            artifact version because it is finalized. Log a new artifact
            version instead.
        zmedia/tableszFound object of type z, expected one of: rE   Nr   T)r  wzutf-8)r  )	sort_keysr  )r  r  )0r9   
startswithr   BokehJoinedTablePartitionedTableTableClasses	ImageMaskBoundingBoxes2DAudioImageVideoHtmlObject3DMolecule_SavedModelr   	TypeError	__class__r   r   _get_artifact_entry_ref_urlr  ri   with_suffixto_jsonr1  get_entry_by_pathr  r   r  _TMP_DIRrg   rh   r  makedirsopenjsondumpr  r  _artifact_target_set_artifact_target
contextlibsuppressFileNotFoundErrorremove)r   r  rg   r  is_tmp_nameallowed_typesobj_idref_pathvalr  r  folder_pathr  tmp_ffilemoder  r   r   r   r  w  st   







zArtifact.addr%  B64MD5 | Nonec                 C  s   |pd}|dvrt d|d|}|dkr@tjt dd}|j}	t||	 t|	t	j
 |	}W d    n1 s;w   Y  t||pGt|tj|||d}
| jj|
|d |
| jt|< |
S )	Nr  )r  r  zInvalid policy z.. Policy may only be `mutable` or `immutable`.F)dirdelete)r   r%  r$  r  r  )r  )r   r  NamedTemporaryFilerX   rg   shutilcopyfiler  chmodstatS_IRUSRrP   r7   r   getsizer1  r  r   fspath)r   rg   r   r%  r  r  r  upload_pathr  staging_pathr  r   r   r   r    s.   	


zArtifact._add_local_fileStrPath | ArtifactManifestEntryc                 C  sz   t |tr| j| dS tt|}| j| }r!| j|S | j|}|s0td| |D ]}| j| q2dS )a)  Remove an item from the artifact.

        Args:
            item: The item to remove. Can be a specific manifest entry
                or the name of an artifact-relative path. If the item
                matches a directory all items in that directory will be removed.

        Raises:
            ArtifactFinalizedError: You cannot make changes to the current
                artifact version because it is finalized. Log a new artifact
                version instead.
            FileNotFoundError: If the item isn't found in the artifact.
        NzNo such file or directory: )	r   rP   r1  remove_entryrh   r   r5  get_entries_in_directoryr?  )r   r  r   r  entriesr   r   r   r@    s   
zArtifact.removec                 C  s   t tdddd | |S )z"Deprecated. Use `get_entry(name)`.T)artifact__get_pathzLArtifact.get_path(name) is deprecated, use Artifact.get_entry(name) instead.rz   )r2   r-   	get_entryr  r   r   r   get_path  s
   
zArtifact.get_pathc                 C  sD   t |}| jj|p| |d }|du rtd| | |_|S )aY  Get the entry with the given name.

        Args:
            name: The artifact relative name to get

        Returns:
            A `W&B` object.

        Raises:
            ArtifactNotLoggedError: if the artifact isn't logged or the run is offline.
            KeyError: if the artifact doesn't contain an entry with the given name.
        r   Nz Path not contained in artifact: )r9   r1  rY  r   _get_obj_entryKeyError_parent_artifact)r   rg   r  r   r   r   r[    s   zArtifact.get_entryc                 C  s   |  |\}}|du s|du rdS |  }r4| jdusJ | j|| jd}|dus,J |t|jS |tjkr=| 	  | 
|j}|	 }t|}t|}	W d   n1 s[w   Y  ||	| }
|
| | |
S )a  Get the WBValue object located at the artifact relative `name`.

        Args:
            name: The artifact relative name to retrieve.

        Returns:
            W&B object that can be logged with `run.log()` and
            visualized in the W&B UI.

        Raises:
            ArtifactNotLoggedError: if the artifact isn't logged or the
                run is offline.
        N)r   )r]  _referenced_artifact_idr   r   r   rC   refr   r%  downloadr[  r   r8  r9  loadr   _set_artifact_source)r   rg   r  wb_classreferenced_idr   r  	item_pathru  json_objr   r   r   r   r   3  s$   

zArtifact.getc                 C  s   | j | }r|jS dS )zGet the artifact relative name of a file added by a local filesystem path.

        Args:
            local_path: The local path to resolve into an artifact relative name.

        Returns:
            The artifact relative name.
        N)r   r   r   )r   r  r  r   r   r   get_added_local_path_nameb  s   	z"Artifact.get_added_local_path_name?tuple[ArtifactManifestEntry, Type[WBValue]] | tuple[None, None]c                 C  s>   t   D ]}||}| jj| }r||f  S qdS )a  Return an object entry by name, handling any type suffixes.

        When objects are added with `.add(obj, name)`, the name is typically changed to
        include the suffix of the object type when serializing to JSON. So we need to be
        able to resolve a name, without tasking the user with appending .THING.json.
        This method returns an entry if it exists by a suffixed name.

        Args:
            name: name used when adding
        NN)r&   type_mappingvaluesr3  r1  rY  r   )r   rg   re  wandb_file_namer  r   r   r   r]  o  s   
zArtifact._get_obj_entryrootallow_missing_referencespath_prefix	multipartr8   c                 C  s   |  |}| j|||||dS )aX  Download the contents of the artifact to the specified root directory.

        Existing files located within `root` are not modified. Explicitly delete `root`
        before you call `download` if you want the contents of `root` to exactly match
        the artifact.

        Args:
            root: The directory W&B stores the artifact's files.
            allow_missing_references: If set to `True`, any invalid reference paths
                will be ignored while downloading referenced files.
            skip_cache: If set to `True`, the artifact cache will be skipped when
                downloading and W&B will download each file into the default root or
                specified download directory.
            path_prefix: If specified, only files with a path that starts with the given
                prefix will be downloaded. Uses unix format (forward slashes).
            multipart: If set to `None` (default), the artifact will be downloaded
                in parallel using multipart download if individual file size is greater
                than 2GB. If set to `True` or `False`, the artifact will be downloaded in
                parallel or serially regardless of the file size.

        Returns:
            The path to the downloaded contents.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        )ro  rp  r  rq  rr  )_add_download_root	_download)r   ro  rp  r  rq  rr  r   r   r   rb    s   
#
zArtifact.downloadc                 C  s6  dd l }ddlm} tjd u r_t }t }|j	 }	|
t }
t|
|	j_t|
| d |	j_t|
d |	j_||	j_| }|j|	|d ||j|d}|  |jsZJ ||j_n
tjjseJ tjj}|jsnJ |j| j||||}| j||||d |jd d}|jj}|jrt d	|j t!|S )
Nr   )Backendz.wandbfiles)r~  run_id)r~  service)ro  rp  r  rq  r  zError downloading artifact: )"pathlibwandb.sdk.backend.backendru  r   r  r.   r  r=   r~  to_protor   r  mkdtemprh   sync_dirro  	sync_file	files_dirrw  ensure_serviceinform_initensure_launched	interface
_stream_id_backenddeliver_download_artifactr   rt  r  ry  download_artifact_responser  r   r8   )r   ro  rp  r  rq  ry  ru  wl	stream_idr~  tmp_dirrx  backendhandler   ry  r   r   r   _download_using_core  sL   




zArtifact._download_using_corec              
     s  t | jj}| jt }|dkp|dk }r)td| jd|dd|d t }	t	|dd# fdd}
t
dd{}t }t }d\}}|r| j||d}|jj}|jj}dd |jD }|D ]!}| |j}|j|_|r{|jt|r||j|
||d qet ||krt|D ]}|  || t ||kr nq|sLt|D ]}|  qW d    n1 sw   Y  |rtt |	 }t|d\}}t|d\}}tdt |ddt |dd|dd|| dd 	d!d" t!S )$N  2   zDownloading large artifact z, z.2fzMB. z	 files...)nfilesr  rP   executorr   rr   rs   c              
     s   t | jdr	|nd }z
| j|d W n\ ty2 } z r-tt| W Y d }~d S  d }~w tyK } zt	t| W Y d }~d S d }~w t
y^   td| jd Y d S  tyq   td| jd Y d S w   d S )N)override)r  r  zUnable to download file z6 as there is a directory with the same path, skipping.z_ as there is a file with the same path as a directory this file is expected to be in, skipping.)r[   r$  rb  r?  r   r+   rh   rY   loggerdebugIsADirectoryErrorr   NotADirectoryErrornotify_downloaded)r  r  multipart_executorrK  rp  download_loggerrr  ro  r  r   r   _download_entry	  s8   z+Artifact._download.<locals>._download_entry@   )max_workers)NT)cursorper_pagec                 s  s    | ]	}|j r|j V  qd S rm  noder  rK  r   r   r   	<genexpr>1  s    z%Artifact._download.<locals>.<genexpr>)r  i  <   zDone. 02dr	  z04.1fz (z.1fzMB/s)Fr  )r  rP   r  r   rr   rs   )"r  r1  rY  r$  re   r*   rg   r  r  rL   r   r   &get_artifact_fetch_file_url_batch_sizer   _fetch_file_urls	page_infohas_next_page
end_cursoredgesr[  rv  _download_urlr   r!  rh   r  submitr   r   r@  absdivmodrg  r8   )r   ro  rp  r  rq  rr  r  size_mblogr  r  r  
batch_sizeactive_futuresr  has_more
files_page
file_nodesr  r  futuredt_secshrsminssecsr   r  r   rt    s^   


(
00zArtifact._downloadCallable[..., Any]c                   s2   dd l }tjtdd|jddd fdd}|S )Nr      )minutes)retry_timedeltaretryable_exceptionsr  r  rk   r  rg  rr   rb   c                   s.  ddl m}m}m}m} ddlm}  jd u rtdt	 jt
jrgt|} j j jdd  j| |d} jj||dd	}	||	}
|
j }rZ|j }rZ|j }rZ|j }sbtd
 j||S t|} j| |d} jj||dd	}	||	}
|
j }r|j }std
 j||S )NrE   )GET_ARTIFACT_FILE_URLS_GQL%GET_ARTIFACT_MEMBERSHIP_FILE_URLS_GQLGetArtifactFileUrlsGetArtifactMembershipFileUrlsra   r;  r	  r   )r   r   r   r  r  perPager  )r   r  z$Unable to fetch files for artifact: )r   r  r  )r   r  r  r  r  _models.paginationrb   r   r<  rI   r   $ARTIFACT_COLLECTION_MEMBERSHIP_FILESr\   r   r   rg   r  r-  r   r   r   artifact_membershiprv  r   r   r   )r  r  r  r  r  r  rb   queryr   r   r   r   r   r   rv  r   r   r   r   _implf  sH   






z6Artifact._build_fetch_file_urls_wrapper.<locals>._implr  r  rk   r  rg  rr   rb   )requestsr0   	retriabler   RequestException)r   r  r  r   r   r   _build_fetch_file_urls_wrapperc  s   /z'Artifact._build_fetch_file_urls_wrapperr  r  r  rb   c                 C  s    | j d u r
|  | _ |  ||S rm  )r   r  )r   r  r  r   r   r   r    s   

zArtifact._fetch_file_urlsc              
   C  s   |p| j dd}t|D ].\}}}|D ]&}tj||}tjj||d}z| | W q ty:   t| Y qw q| j	|dS )a  Replace the specified root directory with the contents of the artifact.

        WARNING: This will delete all files in `root` that are not included in the
        artifact.

        Args:
            root: The directory to replace with this artifact's files.

        Returns:
           The path of the checked out contents.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        F)include_versionr  )ro  )
_default_rootr  r  r   r  r  r[  r^  r@  rb  )r   ro  r  r  rv  ru  	full_pathartifact_pathr   r   r   checkout  s   	zArtifact.checkoutc           
   
   C  s   |p|   }t|D ]2\}}}|D ]*}tj||}tjj||d}z| | W q ty<   td| d| j	 w qd}| j
j D ]!}	|	jdu rcttj||	j|	jkrbtd|	j qF|d7 }qF|dkrvtd| d	 dS dS )
a  Verify that the contents of an artifact match the manifest.

        All files in the directory are checksummed and the checksums are then
        cross-referenced against the artifact's manifest. References are not verified.

        Args:
            root: The directory to verify. If None artifact will be downloaded to
                './artifacts/self.name/'.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
            ValueError: If the verification fails.
        r  zFound file z# which is not a member of artifact r   NzDigest mismatch for file: rE   zskipped verification of z refs)r  r  r  r   r  r  r[  r^  r   rg   r1  rY  rm  ra  r7   r%  r+   )
r   ro  r  r  rv  ru  r  r  	ref_countr  r   r   r   verify  s.   


zArtifact.verifyc                 C  sN   |du rt jdd| j}t| jjdkrtd| t	| jjd 
|S )a  Download a single file artifact to the directory you specify with `root`.

        Args:
            root: The root directory to store the file. Defaults to
                `./artifacts/self.name/`.

        Returns:
            The full path of the downloaded file.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
            ValueError: If the artifact contains more than one file.
        Nr  	artifactsrE   zxThis artifact contains more than one file, call `.download()` to get all files or call .get_entry("filename").download()r   )r  r   r  rg   r  r1  rY  r   r[  r  rb  )r   ro  r   r   r   ru    s   zArtifact.filer  nameslist[str] | Noner#   c                 C  s$   | j  }du rtdt|| ||S )a  Iterate over all files stored in this artifact.

        Args:
            names: The filename paths relative to the root of the artifact you wish to
                list.
            per_page: The number of files to return per request.

        Returns:
            An iterator containing `File` objects.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        Nr;  )r   r<  r#   )r   r  r  r   r   r   r   rv   	  s   zArtifact.filesr  c                 C  s@   |r| j n| j dd }tjt |}tt|pt	|S )Nr	  r   )
r/  r  r  r   r  r   get_artifact_dirr8   r3   r4   )r   r  rg   ro  r   r   r   r  	  s   zArtifact._default_rootdir_pathc                 C  s(   t |p|  }| jtj| |S rm  )rh   r  r   r  r  r   abspath)r   r  ro  r   r   r   rs  	  s   zArtifact._add_download_rootr  c                 C  sn   t j|}|t j}tt|d D ] }t jjt jg|d| R  | jv r4t jj||d    S qdS )z:Convert a local file path to a path entry in the artifact.rE   N)	r  r   r  r  sepranger  r  r   )r   r  abs_file_pathabs_file_partsir   r   r   _local_path_to_name"	  s   $zArtifact._local_path_to_namedelete_aliasesc                 C  s*   | j rtd |   dS | | dS )a  Delete an artifact and its files.

        If called on a linked artifact, only the link is deleted, and the
        source artifact is unaffected.

        Use `Artifact.unlink()` instead of `Artifact.delete()` to remove a
        link between a source artifact and a collection.

        Args:
            delete_aliases: If set to `True`, delete all aliases associated
                with the artifact. If `False`, raise an exception if
                the artifact has existing aliases. This parameter is ignored
                if the artifact is retrieved from a collection it is linked to.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        zDeleting a link artifact will only unlink the artifact from the source artifact and not delete the source artifact and the data of the source artifact.N)r  r   r+   _unlink_delete)r   r  r   r   r   rK  -	  s   zArtifact.deletec                 C  sT   ddl m}m} | jd u rtdt|}|| j|d}| jj|d| id d S )NrE   )DELETE_ARTIFACT_GQLDeleteArtifactInputr  )r   r  r  r   )	r   r  r  r   r<  r\   r   r   r  )r   r  r  r  r   r  r   r   r   r  H	  s   
zArtifact._deletetarget_pathIterable[str] | Nonec                   s  ddl m} ddlm} ddlm}m}m} ddlm}m	}	m
}
 | jr(t d |  r;|  s7| j| jd |   | j }du rFtd	|  }||j|d
pVdd   rp jpf|dpfd}t|| j| _n j| jd |	di t   fdd|
|pg D }|| j j j j|d}d|  i}d }}t!|t"j#sdh}dh}t$|||d}|j%||d}|&|j'}|r|j( }r| j)| |dS |r|j* }dust+d ,  d| }|d| jid-|S )ae  Link this artifact to a collection.

        Args:
            target_path: The path of the collection. Path consists of the prefix
                "wandb-registry-" along with the registry name and the
                collection name `wandb-registry-{REGISTRY_NAME}/{COLLECTION_NAME}`.
            aliases: Add one or more aliases to the linked artifact. The
                "latest" alias is automatically applied to the most recent artifact
                you link.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.

        Returns:
            The linked artifact.
        r   )ApirE   )LINK_ARTIFACT_GQLLinkArtifactLinkArtifactInput)ArtifactPathrc   ri  zhLinking to a link artifact will result in directly linking to the source artifact of that link artifact.)r   Nr  r   uncategorizedr[  r  c                   s   g | ]} j |d qS ))r  r  r  r  r  r   r   r  	  s    
z!Artifact.link.<locals>.<listcomp>)r   artifact_portfolio_namer   r   r  r  includeAliasesartifactMembership)omit_variablesomit_fieldsr   r   z5Unable to parse linked artifact version from responser   r   )	overridesr   ).r   r  wandb.sdk.internal.internal_apir   r  r  r  r   r  rc   ri  r  r+   r4  r}  r  r   r  r   r<  r~  from_strwith_defaultsr   is_registry_pathr   rH   r?  r
   r   rg   r   r  rI   r   -ARTIFACT_MEMBERSHIP_IN_LINK_ARTIFACT_RESPONSEr%   r   r   r   r  r   r   r   r   	_artifact)r   r  r  r  InternalApir  r  r  r  rc   ri  r   r~  orgr  r  r   r  r  r   r   r   r   version_idx	link_namer   r  r   linkV	  sf   



zArtifact.linkc                 C  s0   | j std| jdt| jd|   dS )zUnlink this artifact if it is a linked member of an artifact collection.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
            ValueError: If the artifact is not linked to any collection.
        r   zE is not a linked artifact and cannot be unlinked.  To delete it, use z	 instead.N)r  r   r9  r    rK  r  r   r   r   r   unlink	  s   	
zArtifact.unlinkc              
   C  s   ddl m}m} | jd u rtdt|}|| j| jjd}d| i}z| jj	||d W d S  t
yD } z	t
d| j|d }~ww )NrE   )UNLINK_ARTIFACT_GQLUnlinkArtifactInputr  )r   artifact_portfolio_idr  r   z2You do not have permission to unlink the artifact )r   r  r  r   r<  r\   r   r   r  r   r'   r9  )r   r  r  mutationr  r   rK  r   r   r   r  	  s&   

zArtifact._unlink	list[Run]c                   s   ddl m}m} | j  du rtdt|}d| ji} j||d}||}|j	 }rH|j
 }rH|j }	rHdd |	D }
 fd	d
|
D S g S )zGet a list of the runs that have used this artifact and its linked artifacts.

        Returns:
            A list of `Run` objects.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        rE   )ARTIFACT_USED_BY_GQLArtifactUsedByNrs  r   r   c                 s      | ]}|j V  qd S rm  r  r  r   r   r   r  	      z#Artifact.used_by.<locals>.<genexpr>c                   s,   g | ]}|j  rt jjj|jqS r   )r   r$   r   rg   )r  r  r   r   r   r   r  	  s    z$Artifact.used_by.<locals>.<listcomp>)r   r  r	  r   r<  r\   r   r   r   r   used_byr  )r   r  r	  r  r   r   r   r   r  r  	run_nodesr   r  r   r  	  s$   


zArtifact.used_by
Run | Nonec                 C  s   ddl m}m} | j }du rtdt|}d| ji}|j||d}||}|j	 }rF|j
 }	rF|	j }
rF|	j }rFt||jj|j|
S dS )zGet the W&B run that originally logged the artifact.

        Returns:
            The name of the W&B run that originally logged the artifact.

        Raises:
            ArtifactNotLoggedError: If the artifact is not logged.
        rE   )ARTIFACT_CREATED_BY_GQLArtifactCreatedByNrs  r   r   )r   r  r  r   r<  r\   r   r   r   r   
created_byrg   r   r$   r   )r   r  r  r   r   r   r   r   r   creatorrg   r   r   r   r   	logged_by
  s"   


zArtifact.logged_bydict[str, Any]c                 C  s   t | S )zReturns the artifact encoded to the JSON format.

        Returns:
            A `dict` with `string` keys representing attributes of the artifact.
        )r@   r   r   r   r   json_encode
  s   zArtifact.json_encoder   r   c                 C  sr   ddl m}m} d|v r|n| d}t|}| ||d}|j||d}||}	|	j }
r7|
j }r7|jj	S dS )z@Returns the expected type for a given artifact name and project.rE   )ARTIFACT_TYPE_GQLArtifactTyper	  z:latestr   r   N)
r   r  r  r\   r   r   r   r   r  rg   )r   r   rg   r   r  r  r   r   r   r   r   r   r   r   r   _expected_type(
  s   
zArtifact._expected_typec                 C  s&   d}d}| j s	d S | jr|S | jp|S )N)r   r   r   )r   re  DISABLEDr   r   r   r  9
  s   
z%Artifact._ttl_duration_seconds_to_gqlc                   sr  ddl m ddlm}m m} ddlm} | jdu rt	d| j
 }du r*t	dt|}|j|d	| jid
}||}|j }rL|j }	rL|	j }
sPt	dt } fdd|
D }|D ]Stdd jD }dj }||vr}g ||ng |}rj rj }r|jjr|jst	d||jj|jj d| ||d}| |}|| qat|S )z-Fetches all linked artifacts from the server.r   )gql_typenamerE   )FETCH_LINKED_ARTIFACTS_GQLArtifactPortfolioTypeFieldsFetchLinkedArtifacts)rd   NzBUnable to find any artifact memberships for artifact without an IDrI  
artifactIDr   z4Unable to find any artifact memberships for artifactc                 3  s6    | ]}|j  rj rj krV  qd S rm  )r  r   
typename__)r  edger  colr  r  r   r   r  f
  s    z3Artifact._fetch_linked_artifacts.<locals>.<genexpr>c                 s  r
  rm  r  r  r   r   r   r  p
  r  r  z*Unable to fetch fields for linked artifactr	  )r   r   rg   r-  r  )wandb._pydanticr  r   r  r  r   r   rd   r   r   r   r%   r   r   r   artifact_membershipsr  r   r   r  r   r   r   r   rg   -_create_linked_artifact_using_source_artifactr  r  )r   r  r   rd   r   r   r   r   r   membershipsmembership_edgesrH  linked_nodesr  r-  r  r   link_fieldsr  r   r$  r   rG  G
  sf   

	
z Artifact._fetch_linked_artifactsr,  rd   c                 C  sP   t | }|j|_|j|_t |j|_|j|_|j|_	|j
|_|j|_|j|_|S )z0Copies the source artifact to a linked artifact.)r	   r-  r   r  r   r   rg   r   r   r   r   r   r  r   rH  r   )r   r,  linked_artifactr   r   r   r(  
  s   z6Artifact._create_linked_artifact_using_source_artifact)NNFNN)rg   rh   ri   rh   rj   rk   rl   rm   rn   ro   rp   rk   rq   rk   rr   rs   )rr   rh   )r   rh   r   r^   rr   r   )r   rc   r   r^   rr   rf   )r   rc   r   r^   r   ro   rr   rf   )r   r`   r   rc   r   r^   rr   rf   )
r   rc   r   r_   r   r^   r   r  rr   rf   )r   r_   r   r  r  r  rr   rs   )rr   rf   )rr   rk   )rr   r"   )rr   ro   )rr   rF  )rT  rh   rr   rh   )rj   rk   rr   rs   )rr   r^  )rl   r^  rr   rs   )rr   ra  )rc  rd  rr   rs   )rr   rh  )r  rh  rr   rs   )r   rh  rr   rs   )rl  rk   rr   rs   )rr   rO   )rr   rg  )rr   r{  )rr   rs   rk  )r   rk   r~  r  rr   rs   )r  r  r   r^   rr   rs   rm  )r  r{  rr   rf   )r   rh   rr   rs   )r  r  r   rc   rr   rs   )rg   rh   rr   r  )rg   rh   r  r&   rr   rP   )r  N)rg   rh   r  rh   r  rk   rr   r  )NFFr  F)r  rh   rg   rk   r  r  r  r  r  r  r  ro   rr   rP   )NFr  F)r  rh   rg   rk   r  r  r  r  r  ro   rr   rs   )NTN)
r  r  rg   r  r  ro   r  r{  rr   r  )F)r  r&   rg   r:   r  ro   rr   rP   )rg   r:   r   r:   r%  rI  r  r  r  r  r  ro   rr   rP   )r  rV  rr   rs   )rg   r:   rr   rP   )r  rh   rr   rk   )rg   rh   rr   rj  )NFNNN)ro  r  rp  ro   r  r  rq  r  rr  r  rr   r8   )FFN)
ro  rh   rp  ro   r  ro   rq  r  rr   r8   )FNNN)ro  rh   rp  ro   r  r  rq  r  rr  r  rr   r8   )rr   r  r  r  )ro  rk   rr   rh   )ro  rk   rr   rs   )ro  rk   rr   r:   )Nr  )r  r  r  rg  rr   r#   )T)r  ro   rr   r8   )r  r  rr   r8   )r  rh   rr   rk   )r  ro   rr   rs   )r  rh   r  r  rr   rf   )rr   r  )rr   r  )rr   r  )
r   rh   r   rh   rg   rh   r   r^   rr   rk   )r,  rd   rr   rf   )s__name__
__module____qualname____doc__r  r  r6  atexitregistercleanupr   r   classmethodr   r   r   r   r   r  rJ   r3  propertyr   r   r   rg   r9  r-  r   r?  rA  r/  rC  rD  rE  r  rH  rL  ri   rU  rQ  rR  rS  rj   setterrl   rc  r  r   rl  rn   rp   r#  r1  rp  r%  r$  r&  r'  r(  r)  r*  r  r4  r}  r  r  r  r  r!   r  r  r  r  r  r=  contextmanagerrK   r  r  r  r  r  r  r@  r\  r[  r   ri  r]  rb  r  rt  r  r  r  r  ru  rv  r  rs  r  rK  r  r  r  r  r  r  r  staticmethodr  r  rG  r(  r   r   r   r   rf   s   s   
#c!" k$		(
"
*%*8FVc".7@m9%e Drf   c                   @  s   e Zd ZdZegZdS )_ArtifactVersionTypeartifactVersionN)r.  r/  r0  rg   rf   typesr   r   r   r   r:  
  s    
r:  )r1  
__future__r   r2  r=  r9  loggingmultiprocessing.dummyr  r  r   rM  rP  r  r  collectionsr   collections.abcr   r   concurrent.futuresr   r   r   r	   dataclassesr
   r   datetimer   	itertoolsr   ry  r   r   typingr   r   r   r   r   r   r   urllib.parser   r   r   pydanticr   r   r   r   wandb._iterutilsr   r   r&  r   wandb._strutilsr    wandb.apis.normalizer!   wandb.apis.publicr"   r#   r$   wandb.apis.public.utilsr%   wandb.data_typesr&   wandb.errorsr'   wandb.errors.errorsr(   wandb.errors.termr)   r*   r+   wandb.protor,   r   wandb.proto.wandb_telemetry_pb2r-   	wandb.sdkr.   wandb.sdk.data_types._dtypesWBTyper/   wandb.sdk.libr0   r1   wandb.sdk.lib.deprecationr2   wandb.sdk.lib.filesystemr3   r4   wandb.sdk.lib.hashutilr5   r6   r7   wandb.sdk.lib.pathsr8   r9   r:   r;   wandb.sdk.lib.runidr<   r=   wandb.sdk.mailboxr>   
wandb.utilr?   r@   rA   rB   rC   rD   
_factoriesrF   	_gqlutilsrG   rH   rI   r   rJ   rK   artifact_download_loggerrL   rM   rN   artifact_manifestrO   artifact_manifest_entryrP   'artifact_manifests.artifact_manifest_v1rQ   artifact_staterR   artifact_ttlrS   
exceptionsrT   rU   rV   rW   stagingrX   storage_handlers.gcs_handlerrY   storage_policies._factoriesrZ   storage_policies._multipartr[   
reset_path	wandb_gqlr\   r]   r^   r   r_   r`   r  rb   rc   rd   	getLoggerr.  r  re   __annotations__rf   r:  r  r   r   r   r   <module>   s    $	 	
                    =