Запросы - как потоковая загрузка - частичный файл

Моя цель - сделать PUT части файла с помощью запросов и потокового файла (т.е. не загружать его в память, а затем делать PUT).

Эта страница объясняет, как вы это сделаете для всего файла:

Запросы поддерживают потоковые загрузки, которые позволяют отправлять большие потоки или файлы, не читая их в памяти. Поток и загрузить, просто предоставить файл-подобный объект для вашего тела:

with open('massive-body', 'rb') as f:
 requests.post('http://some.url/streamed', data=f)

Однако в моем случае я хочу только отправить один фрагмент файла. Есть ли способ сделать это?

В концепции что-то вроде:

with open('massive-body', 'rb') as f:
 requests.post('http://some.url/streamed', data=f.read(chunksize))
2 ответа

Основываясь на ответах Грега на мои вопросы, я думаю, что следующее будет работать лучше всего:

Сначала вам понадобится что-то, чтобы обернуть ваш открытый файл, чтобы он ограничивал количество данных, которые можно прочитать:

class FileLimiter(object):
 def __init__(self, file_obj, read_limit):
 self.read_limit = read_limit
 self.amount_seen = 0
 self.file_obj = file_obj
 # So that requests doesn't try to chunk the upload but will instead stream it:
 self.len = read_limit
 def read(self, amount=-1):
 if self.amount_seen >= self.read_limit:
 return b''
 remaining_amount = self.read_limit - self.amount_seen
 data = self.file_obj.read(min(amount, remaining_amount))
 self.amount_seen += len(data)
 return data

Это должно работать как хороший объект-обертка. Тогда вы будете использовать его так:

with open('my_large_file', 'rb') as file_obj:
 file_obj.seek(my_offset)
 upload = FileLimiter(file_obj, my_chunk_limit)
 r = requests.post(url, data=upload, headers={'Content-Type': 'application/octet-stream'})

Заголовки, очевидно, необязательны, но при потоковой передаче данных на сервер рекомендуется быть внимательным пользователем и сообщать серверу, какой тип содержимого вы отправляете.


Я просто бросаю 2 других ответа вместе, так что несите меня, если это не сработает из коробки - у меня нет средств проверить это:

Lazy Method для чтения большого файла в Python?

http://docs.python-requests.org/en/latest/user/advanced/#chunk-encoded-requests

def read_in_chunks(file_object, blocksize=1024, chunks=-1):
 """Lazy function (generator) to read a file piece by piece.
 Default chunk size: 1k."""
 while chunks:
 data = file_object.read(blocksize)
 if not data:
 break
 yield data
 chunks -= 1
requests.post('http://some.url/chunked', data=read_in_chunks(f))

licensed under cc by-sa 3.0 with attribution.