I writing a flask, trying to organize it by using Blueprint with Namespace, following this tutorial
I had faced some problem, and had look around internet and had review solution in 1 and 2. The first one is not relevant to what I doing, and the second one the solution just doesn't fix my problem.
Here are my code:
project/project.py
from flask import Flask, jsonify, url_for
from .apis.apis import api
app = Flask(__name__)
app.register_blueprint(api, url_prefix="/api")
project/apis/apis.py
from flask import Blueprint
from .user.authentication import auth
from flask_restplus import Api, apidoc, Resource
blueprint = Blueprint("api", __name__)
api = Api(blueprint, doc='/docs', ui=False)
api.add_namespace(auth, path="/auth") #Keep getting error at this line
project/apis/user/authentication.py
from flask_restplus import Namespace
auth = Namespace('auth', description='Authentication')
@auth.route("/test")
def authentication():
return "test"
Stack Trace
Traceback (most recent call last):
File "/home/gaara/Python/Flask-Api/project/__init__.py", line 1, in <module>
from .project import app
File "/home/gaara/Python/Flask-Api/project/project.py", line 3, in <module>
from .apis.apis import api
File "/home/gaara/Python/Flask-Api/project/apis/apis.py", line 13, in <module>
api.add_namespace(auth, path="/auth")
File "/home/gaara/Python/Flask-Api/venv/lib/python3.6/site-packages/flask_restplus/api.py", line 413, in add_namespace
self.register_resource(ns, resource, *self.ns_urls(ns, urls), **kwargs)
File "/home/gaara/Python/Flask-Api/venv/lib/python3.6/site-packages/flask_restplus/api.py", line 255, in register_resource
self._register_view(self.app, resource, *urls, **kwargs)
File "/home/gaara/Python/Flask-Api/venv/lib/python3.6/site-packages/flask_restplus/api.py", line 276, in _register_view
resource_func = self.output(resource.as_view(endpoint, self, *resource_class_args,
AttributeError: 'function' object has no attribute 'as_view'
I am not sure why I keep getting this error, had try few approach, include put apis.py all in __init__.py and change the import, but always getting the same error.
What I wish is to code api in an organize way, and when go to localhost:5000/api/auth/test
it will output me test
You defined a function, but Flask restplus requires a class, as you can also see in your tutorial.
So it should look like this:
from flask_restplus import Resource
@auth.route("/test")
class Authentication(Resource):
def get(self):
return "test"
While the approved answer is fully correct, let me dispose why we always say, that if something is possible, does not mean that you should do! So the following to be for everyone a lesson (at 1st place for myself) of an ANTI-PATTERN!
I was a bit tinkering here & there, I found out what is needed for a function like you mentioned in order to be registered and usable by a framework, like F-Restplus (I've used in my case F-RestX==0.5.0, but in reality is a fork of that), and here we go:
def avg(dummy_self_var=''):
# the dummy_self_var is needed in order to trick and pretend to be as an instance method
result = 'any-calculation-that-has-to-be-made'
logging.debug(f'AVG result is: {result}')
return Response(str(result))
# imitating that this function is a Resource :D
avg.view_class = Resource
avg.as_view = Resource.as_view # at the end, it could be the following function as well: `lambda x,y: avg`
avg.view_class.methods = {'GET', }
avg.view_class.get = avg
api.add_resource(avg, '/asd')
With the help of this I achieved to have the same functionality, it works & gets registered automatically by the Swagger-UI docs:
So, while nearly everything is possible, I could not imagine a situation where someone needs this 'workaround', instead, to be forward-compatible, I would definitely refactor instead of producing this mess in the long-run. Of course, the choice is up to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With