Обработка заявки / данных JSON с бутылкой - PullRequest
2 голосов
/ 20 апреля 2011

Я пытаюсь написать простой серверный интерфейс для приложения python3, используя спокойный протокол на основе JSON.Пока что bottle кажется наилучшим подходящим фреймворком для этой задачи (он поддерживает python3, хорошо обрабатывает диспетчеризацию методов и легко возвращает JSON.) Проблема заключается в анализе JSON во входном запросе.

В документации упоминаются только request.fields и request.files, оба, как я полагаю, относятся к данным multipart / form-data.Никаких упоминаний о непосредственном доступе к данным запроса.

Посмотрев на исходный код, я вижу request.body объект типа BytesIO.json.load отказывается действовать напрямую, умирая в json lib с can't use a string pattern on a bytes-like object.Правильный способ сделать это может состоять в том, чтобы сначала декодировать байты в символы Юникода, в зависимости от того, какая кодировка была указана в заголовке HTTP Content-Type.Я не знаю, как это сделать;Я могу видеть класс StringIO и предположить, что он может содержать буфер символов вместо байтов, но не вижу способа декодирования BytesIO в StringIO, если это вообще возможно.

Конечно, это можеттакже возможно прочитать объект BytesIO в строку байтов, затем декодировать его в строку перед передачей его в JSON-декодер, но если я правильно понимаю, это нарушает хорошее поведение буферизации всего этого.

ИлиЕсть ли лучший способ сделать это?

Ответы [ 3 ]

2 голосов
/ 20 апреля 2011

Кажется, что io.TextIOWrapper из стандартной библиотеки делает свое дело!

def parse(request):
    encoding = ... #get encoding from headers
    return json.load(TextIOWrapper(request.body, encoding=encoding))
0 голосов
/ 25 июня 2017

Я написал помощник, чтобы использовать хорошую идею b0fh.Через 2 недели после анализа response.json я подключаюсь к StackOver Flow и понимаю, что нам нужно обойти

Вот:

def json_app_rqt():
    # about request
    request.accept = 'application/json, text/plain; charset=utf-8'

def json_app_resp():
    # about response
    response.headers['Access-Control-Allow-Origin'] = _allow_origin
    response.headers['Access-Control-Allow-Methods'] = _allow_methods
    # response.headers['Access-Control-Allow-Headers'] = _allow_headers
    response.headers['Content-Type'] = 'application/json; charset=utf-8'

def json_app():
    json_app_rqt()
    json_app_resp()

def get_json_request(rqt):
    with TextIOWrapper(rqt.body, encoding = "UTF-8") as json_wrap:
        json_text = ''.join(json_wrap.readlines())
        json_data = json.loads(json_text)
        return json_data

Для использования мы делаем:*

if __name__ == "__main__":

    json_app()

    @post("/train_control/:control")
    def do_train_control(control):
        json_app_resp()

        data = get_json_request(request)
        print(json.dumps(data))

        return data

Спасибо всем

0 голосов
/ 09 сентября 2014

Вот что я делаю, чтобы читать в json на RESTful-сервисе с Python3 и Bottle:

import bson.json_util as bson_json

@app.post('/location/API')
def post_json_example():
    """
    param: _id, value
    return: I usually return something like {"status": "successful", "message": "discription"}
    """

    query_string = bottle.request.query.json
    query_dict = bson_json.loads(query_string)
    _id = query_dict['_id']
    value = query_dict['value']

Затем для проверки

  • из интерпретатора python3, запросы на импорт
  • s = request.Session ()
  • r = s.post ('http://youserver.com:8080/location/API?json {"_id": "540a16663dafb492a0a7626c","value": "test"} ')
  • используйте r.text, чтобы проверить, что было возвращено.
...