如何在Flask中允许HTTP方法“PUT”和“DELETE”?

时间:2013-08-08 09:14:09

标签: python http flask http-delete http-put

我从Python开始,我尝试像这样做PUT和DELETE方法:

import gamerocket
from flask import Flask, request, render_template
app = Flask(__name__)

gamerocket.Configuration.configure(gamerocket.Environment.Development,
                                apiKey = "my_apiKey",
                                secretKey = "my_secretKey")

@app.route("/update_player", methods = ["PUT"])
def update_player():
    result = gamerocket.Player.update(
        "a_player_id",
        {
            "name" : "bob_update",
            "emailHash" : "update@test.com",
            "totalPointsAchievement" : 1
        }
    )

if result.is_success:
    return "<h1>Success! " + result.player.id + " " + result.player.name +   "</h1>"
else:
    return "<h1>Error " + result.error + ": " + result.error_description

if __name__ == '__main__':
app.run(debug=True)

但是我收到HTTP 405错误 方法不允许

请求的网址不允许使用该方法。

你能帮帮我吗?

编辑:以下是我调用该方法的方法:

class PlayerGateway(object):
    def update(self, player_id, params={}):
    response = self.config.http().put("/players/" + player_id, params)
    if "player" in response:
        return SuccessfulResult({"player": Player(self.gateway,response["player"])})
    elif "error" in response:
        return ErrorResult(response)
    else:
        pass

接下来在Http:

class Http(object):
    def put(self, path, params={}):
        return self.__http_do("PUT", path, params)
    def delete(self, path, params={}):
        return self.__http_do("DELETE", path, params)

    def __http_do(self, http_verb, path, params):

        http_strategy = self.config.http_strategy()

        full_path = self.environment.base_url + "/api/" + self.config.api_version() + path
        params['signature'] = self.config.crypto().sign(http_verb, full_path, params,
                              self.config.secretKey)

        params = self.config.sort_dict(params)

        request_body = urlencode(params) if params !={} else ''

        if http_verb == "GET":
            full_path += "?" + request_body
        elif http_verb == "DELETE":
            full_path += "?" + request_body

        status, response_body = http_strategy.http_do(http_verb, full_path, 
                            self.__headers(),request_body)

        if Http.is_error_status(status):
            Http.raise_exception_from_status(status)
        else:
            if len(response_body.strip()) == 0:
                return {}
            else:
                return json.loads(response_body)

    def __headers(self):
        return {
            "Accept" : "application/json",
            "Content-type" : "application/x-www-form-urlencoded",
            "User-Agent" : "Gamerocket Python " + version.Version,
            "X-ApiVersion" : gamerocket.configuration.Configuration.api_version()
        }

确定请求策略:

import requests

class RequestsStrategy(object):
    def __init__(self, config, environment):
        self.config = config
        self.environment = environment

    def http_do(self, http_verb, path, headers, request_body):

        response = self.__request_function(http_verb)(
            path,
            headers = headers,
            data = request_body,
            verify = self.environment.ssl_certificate,
        )

        return [response.status_code, response.text]

    def __request_function(self, method):
        if method == "GET":
            return requests.get
        elif method == "POST":
            return requests.post
        elif method == "PUT":
            return requests.put
        elif method == "DELETE":
            return requests.delete

1 个答案:

答案 0 :(得分:1)

我没有尝试运行您的代码,但我相信我可以看到发生了什么。

class PlayerGateway(object):
    def update(self, player_id, params={}):
    response = self.config.http().put("/players/" + player_id, params)
    if "player" in response:
        return SuccessfulResult({"player": Player(self.gateway,response["player"])})
    elif "error" in response:
        return ErrorResult(response)
    else:
        pass

您正在使用该调用代码调用路由base_url / api / version / players /。

但是,您正在使用PUT方法

注册路径“/ update_player”

如果没有看到Flask应用程序的其余部分,我无法判断这是否是问题,但您必须定义EACH根允许哪些方法。 :)