o
    niZd                  %   @   sd  U 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mZmZmZmZmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lm Z  d
dl!m"Z"m#Z# e$e%e# de%e" Z&erd dl'm(Z( e$dZ)dZ*dZ+dZ,e$d-e,e*gZ.e$dZ/e$dZ0e$dZ1dZ2e$dZ3e$dZ4e$dZ5e$dej6Z7e$dZ8e$dZ9e$dZ:e$dZ;dZ<d Z=d!Z>e?e@ZAejBd"d#d$ d%ZCe	d&d' ZDeeEeFf eGd(< d)eDd*< d+ZHd,e fd-d.ZId/ed,efd0d1ZJd2eEd,eKfd3d4ZLd2eEd,eKfd5d6ZMd2eEd,eKfd7d8ZNd2eEd,eKfd9d:ZOd;eEd,eEfd<d=ZPd>eEd,eeE fd?d@ZQd2eeE d>eeE dAedBeeE dCeeE dDeeeEef  d,eeeE eEf fdEdFZRdAedDeeeEef  fdGdHZSdIeeEef d,dfdJdKZT	dd2eeE d>eeE dAedLeeE dBeeE dCeeE dMeeE dNeeE dOeeeE  dPeeE dQeeeEef  dDeeeEef  dReeE dSeeE dTeeE dUeeE d,eeEef f"dVdWZUdIeeEef d,dfdXdYZVd2eEd,eeEeEeEf fdZd[ZW	\dd]eEd^eEd,eeE fd_d`ZXdaeeE dbeeE d,eeEeEf fdcddZYdeeeE d]eEd,dfdfdgZZdheEdieEd,dfdjdkZ[dieEd2eEdPeeE d,eeE fdldmZ\dneEdoeEd,eEfdpdqZ]dreEd,eEfdsdtZ^dueeEef dveeEef d,dfdwdxZ_dyedQeeEef d,eeef fdzd{Z`d|eeeEef  dueeeEef  dveeeEef  d,eeeEef eeEef f fd}d~ZadAed,eKfddZbdLeEd,eEfddZcdeEdeEdAeded d,df
ddZdddMeEdeKd,eKfddZedMeEd,dfddZfdeEdeeEeeE f d,eEfddZgdedeeEeeE f d,efddZhdedeid,eeEef fddZjdeeE d,eeE fddZkd,eeEeEf fddZldS )    N)defaultdict)TYPE_CHECKINGAnyDictListOptionalTuplecast)util)Api)LaunchError)GitReference)WandbReference)Config   )FAILED_PACKAGES_POSTFIXFAILED_PACKAGES_PREFIXz(.*))JobAndRunStatusTrackerzA^[^/|^~|^\.].*(git|bitbucket|dev\.azure\.com|\.visualstudio\.com)z)^https?://[0-9]+(?:\.[0-9]+){3}(:[0-9]+)?z^[a-zA-Z0-9_.-]+$z^https?://(api.)?wandb|z^https?://ap\w.qa.wandbz^https?://ap\w.wandb.testz^https?://localhostzWANDB_API_KEY=\w+(-\w+)?z\$\{(\w+)\}zG^(?:https://)?([\w]+)\.azurecr\.io/(?P<repository>[\w\-]+):?(?P<tag>.*)zx^(?:https://)?(?P<account>[\w-]+)\.dkr\.ecr\.(?P<region>[\w-]+)\.amazonaws\.com/(?P<repository>[\.\/\w-]+):?(?P<tag>.*)$z^(?:https://)?(?P<region>[\w-]+)-docker\.pkg\.dev/(?P<project>[\w-]+)/(?P<repository>[\w-]+)/?(?P<image_name>[\w-]+)?(?P<tag>:.*)?$zs3://([^/]+)(/(.*))?zgs://([^/]+)(?:/(.*))?z:^https://([^\.]+)\.blob\.core\.windows\.net/([^/]+)/?(.*)$z%^arn:([^:]+):[^:]*:[^:]*:[^:]*:[^:]*$SYNCHRONOUSz"~/.config/wandb/launch-config.yamlzmodel-registryzlaunch:magenta)fg c                   C   s   dS )Ni   r   r   r   T/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/wandb/sdk/launch/utils.py<lambda>W   s    r   MAX_ENV_LENGTHSi   SageMakerRunnerz
/mnt/wandbreturnc               
   C   s   t jd} | du r.d} d}	 t jd| }|du rn	| |7 } |d7 }q|dk r.tdt }zt| }W n tjyM } ztd	| |d}~ww || |S )
a  Load wandb config from WANDB_CONFIG environment variable(s).

    The WANDB_CONFIG environment variable is a json string that can contain
    multiple config keys. The WANDB_CONFIG_[0-9]+ environment variables are
    used for environments where there is a limit on the length of environment
    variables. In that case, we shard the contents of WANDB_CONFIG into
    multiple environment variables numbered from 0.

    Returns:
        A dictionary of wandb config values.
    WANDB_CONFIGN r   TWANDB_CONFIG_r   zBNo WANDB_CONFIG or WANDB_CONFIG_[0-9]+ environment variables foundzFailed to parse WANDB_CONFIG: )	osenvirongetr   r   jsonloadsJSONDecodeErrorupdate)
config_stridxchunkwandb_config
env_configer   r   r   load_wandb_config]   s0   
r/   funcc                    s   dt dt dt f fdd}|S )aC  Wrapper for running any function in an awaitable thread on an event loop.

    Example usage:
    ```
    def my_func(arg1, arg2):
        return arg1 + arg2


    future = event_loop_thread_exec(my_func)(2, 2)
    assert await future == 4
    ```

    The returned function must be called within an active event loop.
    argskwargsr   c                     s2   t  }tt|d  fddI d H }|S )Nc                      s    i S Nr   r   )r1   r0   r2   r   r   r      s    z9event_loop_thread_exec.<locals>.wrapper.<locals>.<lambda>)asyncioget_event_loopr	   r   run_in_executor)r1   r2   loopresultr0   )r1   r2   r   wrapper   s   z'event_loop_thread_exec.<locals>.wrapper)r   )r0   r:   r   r9   r   event_loop_thread_exec   s   r;   uric                 C   s,   t | pt| pt| pt| d uS r3   )_WANDB_URI_REGEXmatch_WANDB_DEV_URI_REGEX_WANDB_LOCAL_DEV_URI_REGEX_WANDB_QA_URI_REGEXr<   r   r   r   _is_wandb_uri   s   
rC   c                 C      t t| S r3   )boolr?   r>   rB   r   r   r   _is_wandb_dev_uri      rF   c                 C   rD   r3   )rE   r@   r>   rB   r   r   r   _is_wandb_local_uri   rG   rH   c                 C   rD   r3   )rE   _GIT_URI_REGEXr>   rB   r   r   r   _is_git_uri   rG   rJ   sc                 C   s   t ttd| S )NWANDB_API_KEY)strresubAPI_KEY_REGEX)rK   r   r   r   sanitize_wandb_api_key   s   rQ   jobc                 C   s"   |  d}t|dkr|d S d S )N/   r   )splitlen)rR   	job_partsr   r   r   get_project_from_job   s   
rX   apiprojectentitylaunch_configc           
      C   s   d }| d ur#t | rt| \}}}nt| r"tjtj| d }n|d ur+t|}|d u r>d }|r8|d}|p=|p=d}|d u rGt	||}d}	t
 dkrWtjjdkrWd}	tt |	 d| |rfd| nd  ||fS )	Nr   rZ   r    WindowszUTF-8u   🚀 zLaunching run into rS   )rC   parse_wandb_urirJ   r"   pathsplitextbasenamerX   r$   get_default_entityplatformsystemsysstdoutencodingwandbtermlog
LOG_PREFIX)
r<   rR   rY   rZ   r[   r\   
source_uri_config_projectprefixr   r   r   set_project_entity_defaults   s.   	

 ro   c                 C   s   d }|r	| d}|p| jS )Nr[   )r$   default_entity)rY   r\   config_entityr   r   r   rb      s   

rb   launch_specc                 C   s8   |  dd r|  dd rtd | d d S d S d S )Nresource_argstemplate_variablesznLaunch spec contains both resource_args and template_variables, only one can be set. Using template_variables.)r$   rh   termwarnpop)rr   r   r   r   %strip_resource_args_and_template_vars   s   rw   namedocker_imageresourceentry_pointversionrs   run_id
repositoryauthorsweep_idc                 C   sh  |dur|ni }| dur| |d< |dur||d< t | |||||\}}||d< |r-||d< ||d< |r7||d< d|vr?i |d< |rG||d d	< |rM||d
< d|vrY|rU|nd|d< d|vrai |d< |	ri|	|d d< d|vrqi |d< t|d dg tstd|
r|
|d< |r||d d< |dur||d< |r|pi }|dr||d d< nd|i|d< t| |S )z6Construct the launch specification from CLI arguments.Nr<   rR   r[   r   rZ   rx   dockerry   r   rz   gitr|   	overridesr1   z'override args must be a list of stringsrs   r{   r}   registryurl)ro   
isinstancer$   listr   rw   )r<   rR   rY   rx   rZ   r[   ry   rz   r{   r|   rs   r\   r}   r~   r   r   rr   r   r   r   construct_launch_spec   s`   
r   c                 C   s8   |  d}|  di  d}t|t|krtdd S )NrR   r   ry   zHExactly one of job or docker_image must be specified in the launch spec.)r$   rE   r   )rr   rR   ry   r   r   r   validate_launch_spec_sourceA  s   
r   c                 C   s>   t | }|r|jr|jr|jstd|  |j|j|jfS )z9Parse wandb uri to retrieve entity, project and run name.zTrouble parsing wandb uri )r   parser[   rZ   r}   r   )r<   refr   r   r   r^   K  s   
r^   requirements.local.txtdirfilenamec              
   C   s   z,t j}tt j| |d}tjddg||d W d    |W S 1 s%w   Y  |W S  tjyH } zt	d|  W Y d }~d S d }~ww )Nwpipfreeze)envrf   zCommand failed: )
r"   r#   openr_   join
subprocesscallCalledProcessErrorrh   	termerror)r   r   r   fr.   r   r   r   get_local_python_depsS  s   
r   req_1req_2c                 C   s   dt t dtttf fdd}z
|| }||}W n ttttfy0 } ztd| d}~ww g }t|	 t|	 A D ]}|
| q?i }|D ]\}	}
||	du r[|
||	< qKd|
 d||	  ||	< qK|S )	zIReturn a list of pip requirements that are not in req_1 but are in req_2.reqr   c                 S   sP  t  }| D ]}d }d }|drqd|v sd|v r-|dd }|dd dd }ncd	|v rH|d	}|d  }|d dd  }nHd
|v rc|d
}|d  }|d dd  }n-d|v r~|d}|d  }|d dd  }ntt|d ur|}ntd| |d urtt|sJ d| |||< q|S )N#zgit+zhg+z#egg=r   @r   z==z>=>z,Unable to parse pip requirements file line: zInvalid pip package name )	dict
startswithrU   lowerstriprN   r>   _VALID_PIP_PACKAGE_REGEX
ValueError)r   dline_name_version_sr   r   r   
_parse_reqc  sB   



z)diff_pip_requirements.<locals>._parse_reqz"Failed to parse pip requirements: Nvz and v)r   rM   r   AssertionErrorr   
IndexErrorKeyErrorr   setitemsappendr$   )r   r   r   
req_1_dict
req_2_dictr.   diffitempretty_diffrx   r|   r   r   r   diff_pip_requirements`  s"   $
r   requirements_filec                 C   s   | durUt j|| }t|}|  }W d   n1 s w   Y  t|}|durUt j||}t|}|  }W d   n1 sIw   Y  t|| dS t	d dS )zEWarn if local python dependencies differ from wandb requirements.txt.Nz,Unable to validate local python dependencies)
r"   r_   r   r   read
splitlinesr   r   _loggerwarning)r   r   requirements_pathr   wandb_python_depslocal_python_filelocal_python_deps_pathlocal_python_depsr   r   r   validate_wandb_python_deps  s   


r   patch_stringdst_dirc                 C   s   t d ttj|dd}||  W d   n1 sw   Y  ztddd| dd	dg W dS  tj	yB   t
d
w )z$Applies a patch file to a directory.zApplying diff.patchz
diff.patchr   Npatchz-sz--directory=z-p1z-iz/Failed to apply diff.patch associated with run.)r   infor   r"   r_   r   writer   
check_callr   rh   Error)r   r   fpr   r   r   apply_patch  s"   



r   c                 C   sF   t d t||}|du rtd| ||  |du r!|j}|S )zClones the git repo at ``uri`` into ``dst_dir``.

    checks out commit ``version``. Assumes authentication parameters are
    specified by the environment, e.g. by a Git credential helper.
    zFetching git repoNzUnable to parse git uri: )r   r   r   r   fetchr   )r   r<   r|   r   r   r   r   _fetch_git_repo  s   
	

r   fnameproject_dirc                 C   s   t jdd}t jdd}td | dd}ttj	|| 9}|
| |j}|jD ]$}|jdkrS|jd}g }	|D ]}
|
d	sL|	|
 q@d	|	|_q/W d    n1 s^w   Y  | }||\}}ttj	||d
}|| W d    |S 1 sw   Y  |S )N	nbconvertz@nbformat and nbconvert are required to use launch with notebooksnbformatzConverting notebook to scriptz.ipynb.pycode
!zw+)rh   r
   
get_moduler   r   replacer   r"   r_   r   readsr   
NO_CONVERTcells	cell_typesourcerU   r   r   PythonExporterfrom_notebook_node
writelines)r   r   r   r   new_namefhnbcellsource_linesmodified_linesr   exporterr   metar   r   r   "convert_jupyter_notebook_to_script  s<   





r   maybe_snake_strc                 C   s*   d| vr| S |  d}ddd |D S )Nrl   r    c                 s   s     | ]}|r
|  nd V  qdS )rl   N)title).0xr   r   r   	<genexpr>  s    z to_camel_case.<locals>.<genexpr>)rU   r   )r   
componentsr   r   r   to_camel_case  s   
r   build_configregistry_configc                 C   s<   |  di }| di }|r|r||krtdd S d S d S )Ncredentialsz-registry and build config credential mismatch)r$   r   )r   r   build_config_credentialsregistry_config_credentialsr   r   r   #validate_build_and_registry_configs  s   r   
kubernetesc           	         s   | dd }d }|d ustjtjdrf| j|\}}d }| drA|d }|D ]}|d |kr8|} nq,td| d|}t	dd | j
||d I d H  | jj||d d	I d H }||fS | j  | jj }||fS )
N
configFilez~/.kube/configcontextrx   zSpecified context z was not found.awsclizoawscli is required to load a kubernetes context from eks. Please run `pip install wandb[launch]` to install it.)r   )r$   r"   r_   exists
expanduserconfiglist_kube_config_contextsr   r
   r   load_kube_confignew_client_from_configload_incluster_configclient
api_client	ApiClient)	r   rs   config_filer   all_contextsactive_contextcontext_namecr  r   r   r   get_kube_context_and_api_client  s<   


r  default_launch_configc                 C   sn   i }|d u r| d ur|  di }n|d ur|}i }|d u r(| d ur(|  di }n|d ur.|}t|| ||fS )Nbuilderr   )r$   r   )r  r   r   resolved_build_configresolved_registry_configr   r   r   !resolve_build_and_registry_config/  s   
r  c                 C   s   | j  }|stddS )zCheck if a user is logged in.

    Raises an error if the viewer doesn't load (likely a broken API key). Expected time
    cost is 0.1-0.2 seconds.
    zCould not connect with current API-key. Please relogin using `wandb login --relogin` and try again (see `wandb login --help` for more options)T)rY   viewerr   )rY   resr   r   r   check_logged_inB  s   
r  c                 C   s.   |  dd }tdd|}|d d }|S )Nrl   -z
[^a-z\.\-]r       )r   r   rN   rO   )rx   respr   r   r   make_name_dns_safeS  s   r  log	image_urijob_trackerr   c                 C   sf   t | }|r/d|d d| d}t| |d ur1|j|dd}||jdd| d S d S d S )	Nz*Failed to install the following packages: r   z for image: z,. Will attempt to launch image without them.zfailed-packages.logr   z>Some packages were not successfully installed during the buildbuild)	FAILED_PACKAGES_REGEXsearchgrouprh   ru   saversave_contentsupdate_run_queue_item_warningrun_queue_item_id)r  r  rY   r  r>   _msgr  r   r   r   $warn_failed_packages_from_build_logs[  s    

r%  Fshould_raisec              
   C   sb   t d ztddd| g W dS  tjtfy0 } z|r |t d W Y d}~dS d}~ww )	zsCheck if a specific image is already available.

    Optionally raises an exception if the image is not found.
    z Checking if base image exists...r   imageinspectTz/Base image not found. Generating new base imageNF)r   r   r   runDockerErrorr   )ry   r&  r.   r   r   r   docker_image_existsn  s   

r+  c              
   C   s@   zt dd| g W dS  t jy } ztd| d}~ww )z Pull the requested docker image.r   pullzDocker server returned error: N)r   r)  r*  r   )ry   r.   r   r   r   pull_docker_image~  s   r-  originalsub_dictc                    s   t  fdd| S )a  Substitute macros in a string.

    Macros occur in the string in the ${macro} format. The macro names are
    substituted with their values from the given dictionary. If a macro
    is not found in the dictionary, it is left unchanged.

    Args:
        original: The string to substitute macros in.
        sub_dict: A dictionary mapping macro names to their values.

    Returns:
        The string with the macros substituted.
    c                    s   t  | d| dS )Nr   r   )rM   r$   r  )r>   r/  r   r   r     s    zmacro_sub.<locals>.<lambda>)MACRO_REGEXrO   )r.  r/  r   r0  r   	macro_sub  s   r2  r   c                    sT   t | tr
t|  S t | tr fdd| D S t | tr( fdd|  D S | S )a  Recursively substitute macros in a parsed JSON or YAML blob.

    Macros occur in strings at leaves of the blob in the ${macro} format.
    The macro names are substituted with their values from the given dictionary.
    If a macro is not found in the dictionary, it is left unchanged.

    Arguments:
        source: The JSON or YAML blob to substitute macros in.
        sub_dict: A dictionary mapping macro names to their values.

    Returns:
        The blob with the macros substituted.
    c                    s   g | ]}t | qS r   recursive_macro_sub)r   r   r0  r   r   
<listcomp>  s    z'recursive_macro_sub.<locals>.<listcomp>c                    s   i | ]
\}}|t | qS r   r3  )r   keyvaluer0  r   r   
<dictcomp>  s    z'recursive_macro_sub.<locals>.<dictcomp>)r   rM   r2  r   r   r   )r   r/  r   r0  r   r4    s   




r4  runqueuefieldsc              
   C   s   i }i }| j D ]}t|d ||d < q|D ]]}|d}t|dkr+td| |\}}||vr?td| j d| d||i }	|	d	}
z|
d
krTt|}n|
dkr\t	|}W n t
yo   td| d|
 dw |||< q|S )Nschemarx   =   zL--set-var value must be in the format "--set-var key1=value1", instead got: zQueue z does not support overriding .typeintegernumberz
Value for z must be of type )rt   r%   r&   rU   rV   r   rx   r$   intfloatr   )r9  r:  rt   variable_schemastvfieldfield_partsr6  valr;  
field_typer   r   r   %fetch_and_validate_template_variables  s8   




rJ  
entrypointc                 C   sD   | sdS | d  ds| d  dr| d S t| dk rdS | d S )zGet the entrypoint file from the given command.

    Args:
        entrypoint (List[str]): List of command and arguments.

    Returns:
        Optional[str]: The entrypoint file if found, otherwise None.
    Nr   r   z.shr=  r   )endswithrV   )rK  r   r   r   get_entrypoint_file  s   	rM  c                  C   sJ   t j d d} | d }t| dkrd| d d n|d }||fS )Nr   r>  r=  z.0)re   r|   rU   rV   r   )full_versionmajorr|   r   r   r   get_current_python_version  s   &rP  r3   )r   )F)mr4   r%   loggingr"   rc   rN   r   re   collectionsr   typingr   r   r   r   r   r   r	   clickrh   wandb.dockerr   r
   wandb.apis.internalr   wandb.sdk.launch.errorsr   wandb.sdk.launch.git_referencer    wandb.sdk.launch.wandb_referencer   wandb.sdk.wandb_configr   "builder.templates._wandb_bootstrapr   r   compileescaper  )wandb.sdk.launch.agent.job_status_trackerr   rI   _VALID_IP_REGEXr   _VALID_WANDB_REGEXr   r=   rA   r?   r@   rP   r1  "AZURE_CONTAINER_REGISTRY_URI_REGEX$ELASTIC_CONTAINER_REGISTRY_URI_REGEX
IGNORECASEGCP_ARTIFACT_REGISTRY_URI_REGEX	S3_URI_RE
GCS_URI_REAZURE_BLOB_REGEXARN_PARTITION_REPROJECT_SYNCHRONOUSLAUNCH_CONFIG_FILELAUNCH_DEFAULT_PROJECT	getLogger__name__r   stylerj   r   rM   rB  __annotations__CODE_MOUNT_DIRr/   r;   rE   rC   rF   rH   rJ   rQ   rX   ro   rb   rw   r   r   r^   r   r   r   r   r   r   r   r   r  r  r  r  r%  r+  r-  r2  r4  r   rJ  rM  rP  r   r   r   r   <module>   s  
 $




$	
!
	


S
	
&9
"





)

""

"