Страницы

Поиск по вопросам

среда, 4 марта 2020 г.

Как отправить полученный файл на другой сервер?

#python #python_3x #django #python_27


Есть следующая система. 

Существует сервер обработки фото на одном сервере и есть основной сервер. 

Пользователь отправляет форму, в которой есть фото, на сервер обработки фото, сервер
фото обрабатывает его и отправляет на основной сервер через requests.post. На данный
момент работает, только если сначала сохранить файл на физический диск, а потом уже
отправить его с (указанием пути) на основной сервер.

Как можно отправить файл через requests.post, не сохраняя его на диск?

Пробовал конвертировать с помощью StringIO, BytesIO, но так ничего и не вышло.

сохраняю на данный момент так:

# Получаю и сохраняю фото
f = request.FILES['photo']
f.save(file_path)

# Меняю размер фото
image = Image.open(file_path)
image.thumbnail([150, 150], Image.ANTIALIAS) 
image.save(file_path, image.format, quality=100, optimize=1)

# Отправляю так
fil = open(file_path, 'rb')
filess = {'photo': ('photo.jpg', fil, 'image/jpeg')}
request = requests.post("%s%s" % (domen, url), data=post, files=filess)


Собственно нужно отправить уже измененный файл image

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

То что я находил по отправке файла через StringIO ничего не работало, то сам модуль
ругался что данные не те, то модель по отправке ругался что данные не те, поэтому причина
видимо в том что я файл не правильно преобразовывал в StringIO. Видимо мой вопрос сводится
к тому как правильно преобразовать этот файл к такому формату и потом как эти данные
отправить через requests.post
    


Ответы

Ответ 1



Основной сервер-то как принимает картинку? Тоже как загружаемый файл? Тогда предельно просто: def upload_view(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): f = request.FILES['photo'] requests.post('http://example.com', files={f.name: f}) return redirect('upload:success') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form}) Если он ожидает поток байт в теле запроса, то чуть сложнее: def upload_bridge(f): for chunk in f.chunks(): yield chunk def upload_view(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): requests.post('http://example.com', data=upload_bridge(request.FILES['photo'])) return redirect('upload:success') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form}) Только учтите, что большой файл может надолго поставить обработчик колом. Это может привести либо к обрыву соединения по таймауту, либо исчерпанию обработчиков и последующей недоступности сайта. UPDATE: from StringIO import StringIO f = request.FILES['photo'] input = StringIO(f.read()) output = StringIO() image = Image.open(input) image.thumbnail([150, 150], Image.ANTIALIAS) image.save(output, 'PNG') requests.post('http://example.com', files={f.name: output}) output.close() input.close() Этот вариант не только будет обработчик ставить колом, но ещё и память жрать будет.

Комментариев нет:

Отправить комментарий