Hỏi về Upload tập tin có kích thước lớn sử dụng request trong Python

Mình có đoạn code sau dùng để Upload file Video lên DooStream :heart_eyes:

import requests
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
import os, time
import json
def Upload_to_DooStream(list_files,api_key):
    #list_results=[]
    extensions_video_file = ['.mp4','.flv','.h264','.avi','.mkv','.mpeg','.mpg','.mov','.m4v','.3gp','.wmv','.vob']
    list_path_video = [s for s in list_files if any(xs in s for xs in extensions_video_file)]
     
    # list all the files from a given path
    #files_to_upload = os.listdir(file_path)
    # tqdm is used as a context manager
    with tqdm(total=len(list_path_video), desc="Uploading", initial=0, unit_scale=True, colour='green') as bar:
        with ThreadPoolExecutor(max_workers=20) as executor:
            for path_video in list_path_video:
               
                with open((path_video), 'rb') as f:
                    files = {'file': (path_video, f.read())}
                
                    url=('https://doodapi.com/api/upload/server?key='+api_key)
                    r=requests.get(url).text
                    y = json.loads(r)
                    upload_url= (y["result"])
                    url=(upload_url+'?'+api_key)
                   
                    data = {
                    "api_key": api_key
                             }
                    futures = executor.submit(requests.post,
                                              url=url,data=data,files=files)
                    if as_completed(futures):
                        pbar.update(1)
                        time.sleep(0.02)
    #return list_results
Upload_to_DooStream(["D:\Project\AutoLazy\FC2-PPV-2539191\[email protected]","D:\Project\AutoLazy\REBD-615\[email protected]"],"83898e7z7wd2f0nv0jb60")

Vấn đề của em nó là khi mình upload các file nhỏ nhỏ tầm vài chục MB thì OK nhưng khi upload file hơn 1GB trở lên thì máy Client bị đơ, giật và phải reset lại .
Mọi người có biết cách nào để giải quyết lỗi này không ạ
Full source code mọi người có thể tìm ở đây : https://github.com/Kulteam/Downloader-For-The-Lazy/blob/main/main.py

Thanks anh em nhiều !

Máy đơ/ giật là máy nào? Client hay server?

3 Likes

Máy mình bạn ạ …Tức là client ý…mình đã update lại

Muốn upload file lớn thì cần upload từng đoạn nhỏ của file đó lên. Bạn có thể dùng header Content-Length để cho server biết client đang upload đoạn nặng bao nhiêu, và Content-Range cho biết đang upload chỗ nào trong file

5 Likes

Có vẻ như vấn đề ở đây, requests.post hỗ trợ streaming upload qua kwarg: data=, nhưng bạn phải upload dưới dạng Multipart-Encoded nên nội dung file của bạn phải được tải vào RAM, bạn có thể thử xem Python process chiếm bao nhiêu dung lượng RAM trong quá trình tải file qua process manager.

Đây là issue được tạo từ library requests, đa phần câu trả lời là sử dụng 3rd party library requests_toolbelt

7 Likes

multi thread + đọc file lớn vào RAM = combo hủy diệt máy tính. Máy bạn chỉ chậm mà chưa ngỏm cũng là khá lắm rồi

6 Likes

Thanks bạn nhé…

Thanks tất cả mọi người …Để mình fix lại code

Thanks bạn nhé…Mình đã thử và thành công

Code cho bạn nào cần

def Upload_to_DooStream(list_files,api_key):
    list_results=[]
    extensions_video_file = ['.mp4','.flv','.h264','.avi','.mkv','.mpeg','.mpg','.mov','.m4v','.3gp','.wmv','.vob']
    list_path_video = [s for s in list_files if any(xs in s for xs in extensions_video_file)]
    for path_video in list_path_video:
        path = Path(path_video)
        total_size = path.stat().st_size
        filename = path.name

         with tqdm(
             desc=filename,
             total=total_size,
             unit="B",
             unit_scale=True,
             unit_divisor=1024,
        ) as bar:
            with open(path_video, "rb") as f:
                fields["file"] = (path_video, f)
                e = MultipartEncoder(fields=fields)
                m = MultipartEncoderMonitor(
                    e, lambda monitor: bar.update(monitor.bytes_read - bar.n)
                )
                headers = {"Content-Type": m.content_type}
                url=('https://doodapi.com/api/upload/server?key='+api_key)
                r=requests.get(url).text
                y = json.loads(r)
                server_upload= (y["result"])
                upload_url=(server_upload+'?'+api_key)
                response=requests.post(upload_url, data=m, headers=headers)
                link_embed=json.loads(response.text)
        
                print(link_embed["result"])
                list_results.append(link_embed["result"])
    return list_results
2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?