使用python将json和文件发送到flask

Mou*_*dri 6 post json file request flask

我有这个问题,我试图在单个函数中向烧瓶 API 发送/接收一些文件和 JSON。

在我的客户(发件人)上,我有:

#my json to be sent 
datas = {'var1' : 'var1','var2'  : 'var2',}
#my file to be sent 
local_file_to_send = 'user_picture.jpg'
url = "http://10.100.2.6:80/customerupdate"
headers = {'Content-type': 'multipart/form-data'}
files = {'document': open(local_file_to_send, 'rb')}
r = requests.post(url, files=files, data=datas, headers=headers)
Run Code Online (Sandbox Code Playgroud)

在我的 Flask 服务器上,我有:

class OPERATIONS(Resource):
        @app.route('/',methods=['GET'])
        def hello_world():
            return 'Hello World!'

        @app.route('/customerupdate',methods=['GET','POST'])
        def customerupdate():
            event_data_2 = json.loads(request.get_data().decode('utf-8'))
            print event_data_2
Run Code Online (Sandbox Code Playgroud)

我收到这条错误消息,告诉我数据实际上既不是 json 格式也不是 utf8 格式。如果我打印“get_data”的内容而不尝试解码它会显示一些二进制字符..

我的客户端读取 json 并在本地写入文件的语法是什么?

Cra*_*lly 11

我建议将 JSON 和文件作为多部分表单的一部分发送。在这种情况下,您将从request.files服务器上读取它们。(一个警告:我使用 Python 3、请求 2.18.4 和 Flask 0.12.2 测试了我的所有示例——您可能需要更改代码以匹配您的环境)。

来自/sf/answers/2515868631/(以及http://docs.python-requests.org/en/latest/user/advanced/#post-multiple-multipart-encoded-files 上的 Flask 文档),您无需指定标题或任何内容。你可以让它requests为你处理:

import json
import requests

# Ton to be sent
datas = {'var1' : 'var1','var2'  : 'var2',}

#my file to be sent
local_file_to_send = 'tmpfile.txt'
with open(local_file_to_send, 'w') as f:
    f.write('I am a file\n')

url = "http://127.0.0.1:3000/customerupdate"

files = [
    ('document', (local_file_to_send, open(local_file_to_send, 'rb'), 'application/octet')),
    ('datas', ('datas', json.dumps(datas), 'application/json')),
]

r = requests.post(url, files=files)
print(str(r.content, 'utf-8'))
Run Code Online (Sandbox Code Playgroud)

然后在您可以读取的服务器上request.files(请参阅http://flask.pocoo.org/docs/0.12/api/#flask.Request.files但请注意 request.files 过去的工作方式略有不同,请参阅https:// stackoverflow.com/a/11817318/2415176):

import json                                                     

from flask import Flask, request                                

app = Flask(__name__)                                           

@app.route('/',methods=['GET'])                                 
def hello_world():                                              
    return 'Hello World!'                                       

@app.route('/customerupdate',methods=['GET','POST'])            
def customerupdate():                                           
    posted_file = str(request.files['document'].read(), 'utf-8')
    posted_data = json.load(request.files['datas'])             
    print(posted_file)                                          
    print(posted_data)                                          
    return '{}\n{}\n'.format(posted_file, posted_data)          
Run Code Online (Sandbox Code Playgroud)


Mou*_*dri 7

感谢 Craig 的回答,我找到了解决方案。我将发布两个代码(客户端和服务器)以帮助将来使用。客户端服务器正在以flask 的“表单”功能上传文件和Json。然后一些 ast 和一些 dict 使有效载荷更清晰(我知道这是丑陋的方式,但这是最好的学者方法)

客户端:

datas = {'CurrentMail': "AA", 'STRUserUUID1': "BB", 'FirstName': "ZZ",     'LastName': "ZZ",  'EE': "RR", 'JobRole': "TT"  }

#sending user infos to app server using python "requests"
url = "http://10.100.2.6:80/customerupdate"
def send_request():
    payload = datas
    local_file_to_send = 'user_picture.jpg' 
    files = {
     'json': (None, json.dumps(payload), 'application/json'),
     'file': (os.path.basename(local_file_to_send), open(local_file_to_send, 'rb'), 'application/octet-stream')
    }
    r = requests.post(url, files=files)

send_request()
Run Code Online (Sandbox Code Playgroud)

Flask 服务器端:

import sys, os, logging, time, datetime, json, uuid, requests, ast
from flask import Flask, request , render_template
from werkzeug import secure_filename
from werkzeug.datastructures import ImmutableMultiDict
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)
app.debug = True

class OPERATIONS(Resource):
        @app.route('/',methods=['GET'])
        def hello_world():
            return 'Hello World!'

        @app.route('/customerupdate',methods=['GET','POST'])
        def customerupdate():
            print "************DEBUG 1 ***********"
            RequestValues = request.values
            print RequestValues
            print "************DEBUG 2 ***********"
            RequestForm = request.form
            print RequestForm
            print "************DEBUG 2-1 ***********"
            so = RequestForm
            json_of_metadatas = so.to_dict(flat=False)
            print json_of_metadatas
            print "************DEBUG 2-2 ***********"
            MetdatasFromJSON = json_of_metadatas['json']
            print MetdatasFromJSON          
            print "************DEBUG 2-3 ***********"
            MetdatasFromJSON0 = MetdatasFromJSON[0]
            print MetdatasFromJSON0
            print "************DEBUG 3-5 ***********"
            strMetdatasFromJSON0 = str(MetdatasFromJSON0)
            MetdatasDICT = ast.literal_eval(strMetdatasFromJSON0)
            print MetdatasDICT
            print "************DEBUG 3-5 ***********"
            for key in MetdatasDICT :
                print "key: %s , value: %s" % (key, MetdatasDICT[key])
            print "************DEBUG 4 ***********"
            f = request.files['file']
            f.save(secure_filename(f.filename))
            print "FILE SAVED LOCALY"
            return 'JSON of customer posted'
Run Code Online (Sandbox Code Playgroud)