处理烧瓶和瓶子中的发帖请求

时间:2020-08-15 14:42:33

标签: python bottle

我已经尝试构建一个API超过4个小时了,我搜索并询问了所有可以找到的地方,但找不到帮助。问题在于处理POST请求的级别。我尝试使用NodeJS(验证和表达(以及中间件))和Python(烧瓶,瓶子),但仍然无法理解为什么我在python中得到一个带有express或None的空对象。我的瓶子有以下代码

 1 from bottle import run, Bottle, post, request, redirect
 2 import json
 3
 4 pika = Bottle()
 5
 6 @post("/shorturl")
 7 def shorten():
 8     data = request.json
 9     #data = json.dumps(rdata)
10     print(data)
11     return f"You posted {data}"
12
13 run(host="localhost", port=3000, debug=True)

我一开始就有以下代码(我已删除并从头开始重新启动)-您可以找到tweet here

分别使用request.get_json()request.json()时,我无法从烧瓶和瓶子中获得None,这是我从文档中找到的方法。

任何帮助表示赞赏。

谢谢

2 个答案:

答案 0 :(得分:1)

您的python代码似乎是正确的,因为我尝试了并且有效。 要进行故障排除,您可以插入:

print(request.headers['Content-Type']) #output should be: application/json'
print(request.body.read())             #output should be like: b'{"key":"value"}'

我使用Postman,当我第一次尝试时,我犯了一个错误,即选择正文 form 而不是 raw 。在Postman中,您必须在标头中手动编写 Content-Type:appliction / json 并将json插入为 raw 。 我认为在Restler中,它是相似的(我从未使用过Restler)。

因此,如果您必须手动配置它,请确保标头包含'Content-Type':'application / json' enter image description here 并且您的身体设置为原始,看起来像这样。 enter image description here 例如,如果选择了 form-data ,邮递员将不会使用手动设置的标头,而 print(request.header ['Content-Type'])会输出一些内容像这样: multipart / form-data; boundary = -------------------------- 742283902180513961059188

可以想象Restler有同样的网罗。

答案 1 :(得分:1)

这是处理api动态路由的一种方法。现在,您只需将方法添加到API类中,瓶子应用程序会自动选择这些方法。我将POST和GET合并为一个方法字符串,以将查询参数和表单合并为一个有效载荷,您可以通过self.payload

访问
import ujson as json
from login import User

def check(data):
    try:
        if isinstance(data, (str,bytes)):
            return json.loads(data)
    except:
        return data
    return data

def merge_dicts(*args):
    result = {}
    for dictionary in args:
        result.update(dictionary or {})
    return result

class API:
    def __init__(self, payload, user):
        self.payload = payload
        self.option = ''
        self.request = None

    @classmethod
    def bot(cls, request, option, user):
        payload = merge_dicts(dict(request.forms), dict(request.query.decode()))  # merge query and form inputs
        slf = cls(payload, user)
        slf.request = request
        slf.option = str(option)
        return slf

    def test(self): # localhost/api/test
        return self.payload

@get('/api/<command>')
@post('/api/<command>')
@get('/api/<command>/<option>')
@post('/api/<command>/<option>')
def routeapi(command='', option=''):
    user = User()
    wapi = API.bot(request, option, user)
    func = getattr(wapi, f"{command}", None)
    if callable(func):
        result = func()
        if result:
            if request.method == 'GET':
                response.headers['Content-Type'] = 'application/json'
                response.headers['Cache-Control'] = 'no-cache'
            return {command:json.check(result)}
        else:
            return {command:None}