o
    niT                     @   sn  d 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mZmZmZmZ ddlmZ ddlZddlmZ ddlmZ ddlmZ dd	lmZ d
dlmZ d
dlmZmZ e
rhddl m!Z! e"e#Z$dddZ%dZ&G dd dej'Z(G dd dZ)G dd dZ*dee+ef dee+ef de,ddfddZ-dee+ef dee+ef de,ddfddZ.dS ) z~Convert launch arguments into a runnable wandb launch script.

Arguments can come from a launch spec or call to wandb launch.
    N)deepcopy)TYPE_CHECKINGAnyDictListOptionalcast)shlex_quote)Api)	CommError)get_entrypoint_file)generate_id   )LaunchError)
LOG_PREFIXrecursive_macro_sub)Artifact  )local	sagemaker    c                   @   s6   e Zd ZU dZdZeed< dZeed< dZeed< dS )	LaunchSourcea5  Enumeration of possible sources for a launch project.

    Attributes:
        DOCKER: Source is a Docker image. This can happen if a user runs
            `wandb launch -d <docker-image>`.
        JOB: Source is a job. This is standard case.
        SCHEDULER: Source is a wandb sweep scheduler command.
    r   DOCKER   JOB   	SCHEDULERN)	__name__
__module____qualname____doc__r   int__annotations__r   r    r#   r#   \/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/wandb/sdk/launch/_project_spec.pyr   &   s
   
 	r   c                   @   s  e Zd ZdZ	dWdee dee dedeeef deded	ee d
eeef deeef deeef dedeeef dee dee fddZ	dXddZ
deddfddZdeeef ddfddZdeeef ddfddZdefddZedeeef dedd fdd Zedee fd!d"Zedee fd#d$Zedee fd%d&Zd'eddfd(d)Zd*eddfd+d,Zd-eddfd.d/Zedefd0d1Zedee fd2d3Zejd4eddfd5d3Zedee fd6d7Zejd4eddfd8d7Zedee fd9d:Zejd4eddfd;d:Zd<edeeef fd=d>Zdefd?d@Zedee fdAdBZ e jd4eddfdCdBZ dedD fdEdFZ!dGe"e ddDfdHdIZ#dXdJdKZ$defdLdMZ%dXdNdOZ&dXdPdQZ'dedRe(deeef fdSdTZ)defdUdVZ*dS )YLaunchProjectaf  A launch project specification.

    The LaunchProject is initialized from a raw launch spec an internal API
    object. The project encapsulates logic for taking a launch spec and converting
    it into the executable code.

    The LaunchProject needs to ultimately produce a full container spec for
    execution in docker, k8s, sagemaker, or vertex. This container spec includes:
    - container image uri
    - environment variables for configuring wandb etc.
    - entrypoint command and arguments
    - additional arguments specific to the target resource (e.g. instance type, node selector)

    This class is stateful and certain methods can only be called after
    `LaunchProject.fetch_and_validate_project()` has been called.

    Notes on the entrypoint:
    - The entrypoint is the command that will be run inside the container.
    - The LaunchProject stores two entrypoints
        - The job entrypoint is the entrypoint specified in the job's config.
        - The override entrypoint is the entrypoint specified in the launch spec.
    - The override entrypoint takes precedence over the job entrypoint.
    Nurijobapilaunch_spectarget_entitytarget_projectnamedocker_configgit_info	overridesresourceresource_argsrun_idsweep_idc                 C   sB  || _ || _|d urtt d|  d | _|| _|| _|| _|	 | _
|| _t|}||i di }|| _|| _|| _|d| _|d| _d | _d | _d | _|di dpe|di d| _|dpp|d	| _|d
d| _d | _| |
 |   | |	 d | _d | _|pt  | _!d | _"d | _#d | _$d S )NzLaunching job: builderauthorpython_versionaccelerator
base_imagecudadocker_image	image_uriuser_idr   )%r&   r'   wandbtermlogr   _job_artifactr(   r)   r*   lowerr+   r,   r   getpopr0   r1   r3   r5   r6   _job_dockerfile_job_build_context_job_base_imageaccelerator_base_imager:   docker_user_id_entry_pointinit_overridesinit_sourceinit_git	deps_type_runtimer   r2   _queue_name_queue_entity_run_queue_item_id)selfr&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   resource_args_copyresource_args_buildr#   r#   r$   __init__O   sX   



zLaunchProject.__init__returnc                 C   st   | j d urtj| _d | _d S | jd urtj| _t | _d S | j	r6| j	
dr8tj| _t | _| j| _d S d S d S )Nplaceholder)r:   r   r   sourceproject_dirr'   r   tempfilemkdtempr&   
startswithr   osgetcwdoverride_entrypointrH   rQ   r#   r#   r$   rJ      s   



zLaunchProject.init_sourcenew_dirc              	   C   s>   | j }|durtj||ddtddd t| || _ dS )z0Change the project directory to a new directory.NTzfsmonitor--daemon.ipcz.git)symlinksdirs_exist_okignore)rX   shutilcopytreeignore_patternsrmtree)rQ   r`   old_dirr#   r#   r$   change_project_dir   s   


z LaunchProject.change_project_dirc                 C   s   | d| _| d| _d S )Nversionrepo)rA   git_versiongit_repo)rQ   r.   r#   r#   r$   rK      s   zLaunchProject.init_gitc                 C   s   || _ |dg | _|di | _|di | _|di | _d| _|d| _|d}|r?t	d t
t||d	| _dS dS )
z4Initialize override attributes for a launch project.args
run_config	artifactsfilesN
dockerfileentry_pointzAdding override entry pointr,   command)r/   rA   override_argsoverride_configoverride_artifactsoverride_filesr^   override_dockerfile_loggerinfo
EntryPointr   )rQ   r/   r^   r#   r#   r$   rI      s   

zLaunchProject.init_overridesc                 C   s   | j tjkr
| j S | j S )z'String representation of LaunchProject.)rW   r   r   r'   r&   r_   r#   r#   r$   __repr__   s   zLaunchProject.__repr__c                 C   s   d}| dr|d }t| d| d|||d |d || di | di | d	i | d
d| di | dd| di S )a  Constructs a LaunchProject instance using a launch spec.

        Arguments:
            launch_spec: Dictionary representation of launch spec
            api: Instance of wandb.apis.internal Api

        Returns:
            An initialized `LaunchProject` object
        Nr,   r&   r'   entityprojectdockergitr/   r0   r1   r2   r3   )rA   r%   )clsr)   r(   r,   r#   r#   r$   	from_spec   s&   







zLaunchProject.from_specc                 C      | j S NrC   r_   r#   r#   r$   job_dockerfile      zLaunchProject.job_dockerfilec                 C   r   r   rD   r_   r#   r#   r$   job_build_context   r   zLaunchProject.job_build_contextc                 C   r   r   rE   r_   r#   r#   r$   job_base_image   r   zLaunchProject.job_base_imagerr   c                 C   
   || _ d S r   r   )rQ   rr   r#   r#   r$   set_job_dockerfile      
z LaunchProject.set_job_dockerfilebuild_contextc                 C   r   r   r   )rQ   r   r#   r#   r$   set_job_build_context   r   z#LaunchProject.set_job_build_contextr8   c                 C   r   r   r   )rQ   r8   r#   r#   r$   set_job_base_image   r   z LaunchProject.set_job_base_imagec                 C   s   | j d ur| j S | jd ur| jS | jd ur-| jdd}|d}||d  }tj|S | jd us4J tj| j	dd S )Nzhttps:///:r   )
r   r:   r&   replacefindr=   utilmake_docker_image_name_safer'   split)rQ   cleaned_uri	first_sepshortened_urir#   r#   r$   
image_name   s   



zLaunchProject.image_namec                 C   r   r   rN   r_   r#   r#   r$   
queue_name  r   zLaunchProject.queue_namevaluec                 C   r   r   r   rQ   r   r#   r#   r$   r   	     
c                 C   r   r   rO   r_   r#   r#   r$   queue_entity  r   zLaunchProject.queue_entityc                 C   r   r   r   r   r#   r#   r$   r     r   c                 C   r   r   rP   r_   r#   r#   r$   run_queue_item_id  r   zLaunchProject.run_queue_item_idc                 C   r   r   r   r   r#   r#   r$   r     r   imagec                 C   sF   | j | j| j| j|| jd}|tj t| j	|}t
tttf |S )a  Substitute values for macros in resource arguments.

        Certain macros can be used in resource args. These macros allow the
        user to set resource args dynamically in the context of the
        run being launched. The macros are given in the ${macro} format. The
        following macros are currently supported:

        ${project_name} - the name of the project the run is being launched to.
        ${entity_name} - the owner of the project the run being launched to.
        ${run_id} - the id of the run being launched.
        ${run_name} - the name of the run that is launching.
        ${image_uri} - the URI of the container image for this run.

        Additionally, you may use ${<ENV-VAR-NAME>} to refer to the value of any
        environment variables that you plan to set in the environment of any
        agents that will receive these resource args.

        Calling this method will overwrite the contents of self.resource_args
        with the substituted values.

        Args:
            image (str): The image name to fill in for ${wandb-image}.

        Returns:
            Dict[str, Any]: The resource args with all macros filled in.
        )project_nameentity_namer2   run_namer;   r5   )r+   r*   r2   r,   r5   updater\   environr   r1   r   r   strr   )rQ   r   update_dictresultr#   r#   r$   fill_macros  s   zLaunchProject.fill_macrosc                 C   s"   | j durdS | jtjkrdS dS )z0Checks the source to see if a build is required.NFT)r   rW   r   r   r_   r#   r#   r$   build_requiredF  s
   
zLaunchProject.build_requiredc                 C   s   | j r| j S dS )zReturns the Docker image associated with this LaunchProject.

        This will only be set if an image_uri is being run outside a job.

        Returns:
            Optional[str]: The Docker image or None if not specified.
        N)_docker_imager_   r#   r#   r$   r:   N  s   	zLaunchProject.docker_imagec                 C   s   || _ |   dS )zSets the Docker image for the project.

        Args:
            value (str): The Docker image to set.

        Returns:
            None
        N)r   *_ensure_not_docker_image_and_local_processr   r#   r#   r$   r:   [  s   
r}   c                 C   s$   | j s| js| jstddS | j S )z+Returns the job entrypoint for the project.zLProject must have at least one entry point unless docker image is specified.N)rH   r:   r   r   r_   r#   r#   r$   get_job_entry_pointh  s   z!LaunchProject.get_job_entry_pointru   c                 C   s,   | j du s	J dt|d |d}|| _ |S )z#Set job entrypoint for the project.NzCCannot set entry point twice. Use LaunchProject.override_entrypointrt   )rH   r}   )rQ   ru   new_entrypointr#   r#   r$   set_job_entry_pointt  s   z!LaunchProject.set_job_entry_pointc                 C   s6   | j tjkrdS | j tjkr|   | jdusJ dS )a\  Fetches a project into a local directory, adds the config values to the directory, and validates the first entrypoint for the project.

        Arguments:
            launch_project: LaunchProject to fetch and validate.
            api: Instance of wandb.apis.internal Api

        Returns:
            A validated `LaunchProject` object.

        N)rW   r   r   r   
_fetch_jobrX   r_   r#   r#   r$   fetch_and_validate_project}  s
   z(LaunchProject.fetch_and_validate_projectc                 C   sZ   | j tjkr| jdusJ | jj d| jj S | j tjkr)t| jt	s&J | jS t
d)z;Returns a unique string identifying the source of an image.Nz:vz8Unknown source type when determining image source string)rW   r   r   r?   r,   rj   r   
isinstancer:   r   r   r_   r#   r#   r$   get_image_source_string  s   z%LaunchProject.get_image_source_stringc                 C   s$   | j dur| jdkrtddS dS )zEnsure that docker image is not specified with local-process resource runner.

        Raises:
            LaunchError: If docker image is specified with local-process resource runner.
        Nzlocal-processz>Cannot specify docker image with local-process resource runner)r:   r0   r   r_   r#   r#   r$   r     s
   z8LaunchProject._ensure_not_docker_image_and_local_processc                 C   s   t jj }t }z
|j| j|d}W n! ty5 } z|j}t	d| j d| d|j
d d}~ww ||  |j| _dS )zFetches the job details from the public API and configures the launch project.

        Raises:
            LaunchError: If there is an error accessing the job.
        )pathzError accessing job z: z on base_urlN)r=   apispublicr
   rY   rZ   r'   r   messager   settingsrA   configure_launch_projectr?   )rQ   
public_apijob_dirr'   emsgr#   r#   r$   r     s   
zLaunchProject._fetch_jobmax_env_lengthc                 C   sN  i }| d|d< | jd}|p|j|d< | jr| j|d< | j|d< d|d< | j|d	< | jr4| j|d
< | jdur>| j|d< d| jv rL|sL| jd |d< | j	rT| j	|d< | jdddkrad|d< | j
rk| j
|tjj< | jru| j|tjj< | jr| j|tjj< t| j|| t| j|| i }| jrtjj| ji}ti || j|d< |S )zGenerate environment variables for the project.

        Arguments:
        launch_project: LaunchProject to generate environment variables for.

        Returns:
            Dictionary of environment variables.
        r   WANDB_BASE_URL_wandb_api_keyWANDB_API_KEYWANDB_PROJECTWANDB_ENTITYTrueWANDB_LAUNCHWANDB_RUN_IDWANDB_DOCKERN
WANDB_NAMEr5   WANDB_USERNAMEWANDB_SWEEP_ID_resume_countr   allowWANDB_RESUMEWANDB_ARTIFACTS)r   r)   rA   api_keyr+   r*   r2   r:   r,   r3   r   r=   envLAUNCH_QUEUE_NAMEr   LAUNCH_QUEUE_ENTITYr   LAUNCH_TRACE_ID_inject_wandb_config_env_varsrw   _inject_file_overrides_env_varsry   r'   r   LAUNCH_JOB_ARTIFACT_SLOT_NAMEjsondumpsrx   )rQ   r(   r   env_varsoverride_api_keyrp   r#   r#   r$   get_env_vars_dict  sD   	






zLaunchProject.get_env_vars_dictc           
      C   s   dd l }d}| jd usJ tj| jd}tj|rt }t|N}||}	 zt	|}t
|dr9|j }nt|}|t| W n" tyN   Y n tyg }	 ztd|	  W Y d }	~	q(d }	~	ww q)W d    n1 ssw   Y  |dd|7 }d	|vrtt d
 |S )Nr    zrequirements.txtTr,   z"Unable to parse requirements.txt: zWANDB_ONLY_INCLUDE={} ,r=   z)wandb is not present in requirements.txt.)pkg_resourcesrX   r\   r   joinexistssetopenparse_requirementsnexthasattrr,   r@   r   addr	   StopIteration	Exceptionr{   warnformatr=   termwarnr   )
rQ   r   requirements_linebase_requirementsinclude_onlyfiterpkgr,   r   r#   r#   r$   parse_existing_requirements  s:   


	z)LaunchProject.parse_existing_requirementsr   )rU   N)+r   r   r   r    r   r   r
   r   r   rT   rJ   ri   rK   rI   r~   classmethodr   propertyr   r   r   r   r   r   r   r   setterr   r   r   boolr   r:   r   r   r   r   r   r   r   r!   r   r   r#   r#   r#   r$   r%   5   s    (

	





< )
	

0r%   c                   @   s<   e Zd ZdZdee dee fddZdeddfd	d
ZdS )r}   z1An entry point into a wandb launch specification.r,   ru   c                 C   s   || _ || _d S r   rt   )rQ   r,   ru   r#   r#   r$   rT     s   
zEntryPoint.__init__new_pathrU   Nc                 C   sB   t | jdkr| jd ds| jd dkr|| jd< dS dS dS )z*Updates the entrypoint path to a new path.r   r   pythonbashr   N)lenru   r[   )rQ   r  r#   r#   r$   update_entrypoint_path  s   z!EntryPoint.update_entrypoint_path)	r   r   r   r    r   r   r   rT   r  r#   r#   r#   r$   r}     s    r}   configenv_dictmaximum_env_lengthrU   c                    b   t | t kr|d< d S  fddtdt D }dd t|D }|| d S )NWANDB_CONFIGc                       g | ]
}||   qS r#   r#   .0ir  
str_configr#   r$   
<listcomp>      z1_inject_wandb_config_env_vars.<locals>.<listcomp>r   c                 S      i | ]
\}}d | |qS )WANDB_CONFIG_r#   r  r  chunkr#   r#   r$   
<dictcomp>#  s    z1_inject_wandb_config_env_vars.<locals>.<dictcomp>r   r   r  range	enumerater   )r  r  r  chunksconfig_chunks_dictr#   r  r$   r     s   
r   r/   c                    r	  )NWANDB_LAUNCH_FILE_OVERRIDESc                    r  r#   r#   r  r  str_overridesr#   r$   r  /  r  z3_inject_file_overrides_env_vars.<locals>.<listcomp>r   c                 S   r  )WANDB_LAUNCH_FILE_OVERRIDES_r#   r  r#   r#   r$   r  3  s    z3_inject_file_overrides_env_vars.<locals>.<dictcomp>r  )r/   r  r  r  overrides_chunks_dictr#   r  r$   r   '  s   
r   )/r    enumr   loggingr\   rd   rY   copyr   typingr   r   r   r   r   r   	six.movesr	   r=   wandb.apis.internalr
   wandb.errorsr   wandb.sdk.launch.utilsr   wandb.sdk.lib.runidr   errorsr   utilsr   r   wandb.sdk.artifacts.artifactr   	getLoggerr   r{   RESOURCE_UID_MAPIMAGE_TAG_MAX_LENGTHIntEnumr   r%   r}   r   r!   r   r   r#   r#   r#   r$   <module>   s\     

   V




