Hub Python Library documentation

Quản lý Space của bạn

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Quản lý Space của bạn

Trong hướng dẫn này, chúng ta sẽ xem cách quản lý môi trường chạy Space của bạn (secrets, hardware và volumes) bằng huggingface_hub.

Tìm kiếm Spaces

Bạn có thể tìm kiếm Spaces trên Hub bằng cách tìm kiếm ngữ nghĩa với search_spaces(). Phương pháp này sử dụng tìm kiếm dựa trên embedding cho các truy vấn nhiều từ và tìm kiếm toàn văn cho các truy vấn một từ.

>>> from huggingface_hub import search_spaces
>>> results = list(search_spaces("generate image"))
>>> results[0]
SpaceSearchResult(id='mrfakename/Z-Image-Turbo', title='Z Image Turbo', sdk='gradio', likes=2867, ...)

Bạn có thể lọc kết quả theo SDK hoặc thẻ:

>>> results = search_spaces("chatbot", sdk="gradio", filter="mcp-server")

Hoặc qua CLI:

>>> hf spaces search "generate image"
>>> hf spaces search "chatbot" --sdk gradio --limit 5

Một ví dụ đơn giản: cấu hình bí mật và phần cứng.

Dưới đây là một ví dụ đầu-cuối để tạo và thiết lập một Space trên Hub.

Tạo một Space trên Hub

>>> from huggingface_hub import HfApi
>>> repo_id = "Wauplin/my-cool-training-space"
>>> api = HfApi()

# For example with a Gradio SDK
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="gradio")

Static Spaces miễn phí cho tất cả mọi người. Gradio và Docker Spaces chạy trên compute: trên phần cứng cpu-basic miễn phí, chúng yêu cầu một gói đăng ký (PRO cho người dùng, Team hoặc Enterprise cho tổ chức), trong khi phần cứng trả phí chỉ yêu cầu thanh toán (phương thức thanh toán và tín dụng trả trước). Nếu không có gói đăng ký, việc tạo, nhân bản hoặc di chuyển một Gradio hoặc Docker Space trên cpu-basic sẽ thất bại với lỗi thanh toán (HTTP 402). Xem pricing để biết thêm chi tiết.

Tạo một Space từ một mẫu

Thay vì bắt đầu từ một Space trống, bạn có thể khởi tạo một Space mới từ một trong các mẫu chính thức có sẵn trên Hub (ví dụ: JupyterLab, chatbot Gradio, ứng dụng Streamlit, v.v.). Liệt kê các mẫu khả dụng bằng list_space_templates(), sau đó truyền repo_id (hoặc name rút gọn) của mẫu đó vào space_template của create_repo(). Lưu ý rằng space_sdk vẫn là bắt buộc: mẫu sẽ khởi tạo các tệp trong khi SDK thiết lập metadata của card.

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# List available templates
>>> for template in api.list_space_templates():
...     print(f"{template.name} ({template.repo_id})")
Streamlit (streamlit/streamlit-template-space)
JupyterLab (SpacesExamples/jupyterlab)
chatbot (gradio-templates/chatbot)
...

# Create a Space from a template, by repo id or by short name
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="SpacesExamples/jupyterlab")
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="JupyterLab")

Một số template được khuyến nghị để ở chế độ riêng tư (ví dụ: JupyterLab). Nếu bạn không đặt rõ mức độ hiển thị, các Spaces như vậy sẽ tự động được tạo ở chế độ riêng tư.

Từ CLI, các tính năng tương tự có sẵn thông qua hf spaces templates và hf repos create --template:

# List available templates
>>> hf spaces templates
NAME            REPO_ID                                        SDK    PREFERRED_PRIVATE
--------------- ---------------------------------------------- ------ -----------------
Streamlit       streamlit/streamlit-template-space             docker
JupyterLab      SpacesExamples/jupyterlab                      docker ✔
Argilla         argilla/argilla-template-space                 docker
Livebook        livebook-dev/livebook                          docker
...

# Create a Space from a template
>>> hf repos create my-jupyterlab --type space --template jupyterlab

Nhân bản một Space

Điều này có thể hữu ích nếu bạn muốn xây dựng dựa trên một Space hiện có thay vì bắt đầu từ đầu. Nó cũng hữu ích nếu bạn muốn kiểm soát cấu hình/cài đặt của một Space công khai. Xem duplicate_repo() để biết thêm chi tiết.

>>> api.duplicate_repo("multimodalart/dreambooth-training", repo_type="space")

Tải mã của bạn lên bằng giải pháp bạn ưa thích

Dưới đây là một ví dụ để tải thư mục cục bộ src/ từ máy của bạn lên Space của bạn:

>>> api.upload_folder(repo_id=repo_id, repo_type="space", folder_path="src/")

Ở bước này, ứng dụng của bạn đã chạy trên Hub! Tuy nhiên, bạn có thể muốn cấu hình thêm với các bí mật (secrets) và phần cứng nâng cấp.

Cấu hình bí mật và biến

Space của bạn có thể cần một số khóa bí mật, token hoặc biến để hoạt động. Xem tài liệu để biết thêm chi tiết. Ví dụ, một token HF để tải lên Hub một bộ dữ liệu ảnh sau khi được tạo từ Space của bạn.

>>> api.add_space_secret(repo_id=repo_id, key="HF_TOKEN", value="hf_api_***")
>>> api.add_space_variable(repo_id=repo_id, key="MODEL_REPO_ID", value="user/repo")

Bạn có thể liệt kê các bí mật và biến hiện có. Giá trị bí mật chỉ có thể ghi, do đó chỉ các khóa, mô tả và dấu thời gian cập nhật được trả về:

>>> api.get_space_secrets(repo_id=repo_id)
{'HF_TOKEN': SpaceSecret(key='HF_TOKEN', description=None, updated_at=datetime.datetime(...))}
>>> api.get_space_variables(repo_id=repo_id)
{'MODEL_REPO_ID': SpaceVariable(key='MODEL_REPO_ID', value='user/repo', description=None, updated_at=...)}

Các bí mật và biến cũng có thể bị xóa:

>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")

Từ bên trong Space của bạn, các secret có sẵn dưới dạng biến môi trường (hoặc Streamlit Secrets Management nếu bạn đang dùng Streamlit). Không cần phải lấy chúng qua API!

Bất kỳ thay đổi nào trong cấu hình Space của bạn (secrets hoặc phần cứng) sẽ kích hoạt việc khởi động lại ứng dụng của bạn.

Phần thưởng: đặt secrets và variables khi tạo hoặc nhân bản Space!

Các bí mật và biến có thể được thiết lập khi tạo hoặc sao chép một space:

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )

Cấu hình phần cứng

Mặc định, Space của bạn chạy trên phần cứng cpu-basic miễn phí (đòi hỏi một gói đăng ký cho Gradio và Docker Spaces, xem ở trên). Bạn có thể nâng cấp phần cứng để chạy trên GPU. Cần có phương thức thanh toán và tín dụng trả trước (hoặc một khoản tài trợ cộng đồng) để nâng cấp Space của bạn. Xem tài liệu để biết thêm chi tiết.

# Use `SpaceHardware` enum
>>> from huggingface_hub import SpaceHardware
>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM)

# Or simply pass a string value
>>> api.request_space_hardware(repo_id=repo_id, hardware="t4-medium")

Việc cập nhật phần cứng không được thực hiện ngay lập tức vì Space của bạn phải được tải lại trên máy chủ của chúng tôi. Vào bất kỳ lúc nào, bạn có thể kiểm tra phần cứng mà Space của bạn đang chạy để xem yêu cầu của bạn đã được đáp ứng hay chưa.

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.stage
"RUNNING_BUILDING"
>>> runtime.hardware
"cpu-basic"
>>> runtime.requested_hardware
"t4-medium"

Bạn đã có một Space được cấu hình hoàn chỉnh. Hãy nhớ hạ cấp Space của bạn về cpu-basic khi bạn đã dùng xong.

Phần thưởng: yêu cầu phần cứng khi tạo hoặc sao chép Space!

Phần cứng nâng cấp sẽ được tự động gán cho Space của bạn sau khi nó được xây dựng.

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )

Theo dõi hạn mức ZeroGPU của bạn

ZeroGPU Spaces chạy trên các GPU dùng chung được cấp phát theo nhu cầu. Mỗi khi bạn sử dụng một ZeroGPU Space (từ giao diện người dùng hoặc thông qua API của nó), một phần thời gian GPU sẽ được trừ khỏi hạn mức cá nhân của bạn, và hạn mức này được đặt lại định kỳ. Nếu bạn đang xây dựng ứng dụng, tác tử hoặc máy chủ MCP trên nền tảng ZeroGPU Spaces, bạn có thể theo dõi mức sử dụng của mình bằng get_zero_gpu_quota(). Các giá trị được biểu diễn bằng giây GPU.

>>> quota = api.get_zero_gpu_quota()
>>> quota
ZeroGpuQuota(base=2400, remaining=1810, resets_at=datetime.datetime(2026, 9, 30, 9, 12, 3, tzinfo=datetime.timezone.utc), overquota_used=0)
>>> if quota.remaining < 60:
...     print(f"Less than 1 minute of ZeroGPU left. Quota resets at {quota.resets_at}.")

resets_at là None nếu bạn chưa sử dụng ZeroGPU kể từ lần reset gần nhất. Nếu bạn sử dụng token chi tiết, token đó phải có quyền “Billing > Read billing usage and payment method status”. Thông tin tương tự có thể xem từ CLI bằng hf spaces zero-gpu quota.

Khi hạn mức đã dùng hết, người dùng PRO, Team và Enterprise vẫn có thể tiếp tục sử dụng ZeroGPU Spaces bằng cách tiêu thụ các tín dụng đã trả trước. Bạn có thể mua tín dụng từ cài đặt thanh toán của mình. Xem Mở rộng hạn mức bằng tín dụng để biết thêm chi tiết.

Tạm dừng và khởi động lại Space của bạn

Mặc định, nếu Space của bạn đang chạy trên phần cứng nâng cấp, nó sẽ không bao giờ bị dừng. Tuy nhiên, để tránh bị tính phí, bạn có thể muốn tạm dừng nó khi không sử dụng. Điều này có thể thực hiện bằng pause_space(). Một Space ở trạng thái tạm dừng sẽ không hoạt động cho đến khi chủ sở hữu của Space khởi động lại nó, thông qua giao diện người dùng hoặc qua API bằng restart_space(). Để biết thêm chi tiết về chế độ tạm dừng, vui lòng tham khảo mục này

# Pause your Space to avoid getting billed
>>> api.pause_space(repo_id=repo_id)
# (...)
# Restart it when you need it
>>> api.restart_space(repo_id=repo_id)

Một khả năng khác là đặt thời gian chờ (timeout) cho Space của bạn. Nếu Space của bạn không hoạt động trong thời gian dài hơn thời gian chờ, nó sẽ chuyển sang trạng thái ngủ. Bất kỳ khách truy cập nào đến Space của bạn sẽ khởi động lại nó. Bạn có thể đặt thời gian chờ bằng cách sử dụng set_space_sleep_time(). Để biết thêm chi tiết về chế độ ngủ, vui lòng tham khảo mục này.

# Put your Space to sleep after 1h of inactivity
>>> api.set_space_sleep_time(repo_id=repo_id, sleep_time=3600)

Lưu ý: nếu bạn đang sử dụng phần cứng ‘cpu-basic’, bạn không thể cấu hình thời gian ngủ tùy chỉnh. Space của bạn sẽ tự động tạm dừng sau 48 giờ không hoạt động.

Phần thưởng: đặt thời gian ngủ khi yêu cầu phần cứng

Phần cứng nâng cấp sẽ được tự động gán cho Space của bạn sau khi nó được xây dựng.

>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM, sleep_time=3600)

Phần thưởng: đặt thời gian ngủ khi tạo hoặc nhân bản Space!

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )

Chẩn đoán Space bị lỗi bằng cách đọc nhật ký của nó

Khi một Space không thể build hoặc bị crash khi chạy, các log mà bạn thường xem trong trình duyệt cũng có thể truy cập theo cách lập trình thông qua fetch_space_logs(). Điều này đặc biệt hữu ích trong các script hoặc workflow dạng agentic, nơi việc mở trình duyệt không khả thi.

# Drain the currently available run logs and return immediately (like `docker logs`)
>>> for line in api.fetch_space_logs(repo_id=repo_id):
...     print(line, end="")

# Read the container build logs instead (useful when the Space is stuck in BUILD_ERROR)
>>> for line in api.fetch_space_logs(repo_id=repo_id, build=True):
...     print(line, end="")

# Stream run logs in real time until the server closes the stream (Ctrl-C to stop)
>>> for line in api.fetch_space_logs(repo_id=repo_id, follow=True):
...     print(line, end="")

Chức năng tương tự cũng có sẵn từ CLI:

hf spaces logs username/my-space             # drain run logs
hf spaces logs username/my-space --build     # read build logs
hf spaces logs username/my-space -f          # stream in real time
hf spaces logs username/my-space -n 50       # last 50 lines only

Truy cập Space qua SSH (Chế độ Dev)

Dev Mode cho phép bạn SSH vào container Space đang chạy để gỡ lỗi và phát triển trực tiếp. Sử dụng hf spaces ssh để mở phiên trực tiếp từ terminal. Nếu Dev Mode chưa được bật trên Space, CLI sẽ yêu cầu bạn bật nó (hoặc truyền --auto để bỏ qua lời nhắc).

Khóa công khai SSH của bạn phải được đăng ký tại cài đặt của bạn.

# SSH into a Space (enables Dev Mode if needed)
hf spaces ssh username/my-space

# Auto-enable Dev Mode without prompting
hf spaces ssh username/my-space --auto

# Print the SSH command without running it
hf spaces ssh username/my-space --dry-run

# Use a specific SSH key
hf spaces ssh username/my-space -i ~/.ssh/id_ed25519

Bạn cũng có thể bật Dev Mode mà không cần SSH bằng cách sử dụng hf spaces dev-mode, lệnh này sẽ in ra các hướng dẫn kết nối cho SSH, VS Code, Cursor và Windsurf:

hf spaces dev-mode username/my-space

Bật Dev Mode yêu cầu gói PRO hoặc Team & Enterprise. Việc tắt Dev Mode luôn được cho phép, chẳng hạn khi gói đăng ký của bạn đã hết hạn trong khi Dev Mode đang bật:

hf spaces dev-mode username/my-space --stop

Gắn các volume trong Space của bạn

Bạn có thể gắn các tài nguyên Hub (mô hình, bộ dữ liệu, hoặc bucket lưu trữ) dưới dạng volume trong container của Space. Điều này cho phép Space của bạn truy cập trực tiếp vào hệ thống tệp của các tài nguyên này mà không cần phải tải chúng xuống trong mã của bạn. Volume có thể được thiết lập trực tiếp khi tạo hoặc nhân bản một Space:

>>> from huggingface_hub import Volume
>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )

Bạn có thể kiểm tra các volume đang được gắn qua Space runtime:

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.volumes
[Volume(type='model', source='username/my-model', mount_path='/models', read_only=True), ...]

Nếu bạn cần cập nhật các volume trên một Space hiện có, hãy sử dụng set_space_volumes(). Lưu ý rằng thao tác này sẽ thay thế tất cả các volume đã được gắn trước đó.

>>> api.set_space_volumes(
...     repo_id=repo_id,
...     volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="dataset", source="username/my-dataset", mount_path="/data", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/output"),
...     ],
... )

Để xóa tất cả các volume khỏi Space của bạn:

>>> api.delete_space_volumes(repo_id=repo_id)

Các mô hình, bộ dữ liệu và Spaces luôn được gắn (mount) ở chế độ chỉ đọc. Chỉ có các bucket lưu trữ mới hỗ trợ gắn ở chế độ đọc-ghi.

Việc thiết lập các volume sẽ thay thế các volume đã được gắn trước đó. Để thêm một volume vào danh sách hiện có, trước tiên hãy đọc các volume hiện tại từ runtime và bao gồm chúng trong danh sách mới.

Tất cả các thao tác với volume cũng có sẵn từ CLI:

# List current volumes
hf spaces volumes ls username/my-space

# Set (replace) volumes
hf spaces volumes set username/my-space \
    -v hf://models/username/my-model:/models \
    -v hf://buckets/username/my-bucket:/data

# Remove all volumes
hf spaces volumes delete username/my-space

Nâng cao hơn: tạm thời nâng cấp Space của bạn!

Spaces cho phép rất nhiều trường hợp sử dụng khác nhau. Đôi khi, bạn có thể muốn chạy tạm thời một Space trên phần cứng cụ thể, thực hiện một tác vụ rồi tắt nó đi. Trong phần này, chúng ta sẽ tìm hiểu cách tận dụng Spaces để tinh chỉnh (finetune) một mô hình theo yêu cầu. Đây chỉ là một cách để giải quyết vấn đề cụ thể này. Bạn nên xem đây như một gợi ý và điều chỉnh cho phù hợp với trường hợp sử dụng của mình.

Giả sử chúng ta có một Space để tinh chỉnh (finetune) một mô hình. Đây là một ứng dụng Gradio nhận vào một model id và một dataset id. Quy trình làm việc như sau:

  1. (Đề nghị người dùng nhập một mô hình và một bộ dữ liệu)
  2. Tải mô hình từ Hub.
  3. Tải bộ dữ liệu từ Hub.
  4. Huấn luyện lại mô hình trên bộ dữ liệu.
  5. Tải lên mô hình mới lên Hub.

Bước 3. yêu cầu phần cứng tùy chỉnh nhưng bạn không muốn Space của mình chạy liên tục trên GPU trả phí. Một giải pháp là yêu cầu phần cứng một cách động cho quá trình huấn luyện và tắt nó đi sau đó. Vì việc yêu cầu phần cứng sẽ khởi động lại Space của bạn, ứng dụng của bạn phải có cách nào đó để “nhớ” tác vụ hiện tại mà nó đang thực hiện. Có nhiều cách để làm điều này. Trong hướng dẫn này, chúng ta sẽ xem xét một giải pháp sử dụng Dataset như “bộ lập lịch tác vụ”.

Khung ứng dụng

Dưới đây là cách ứng dụng của bạn sẽ hoạt động. Khi khởi động, kiểm tra xem có tác vụ nào được lên lịch hay không, và nếu có, chạy nó trên phần cứng phù hợp. Khi hoàn tất, đặt lại phần cứng về CPU cpu-basic trống và yêu cầu người dùng nhập tác vụ mới.

Quy trình làm việc như vậy không hỗ trợ truy cập đồng thời như các demo thông thường. Cụ thể, giao diện sẽ bị vô hiệu hóa khi quá trình huấn luyện diễn ra. Tốt nhất nên đặt kho của bạn ở chế độ riêng tư để đảm bảo bạn là người dùng duy nhất.

# Space will need your token to request hardware: set it as a Secret !
HF_TOKEN = os.environ.get("HF_TOKEN")

# Space own repo_id
TRAINING_SPACE_ID = "Wauplin/dreambooth-training"

from huggingface_hub import HfApi, SpaceHardware
api = HfApi(token=HF_TOKEN)

# On Space startup, check if a task is scheduled. If yes, finetune the model. If not,
# display an interface to request a new task.
task = get_task()
if task is None:
    # Start Gradio app
    def gradio_fn(task):
        # On user request, add task and request hardware
        add_task(task)
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

    gr.Interface(fn=gradio_fn, ...).launch()
else:
    runtime = api.get_space_runtime(repo_id=TRAINING_SPACE_ID)
    # Check if Space is loaded with a GPU.
    if runtime.hardware == SpaceHardware.T4_MEDIUM:
        # If yes, finetune base model on dataset !
        train_and_upload(task)

        # Then, mark the task as "DONE"
        mark_as_done(task)

        # DO NOT FORGET: set back CPU hardware
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.CPU_BASIC)
    else:
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

Trình lập lịch tác vụ

Việc lập lịch các tác vụ có thể được thực hiện theo nhiều cách. Dưới đây là một ví dụ về cách thực hiện bằng cách sử dụng một tệp CSV đơn giản được lưu dưới dạng Dataset.

# Dataset ID in which a `tasks.csv` file contains the tasks to perform.
# Here is a basic example for `tasks.csv` containing inputs (base model and dataset)
# and status (PENDING or DONE).
#     multimodalart/sd-fine-tunable,Wauplin/concept-1,DONE
#     multimodalart/sd-fine-tunable,Wauplin/concept-2,PENDING
TASK_DATASET_ID = "Wauplin/dreambooth-task-scheduler"

def _get_csv_file():
    return hf_hub_download(repo_id=TASK_DATASET_ID, filename="tasks.csv", repo_type="dataset", token=HF_TOKEN)

def get_task():
    with open(_get_csv_file()) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        for row in csv_reader:
            if row[2] == "PENDING":
                return row[0], row[1] # model_id, dataset_id

def add_task(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to add a task
        path_or_fileobj=(tasks + f"\n{model_id},{dataset_id},PENDING").encode()
    )

def mark_as_done(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to set the task as DONE
        path_or_fileobj=tasks.replace(
            f"{model_id},{dataset_id},PENDING",
            f"{model_id},{dataset_id},DONE"
        ).encode()
    )
Update on GitHub