Как взять в JSON в качестве входных данных для "post" метод торнадо Python - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь использовать торнадо, чтобы сделать простой метод получения и публикации. Совершенно новый для торнадо рамки. Для поста, который я хотел бы принять в качестве входного файла json, используйте этот вход для подачи в другую функцию, которую я должен выполнить в другой части кода. Однако я не могу заставить метод post tornado работать даже с простой функцией self.write ().

Для моего метода get я читаю из базы данных SQL, чтобы получить состояние датчика и записать его в формате json. Метод get работает отлично! Когда я захожу на localhost: port #, он читает мой файл get json. Для моего метода записи я хотел бы взять простой json только из одного ключа: значение, которое является числом с плавающей запятой. Я хочу взять число с плавающей запятой, указанное пользователем в json, и использовать его в моей функции flowMKS.set (), которая изменит параметр заданного значения датчика. Я не уверен, как ввести json в метод post и прочитать его в переменную. У меня есть # # -комментированный код ниже, который я пробовал и не работал. Однако я вернулся к основам и просто сделал self.write («Hello World»), чтобы посмотреть, работает ли пост. Я тоже не могу заставить себя писать. Продолжайте получать сообщение об ошибке 500, когда я иду на localhost: порт # / flow_post. Переменная flow_status использовалась в моем методе get.

Предполагаемый результат - принять json {"setpoint": 45.5} в метод post. Используйте номер и вставьте в метод flowMKS, чтобы изменить параметр датчика.

Как бы вы взяли json для метода post, взяли число из ввода json и сохранили его в переменной?

class Current(tornado.web.RequestHandler):
    def get(self): 
        global flow_status
        time = flow_status[0]
        ip = flow_status[1]
        rate = flow_status[2]
        setp = flow_status[3]
        tempc = flow_status[4]

        status = {"flow_controller":{
                "time":time,
                "ip":ip,
                "rate_sccm":rate,
                "setpoint":setp,
                "temperature_c":tempc,
                }
        }

        self.write(status)


class Update(tornado.web.RequestHandler):

#    def prepare(self):
#        if self.request.haders["Content-Type"].startswith("application/json"):
#            self.json_args = json.loads(self.request.body)
#        else:
#            self.json_args = None



    def post(self):

#        #expecting body data to contain JSON so we use json.loads to decrypt the JSON into a dict
#        data = json.loads(self.request.body)
#        
#        #Getting what the setpoint should be
#        setpoint = self.json_args["setpoint"]
#        
#        #making the input a float
#        setpoint = float(setpoint)
#    
#        #setting up connection with sensor
#        flowMKS = FlowController(flow_status[1])
#            
#        #sending setpoint to sensor
#        flowMKS.set(setpoint)

        self.write("Hello World")





if __name__ == '__main__':
#    global flow_status

    #Below is creating the Tornado based API for get and post methods
    tornado.options.parse_command_line()
    app = tornado.web.Application(
            handlers=[(r'/',Current), (r'/flow_post', Update)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)


    #using PeriodicCallback to get info from the SQL database every 500 ms
    PeriodicCallback(get_sql_status,500).start()
    #starting the entire Tornado IOLoop
    tornado.ioloop.IOLoop.current().start()

1 Ответ

0 голосов
/ 09 мая 2019

Для загрузки файла с использованием Tornado вы можете использовать эту функцию tornado.httputil.parse_body_arguments, которая будет разбивать содержимое загруженного файла в словаре file_dict и другие аргументы в FormData в args_dict.

Пример кода:

import tornado.httputil
import tornado.web
import tornado.escape
import json
import os
import sys
import traceback

class FileHandler(tornado.web.RequestHandler):

    def _return_response(self, request, message_to_be_returned: dict, status_code):
        """
        Returns formatted response back to client
        """
        try:
            request.set_header("Content-Type", "application/json; charset=UTF-8")
            request.set_status(status_code)

            #If dictionary is not empty then write the dictionary directly into
            if(bool(message_to_be_returned)):
                request.write(message_to_be_returned)

            request.finish()
        except Exception:
            raise

    def set_default_headers(self, *args, **kwargs):
        self.set_header('Content-Type','text/csv')
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "x-requested-with")
        self.set_header("Access-Control-Allow-Methods", "*")

    def post(self):
        """
        This function reads an uploaded file
        """    
        try:
            arg_dict = {}
            file_dict = {}

            tornado.httputil.parse_body_arguments(self.request.headers["Content-Type"], self.request.body, arg_dict, file_dict)
            uploaded_file = file_dict['TestFile'][0]

            if not uploaded_file:
                return self._return_response(self, { 'message': 'No test file uploaded, please upload a test file' }, 400)

            # File contents here
            file_contents = str(uploaded_file['body'], "utf-8")

            self.set_status(200)
            self.finish()

        except Exception as ex:
            return self._return_response(self, { "message": 'Could not complete the request because of some error at the server!', "cause": ex.args[0], "stack_trace": traceback.format_exc(sys.exc_info()) }, 500)

Вы также можете использовать tornado.escape.json_decode, чтобы десериализовать тело запроса в словарь и что-то с ним сделать.

Пример кода:

import tornado.gen
import tornado.web
import tornado.escape
import json
import os
import sys
import traceback

class JSONHandler(tornado.web.RequestHandler):

    def _return_response(self, request, message_to_be_returned: dict, status_code):
        """
        Returns formatted response back to client
        """
        try:
            request.set_header("Content-Type", "application/json; charset=UTF-8")
            request.set_status(status_code)

            #If dictionary is not empty then write the dictionary directly into
            if(bool(message_to_be_returned)):
                request.write(message_to_be_returned)

            request.finish()
        except Exception:
            raise

    def set_default_headers(self, *args, **kwargs):
        self.set_header("Content-Type", "application/json")
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "x-requested-with")
        self.set_header("Access-Control-Allow-Methods", "*")

    def post(self):
        """
        This function parses the request body and does something
        """    
        try:
            # Do something with request body
            request_payload = tornado.escape.json_decode(self.request.body)

            return self._return_response(self, request_payload, 200)

        except json.decoder.JSONDecodeError:
            return self._return_response(self, { "message": 'Cannot decode request body!' }, 400)

        except Exception as ex:
            return self._return_response(self, { "message": 'Could not complete the request because of some error at the server!', "cause": ex.args[0], "stack_trace": traceback.format_exc(sys.exc_info()) }, 500)
...