尝试 运行 flask app 时出现错误 'function' object has no attribute 'as_view'

getting error 'function' object has no attribute 'as_view' while trying to run flask app

时隔一年多才开始写flask app,估计是忘记了什么。下面的代码会导致错误:

from flask import Flask
from flask import jsonify

from flask_restplus import Resource, Api

from home_iot.config import reader
from download_audio.ydla import download


app = Flask(__name__)

_api = Api(app, catch_all_404s=True, version=0.1,
          title="REST HTTP API's Gateway",
          descrition="REST API gateway")


api_ns = _api.namespace("iot", description="API.")


@api_ns.route("/tcpserver", methods=["GET"])
def advertise_tcpserver():
    ip = reader.get_server_ip()
    return jsonify({"tcpserver": ip})


if __name__ == "__main__":
    app.run(host='127.0.0.1')

错误是:

$pythonapp.py

Traceback (most recent call last):
  File "app.py", line 29, in <module>
    @api_ns.route("/tcpserver", methods=["GET"])
  File "/Users/ciasto/pyenvs/flaskrestplusiot/lib/python2.7/site-packages/flask_restplus/namespace.py", line 98, in wrapper
    self.add_resource(cls, *urls, **kwargs)
  File "/Users/ciasto/pyenvs/flaskrestplusiot/lib/python2.7/site-packages/flask_restplus/namespace.py", line 87, in add_resource
    api.register_resource(self, resource, *ns_urls, **kwargs)
  File "/Users/ciasto/pyenvs/flaskrestplusiot/lib/python2.7/site-packages/flask_restplus/api.py", line 264, in register_resource
    self._register_view(self.app, resource, namespace, *urls, **kwargs)
  File "/Users/ciasto/pyenvs/flaskrestplusiot/lib/python2.7/site-packages/flask_restplus/api.py", line 287, in _register_view
    resource_func = self.output(resource.as_view(endpoint, self, *resource_class_args,
AttributeError: 'function' object has no attribute 'as_view'

不要认为这是使用 flask_restplus 定义命名空间的正确方法。看看 scaling docs.

您可能正在寻找类似的东西:

iot.py

from flask_restplus import Namespace

api_ns = Namespace("iot", description="API.")

@api_ns.route("/tcpserver", methods=["GET"])
def advertise_tcpserver():
    ip = reader.get_server_ip()
    return jsonify({"tcpserver": ip})

然后在你的主 app.py:

# other imports 

from .iot import api_ns

app = Flask(__name__)

_api = Api(app, catch_all_404s=True, version=0.1,
          title="REST HTTP API's Gateway",
          descrition="REST API gateway")

_api.add_namespace(api_ns, path='/some/prefix')

您似乎还在使用已停产的 Python 2.7。我建议使用虚拟环境或 docker 升级到最新版本,以免干扰系统的 python.

希望这可以帮助那些有同样错误但没有找到解决方案的人

要完成 @v25 给出的答案,您必须通过继承 flask_restplus.

中的资源 class 来为您的命名空间提供资源

下面的例子适合我

环境:

  • ubuntu 18.04
  • python 3.7.1

python要求:

  • 烧瓶==1.1.2
  • flask-restplus==0.13.0
  • werkzeug==0.16.1

源代码: iot.py

from flask_restplus import Namespace,Resource

api_ns = Namespace("iot", description="API.")

@api_ns.route("/tcpserver")
class AdvertiseTcpserver(Resource):
    def get(self):
        #TODO return the correct ip value
        return {"tcpserver": "ip"}

app.py

from .iot import api_ns
from flask import Flask
from flask_restplus import Api

app = Flask(__name__)

_api = Api(app, catch_all_404s=True, version=0.1,
      title="REST HTTP API's Gateway",
      descrition="REST API gateway")

_api.add_namespace(api_ns, path='/some/prefix')

app.run()

测试命令:

#!/bin/sh
wget localhost:5000/some/prefix/tcpserver

如果有帮助,请告诉我。