ivknv/yadisk

Скорость загрузки файла с ПК

Pacifist2503 opened this issue · 9 comments

Добрый день!

Скорость загрузки 14 мб .mp3 составляет около 2 минут
Тот же файл в браузере грузится за доли сек
Это особенности api или я что-то не учел?
Спасибо!

ivknv commented

Если вы под Windows, это может быть баг стандартной библиотеки (urllib3 issue #1394, Python Issue33838), из-за которого скорость загрузки в некоторых случаях значительно ниже под Windows.
Вы можете попробовать залить файл при помощи yadisk-async (API почти такой же) и сравнить скорость загрузки, там этой проблемы нет, т.к. aiohttp не использует http.client.

ivknv commented

Проблему можно обойти, пропатчив http.client и urllib3:

def patch_http_client_blocksize():
    """Increases default blocksize for http.client.HTTPConnection"""

    import http.client

    original_init = http.client.HTTPConnection.__init__

    def init_patched(self, *args, **kwargs):
        kwargs.setdefault("blocksize", 2 * 1024**2)
        original_init(self, *args, **kwargs)

    http.client.HTTPConnection.__init__ = init_patched

def patch_urllib3_blocksize():
    """Increases default blocksize for urllib3's HTTPConnection"""

    import urllib3

    original_init = urllib3.connection.HTTPConnection.__init__

    def init_patched(self, *args, **kwargs):
        kwargs.setdefault("blocksize", 2 * 1024**2)
        original_init(self, *args, **kwargs)

    urllib3.connection.HTTPConnection.__init__ = init_patched

# Should be done before imports of these modules
patch_http_client_blocksize()
patch_urllib3_blocksize()

Приведенный кусок кода нужно выполнить до импорта yadisk и requests. Более детальное описание, почему это работает, я привел в том issue urllib3.

Спасибо!!
А если использовать api яндекса и requests способ тот же?

def patch_http_client_blocksize():
    """Increases default blocksize for http.client.HTTPConnection"""

    import http.client

    original_init = http.client.HTTPConnection.__init__

    def init_patched(self, *args, **kwargs):
        kwargs.setdefault("blocksize", 2 * 1024**2)
        original_init(self, *args, **kwargs)

    http.client.HTTPConnection.__init__ = init_patched

def patch_urllib3_blocksize():
    """Increases default blocksize for urllib3's HTTPConnection"""

    import urllib3

    original_init = urllib3.connection.HTTPConnection.__init__

    def init_patched(self, *args, **kwargs):
        kwargs.setdefault("blocksize", 2 * 1024**2)
        original_init(self, *args, **kwargs)

    urllib3.connection.HTTPConnection.__init__ = init_patched

# Should be done before imports of these modules
patch_http_client_blocksize()
patch_urllib3_blocksize()

import requests
from datetime import datetime

URL = 'https://cloud-api.yandex.net/v1/disk/resources'
TOKEN = ''
headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': f'OAuth {TOKEN}'}

path_p = '123'
path_f = r'C:/Users/fire-/Desktop/1/11.mp4'


def upload_file(loadfile, savefile, replace=False):
    """Загрузка файла.
    savefile: Путь к файлу на Диске
    loadfile: Путь к загружаемому файлу
    replace: true or false Замена файла на Диске"""
    start = datetime.now()
    res_url = requests.get(f'{URL}/upload?path={savefile}&overwrite={replace}', headers=headers).json()
    with open(loadfile, 'rb') as f:
        try:
            res_load_file = requests.put(res_url['href'], files={'file': f})
            if res_load_file.status_code == 201:
                print(f'Загрузка файла {f.name} завершена, затрачено времени: {datetime.now() - start}')
        except KeyError:
            print(f'{res_url=}')


if __name__ == '__main__':
    name = path_f.split('/')[-1]
    upload_file(path_f, f'/{name}')

Такое не работает (

ivknv commented

Что именно не работает? Я попробовал запустить ваш код, у меня все нормально загрузилось, с нормальной скоростью. Единственное, что GET параметры подставлять напрямую в URL - плохая идея, лучше передавать их через params.

Загрузка файла с патчем, затрачено времени: 0:02:23.403436 - попытка 1
Загрузка файла без патча, затрачено времени: 0:02:01.080888
Загрузка файла c патчем, затрачено времени: 0:02:09.742823 - попытка 2
Из браузера загрузка фала 15.2 мб практически мгновенно

ivknv commented

Кажется, это другая проблема. У Яндекс.Диска в последнее время какие-то проблемы с загрузкой файлов с определенными расширениями. На данный момент на Диск через REST API (в браузере всё в порядке) файлы грузятся до боли медленно (у меня вообще терпения не хватает, чтобы дождаться до конца). Проблему можно обойти только если указывать другое расширение файла, как бы глупо это не звучало.

По неизвестным причинам не грузятся: *.db, *.zip и *.mp4 файлы (скорее всего и некоторые другие).
Эта проблема самого Яндекс.Диска, она не связана с этой библиотекой, такой же результат можно получить и через CURL.

Совсем недавно у другого человека была такая же проблема, но только с async-версией: yadisk-async issue #3

На данный момент проблема со скоростью загрузки файлов НА яндекс диск актуальна. Не знаю с какими конкретно расширениями, но видео .avi размером 500МБ у меня грузилось 48 минут 👎 👎 👎

Убрал расширение из названия и все ок, загрузилось как в браузере за 30 сек
пи.си. автору респект

Я нашёл ссылку, где человек эксперимент с разными расширениями провёл
https://python.su/forum/topic/40819/

ivknv commented

В документации теперь про эту проблему есть отдельный пункт. Там описано что это такое и что с этим делать.