flask_restful以字节为单位返回json数据

时间:2017-05-08 18:58:57

标签: python json flask flask-restful

我有以下烧瓶应用设置。

#!/usr/bin/env python3

import sys
import logging

from flask import Flask, jsonify
from flask_env import MetaFlaskEnv
from flask_restful import Resource, Api
from flask_restful import reqparse
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.wsgi import WSGIContainer

class Configuration(metaclass=MetaFlaskEnv):
    """
    export PORT=80
    """
    DEBUG = True
    PORT = 5000

root = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
root.addHandler(handler)

LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)

app = Flask(__name__)
app.config.from_object(Configuration)
api = Api(app)

peopleDict = {}

class People(Resource):
    def get(self):
        """curl http://localhost:5000/people/
        """
        return jsonify(peopleDict)

    def post(self):
        """curl http://localhost:5000/people -d "age=22&name=john" -X POST -v
        """
        parser = reqparse.RequestParser()
        parser.add_argument('name')
        parser.add_argument('age')

        args = parser.parse_args()
        peopleDict[args['name']] = {'age': args['age']}
        return jsonify({args['name']: peopleDict[args['name']]})


class Person(Resource):
    def get(self, name):
        """curl http://localhost:5000/person/john
        """
        return jsonify({name: peopleDict[name]})

    def put(self, name):
        """curl http://localhost:5000/person/john -d "age=30" -X PUT -v
        """
        parser = reqparse.RequestParser()
        parser.add_argument('age')

        args = parser.parse_args()
        peopleDict[name] = {'age': args['age']}
        return jsonify({name: peopleDict[name]})

    def delete(self, name):
        """curl http://localhost:5000/person/john -X DELETE -v
        """
        person = peopleDict[name]
        del peopleDict[name]
        return jsonify({name: person, 'deleted':'true'})


api.add_resource(People, '/people')
api.add_resource(Person, '/person/<string:name>')


@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    LOGGER.debug("server starting on port :" + str(app.config["PORT"]))
    HTTP_SERVER = HTTPServer(WSGIContainer(app))
    HTTP_SERVER.listen(port=app.config["PORT"])
    IOLoop.instance().start()

我也有这样的测试用例:

import json
import unittest
from ddt import ddt, data, unpack
from app import app

@ddt
class ApiTestCase(unittest.TestCase):

    def setUp(self):
        self.client = app.test_client()

    def testPostPeople(self):
        result = self.client.post('/people', data={'name':'john', 'age':22})
        print (result.data)
        values = json.loads(result.data)

我在运行测试用例时遇到了以下错误

b'{\n  "john": {\n    "age": "22"\n  }\n}\n'
E
======================================================================
ERROR: testPostPeople (tests.test_api.ApiTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/ubuntu/transfer/tests/test_api.py", line 15, in testPostPeople
    values = json.loads(result.data)
  File "/usr/lib/python3.5/json/__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'

----------------------------------------------------------------------
Ran 1 test in 0.015s

我不明白为什么我以字节为单位获取json字符串,它应该在str中。我可以在result.data上调用decode(),但我真的想在应用程序中解决这个问题,而不是在测试用例中。

0 个答案:

没有答案