С сервером Flask:

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print('get_json: %s get_data: %s' % (type(request.get_json()), type(request.get_data())) )
    return 'OK', 200

app.run('0.0.0.0', 80)

Клиент отправляет запрос, используя аргументы json и files:

import requests 
files_data = {"dirname/file,name": bytearray(4)}
response = requests.post('http://127.0.0.1:80/', json = 'hello world', files = files_data)

Сервер печатает, что request.get_json() возвращает None.

get_json: <type 'NoneType'> get_data: <type 'str'>

Как передать строку hello world на сервер?

1
alphanumeric 15 Авг 2019 в 09:54

2 ответа

Лучший ответ

Согласно документации:

Note, the json parameter is ignored if either data or files is passed.

Ваш параметр json должен иметь тип json, например:

import requests 
json_data = {'data': 'hello world'}
files_data = {"dirname/file_name": bytearray(4)}
response = requests.post('http://127.0.0.1:80/', json = 'hello world')

Если вы хотите использовать файл и json вместе, не кодируйте, используя json.

Кроме того, не устанавливайте заголовок Content-type самостоятельно, оставьте его для пиреквестов для генерации

payload = {"param_1": "value_1", "param_2": "value_2"}
    files = {
         'json': (None, json.dumps(payload), 'application/json'),
         'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
    }

    r = requests.post(url, files=files)

Для получения дополнительной информации см. Эту тему Как отправить JSON как часть составного POST-запроса

3
Дмитрий Сиденко 15 Авг 2019 в 08:22

Рабочее решение размещено ниже:

Server.py

import os 
import json 
import tempfile
from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print('get_json: %s get_data: %s' % (type(request.get_json()), type(request.get_data())) )

    for key, value in request.files.items():
        if value.content_type == 'application/json':
            data = json.loads(value.stream.read())
            print('got json data %s' % data)

        elif value.content_type == 'application/octet-stream':
            dst_filepath = os.path.join(tempfile.mktemp(), value.filename)
            if not os.path.exists(os.path.dirname(dst_filepath)):
                os.makedirs(os.path.dirname(dst_filepath))

            with open(dst_filepath, 'wb') as fd:
                for chunk in value: 
                    fd.write(chunk)
                print('saved file as %s' % dst_filepath)

    return 'OK', 200

app.run('0.0.0.0', 80)

Client.py

import requests 
import json
import os 


payload = {"param_1": "value_1", "param_2": "value_2"}

filepath = '/file/path/to/local_file.zip'

files = {'json': ('some-json', json.dumps(payload), 'application/json'),
        'file': (os.path.basename(filepath), open(filepath, 'rb'), 'application/octet-stream')}

response = requests.post('http://127.0.0.1:80/', files=files)
0
alphanumeric 15 Авг 2019 в 15:42