U
    Ód¨iƒ*  ã                
   @   sH  d dl mZ d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ G dd	„ d	eeƒZeG d
d„ dƒƒZeG dd„ dƒƒZeG dd„ dƒƒZeG dd„ dƒƒZeG dd„ dƒƒZeG dd„ dƒƒZeG dd„ dƒƒZeee e	eeef  e	eeef  e	e e	e
eeef  eeef dœdd„ZdS )é    )Ú	dataclass)Údatetime)ÚEnum)ÚAnyÚDictÚListÚOptionalÚUnion)Ú	constants)ÚSpaceHardware)Úparse_datetimec                   @   s$   e Zd ZdZdZdZdZdZdZdS )ÚJobStageah  
    Enumeration of possible stage of a Job on the Hub.

    Value can be compared to a string:
    ```py
    assert JobStage.COMPLETED == "COMPLETED"
    ```
    Possible values are: `COMPLETED`, `CANCELED`, `ERROR`, `DELETED`, `RUNNING`.
    Taken from https://github.com/huggingface/moon-landing/blob/main/server/job_types/JobInfo.ts#L61 (private url).
    Ú	COMPLETEDÚCANCELEDÚERRORÚDELETEDÚRUNNINGN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   © r   r   ú=/tmp/pip-unpacked-wheel-ohruig0i/huggingface_hub/_jobs_api.pyr      s   r   c                   @   s"   e Zd ZU eed< ee ed< dS )Ú	JobStatusÚstageÚmessageN)r   r   r   r   Ú__annotations__r   Ústrr   r   r   r   r   -   s   
r   c                   @   s&   e Zd ZU eed< eed< eed< dS )ÚJobOwnerÚidÚnameÚtypeN)r   r   r   r   r   r   r   r   r   r   3   s   
r   c                   @   sÀ   e Zd ZU dZeed< ee ed< ee ed< ee ed< eee  ed< eee  ed< ee	ee
f  ed< ee	ee
f  ed	< ee ed
< eed< eed< eed< eed< ddœdd„ZdS )ÚJobInfoa&	  
    Contains information about a Job.

    Args:
        id (`str`):
            Job ID.
        created_at (`datetime` or `None`):
            When the Job was created.
        docker_image (`str` or `None`):
            The Docker image from Docker Hub used for the Job.
            Can be None if space_id is present instead.
        space_id (`str` or `None`):
            The Docker image from Hugging Face Spaces used for the Job.
            Can be None if docker_image is present instead.
        command (`List[str]` or `None`):
            Command of the Job, e.g. `["python", "-c", "print('hello world')"]`
        arguments (`List[str]` or `None`):
            Arguments passed to the command
        environment (`Dict[str]` or `None`):
            Environment variables of the Job as a dictionary.
        secrets (`Dict[str]` or `None`):
            Secret environment variables of the Job (encrypted).
        flavor (`str` or `None`):
            Flavor for the hardware, as in Hugging Face Spaces. See [`SpaceHardware`] for possible values.
            E.g. `"cpu-basic"`.
        status: (`JobStatus` or `None`):
            Status of the Job, e.g. `JobStatus(stage="RUNNING", message=None)`
            See [`JobStage`] for possible stage values.
        owner: (`JobOwner` or `None`):
            Owner of the Job, e.g. `JobOwner(id="5e9ecfc04957053f60648a3e", name="lhoestq", type="user")`

    Example:

    ```python
    >>> from huggingface_hub import run_job
    >>> job = run_job(
    ...     image="python:3.12",
    ...     command=["python", "-c", "print('Hello from the cloud!')"]
    ... )
    >>> job
    JobInfo(id='687fb701029421ae5549d998', created_at=datetime.datetime(2025, 7, 22, 16, 6, 25, 79000, tzinfo=datetime.timezone.utc), docker_image='python:3.12', space_id=None, command=['python', '-c', "print('Hello from the cloud!')"], arguments=[], environment={}, secrets={}, flavor='cpu-basic', status=JobStatus(stage='RUNNING', message=None), owner=JobOwner(id='5e9ecfc04957053f60648a3e', name='lhoestq', type='user'), endpoint='https://huggingface.co', url='https://huggingface.co/jobs/lhoestq/687fb701029421ae5549d998')
    >>> job.id
    '687fb701029421ae5549d998'
    >>> job.url
    'https://huggingface.co/jobs/lhoestq/687fb701029421ae5549d998'
    >>> job.status.stage
    'RUNNING'
    ```
    r   Ú
created_atÚdocker_imageÚspace_idÚcommandÚ	argumentsÚenvironmentÚsecretsÚflavorÚstatusÚownerÚendpointÚurlN©Úreturnc                 K   s  |d | _ | d¡p| d¡}|r*t|ƒnd | _| d¡pB| d¡| _| d¡pX| d¡| _| di ¡}t|d |d	 |d
 d| _| d¡| _| d¡| _	| d¡| _
| d¡| _| d¡| _| di ¡}t|d | d¡d| _| dtj¡| _| j› d| jj› d| j › | _d S )Nr   Ú	createdAtr#   ÚdockerImager$   ÚspaceIdr%   r,   r    r!   ©r   r    r!   r&   r'   r(   r)   r*   r+   r   r   )r   r   r-   z/jobs/ú/)r   Úgetr   r#   r$   r%   r   r,   r&   r'   r(   r)   r*   r   r+   r
   ZENDPOINTr-   r    r.   )ÚselfÚkwargsr#   r,   r+   r   r   r   Ú__init__~   s     
zJobInfo.__init__)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r9   r   r   r   r   r"   :   s   
2r"   c                   @   s°   e Zd ZU ee ed< ee ed< eee  ed< eee  ed< eeeef  ed< eeeef  ed< ee	 ed< ee
 ed< eee  ed	< ee ed
< ddœdd„ZdS )ÚJobSpecr$   r%   r&   r'   r(   r)   r*   ÚtimeoutÚtagsÚarchNr/   c                 K   s   |  d¡p|  d¡| _|  d¡p(|  d¡| _|  d¡| _|  d¡| _|  d¡| _|  d¡| _|  d	¡| _|  d
¡| _|  d¡| _	|  d¡| _
d S )Nr2   r$   r3   r%   r&   r'   r(   r)   r*   r;   r<   r=   )r6   r$   r%   r&   r'   r(   r)   r*   r;   r<   r=   ©r7   r8   r   r   r   r9       s    zJobSpec.__init__)r   r   r   r   r   r   r   r   r   r   Úintr9   r   r   r   r   r:   “   s   
r:   c                   @   s,   e Zd ZU eed< eed< ddœdd„ZdS )ÚLastJobInfor   ÚatNr/   c                 K   s   |d | _ t|d ƒ| _d S )Nr   rA   )r   r   rA   r>   r   r   r   r9   ²   s    
zLastJobInfo.__init__)r   r   r   r   r   r   r9   r   r   r   r   r@   ­   s   
r@   c                   @   s4   e Zd ZU ee ed< ee ed< ddœdd„ZdS )ÚScheduledJobStatusÚlast_jobÚnext_job_run_atNr/   c                 K   sV   |  d¡p|  d¡}|r"tf |Žnd | _|  d¡p:|  d¡}|rLtt|ƒƒnd | _d S )NÚlastJobrC   ÚnextJobRunAtrD   )r6   r@   rC   r   r   rD   )r7   r8   rC   rD   r   r   r   r9   ¼   s    zScheduledJobStatus.__init__)r   r   r   r   r@   r   r   r9   r   r   r   r   rB   ·   s   
rB   c                   @   sp   e Zd ZU dZeed< ee ed< eed< ee ed< ee	 ed< ee	 ed< e
ed< eed	< d
dœdd„Zd
S )ÚScheduledJobInfoaÅ  
    Contains information about a Job.

    Args:
        id (`str`):
            Scheduled Job ID.
        created_at (`datetime` or `None`):
            When the scheduled Job was created.
        tags (`List[str]` or `None`):
            The tags of the scheduled Job.
        schedule (`str` or `None`):
            One of "@annually", "@yearly", "@monthly", "@weekly", "@daily", "@hourly", or a
            CRON schedule expression (e.g., '0 9 * * 1' for 9 AM every Monday).
        suspend (`bool` or `None`):
            Whether the scheduled job is suspended (paused).
        concurrency (`bool` or `None`):
            Whether multiple instances of this Job can run concurrently.
        status (`ScheduledJobStatus` or `None`):
            Status of the scheduled Job.
        owner: (`JobOwner` or `None`):
            Owner of the scheduled Job, e.g. `JobOwner(id="5e9ecfc04957053f60648a3e", name="lhoestq", type="user")`
        job_spec: (`JobSpec` or `None`):
            Specifications of the Job.

    Example:

    ```python
    >>> from huggingface_hub import run_job
    >>> scheduled_job = create_scheduled_job(
    ...     image="python:3.12",
    ...     command=["python", "-c", "print('Hello from the cloud!')"],
    ...     schedule="@hourly",
    ... )
    >>> scheduled_job.id
    '687fb701029421ae5549d999'
    >>> scheduled_job.status.next_job_run_at
    datetime.datetime(2025, 7, 22, 17, 6, 25, 79000, tzinfo=datetime.timezone.utc)
    ```
    r   r#   Újob_specÚscheduleÚsuspendÚconcurrencyr+   r,   Nr/   c                 K   sØ   |d | _ | d¡p| d¡}|r*t|ƒnd | _tf | d¡pH| di ¡Ž| _| d¡| _| d¡| _| d¡| _| d	i ¡}t	| d
¡p’| d¡| d¡p¤| d¡d| _
| di ¡}t|d |d |d d| _d S )Nr   r1   r#   rH   ZjobSpecrI   rJ   rK   r+   rC   rE   rD   rF   )rC   rD   r,   r    r!   r4   )r   r6   r   r#   r:   rH   rI   rJ   rK   rB   r+   r   r,   )r7   r8   r#   r+   r,   r   r   r   r9   ö   s    
þzScheduledJobInfo.__init__)r   r   r   r   r   r   r   r   r:   ÚboolrB   r   r9   r   r   r   r   rG   Ã   s   
(rG   )Úimager&   Úenvr)   r*   r;   r0   c           	      C   s¶   |g |p
i |pt jdœ}|r$||d< |r~dddddœ}t|tƒrr|d |krrtt|d d… ƒ||d   ƒ|d	< nt|ƒ|d	< d
D ]&}|  |¡r‚| t|ƒd … |d<  q²q‚| |d< |S )N)r&   r'   r(   r*   r)   é   é<   i  i€Q )ÚsÚmÚhÚdéÿÿÿÿZtimeoutSeconds)zhttps://huggingface.co/spaces/zhttps://hf.co/spaces/zhuggingface.co/spaces/zhf.co/spaces/r3   r2   )r   Z	CPU_BASICÚ
isinstancer   r?   ÚfloatÚ
startswithÚlen)	rM   r&   rN   r)   r*   r;   rH   Ztime_units_factorsÚprefixr   r   r   Ú_create_job_spec  s$    ü&
r[   N)Zdataclassesr   r   Úenumr   Útypingr   r   r   r   r	   Zhuggingface_hubr
   Zhuggingface_hub._space_apir   Zhuggingface_hub.utils._datetimer   r   r   r   r   r"   r:   r@   rB   rG   r?   rW   r[   r   r   r   r   Ú<module>   s:   X	E
ø