Cannot get API specs with Flask Blueprints and Swagger UI - python

So, following the examples for swagger ui usage with flask blueprints (https://github.com/rantav/flask-restful-swagger/blob/master/examples/blueprints.py), I have the following code:
app = Flask(__name__)
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(restful.Api(test_blueprint), apiVersion='0.1',
basePath='http://localhost:5000',
produces=["application/json", "text/html"],
api_spec_url='/api/spec')
# Operation TestOp defined here
test_api.add_resource(TestOp, '/')
if __name__ == "__main__":
app.register_blueprint(test_blueprint, url_prefix='/test')
app.run(debug=True)
However, when I try to access the api spec docs, the URL cannot be located.
I've tried...
localhost:5000/api/spec
localhost:5000/test_api/api/spec
localhost:5000/test_api
...all of which return a 404. I've also tried creating the app without blueprints, creating the docs with
swagger.docs(restful.Api(app)...)
instead. When there this is done and no blueprints are involved, I can reach the docs at
localhost:5000/api/spec
So, am I creating my application incorrectly with blueprints, or am I just not hitting the right URL to get access to the docs?

I know this thread is old, but I ran into this exact problem today, trying to use flask-restful-swagger with my (somewhat) modern flask + python3 app that uses blueprints. Same problem, no errors, just no spec available no matter what i tried.
I finally abandoned this package (as it seems like it hasn't been very active anyway), even though I like the markup better with this package.
I chose Flasgger, which seemed to be updated more recently. In 10 minutes I had it up and running. Code and short tutorial are here: https://github.com/rochacbruno/flasgger

It looks like you're just not hitting the right URL. Because your blueprint url_prefix is "/test", the Swagger spec url should be at:
localhost:5000/test/api/spec

something wrong in swagger.docs()
from flask_restful import Api
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(Api(test_blueprint)...)
app.register_blueprint(test_blueprint)
what'more
main_blueprint = Blueprint('api', __name__, url_prefix='/demo')

Related

Flask authentication using htpassword with routes in seperate files

I'm working on updating an existing university department internal website to run using Flask. Before we completely release the project where it will use shibboleth to manage authentication, I've been trying to setup authentication for testing using htpassword using this tutorial. I'm able to get authentication using htpasswords working for a single file, but I can't figure out how to add the authentication to separate files. Currently, the project looks like this:
This is my main file called app.py:
#app.py
from flask import Flask
from flask_htpasswd import HtPasswdAuth
app = Flask(__name__)
app.config['FLASK_HTPASSWD_PATH'] = '.htpasswd'
app.config['FLASK_SECRET'] = "Super secret key that I will change later"
htpasswd = HtPasswdAuth(app)
import exampleRoute
#app.route('/')
#htpasswd.required
def home(user):
return "This is the homepage"
This is an example of one of my route files called exampleRoute.py:
# exampleRoute.py
from app import app
from flask import Flask
#app.route('/exampleRoute')
def exampleRoute():
return "This is an example route in another file"
When I place the #htpassword.required decorator in front of exampleRoute(), I get an error saying that htpassword is not defined (which makes sense). I've tried to import the app configuration a few different ways and at best, I end up with a circular dependency. I know that I could place the authentication code in a separate file and then import that into all my endpoints, but I didn't think this was possible since this method is incorporated into the app configuration.
I ended up getting an answer from the reddit user alexisprince. The solution was to use Blueprints that import htpasswd from another file (called extensions.py).

Creating an API to execute a python script

I have a python script app.py in my local server (path=Users/soubhik.b/Desktop) that generates a report and mails it to certain receivers. Instead of scheduling this script on my localhost, i want to create an API which can be accessed by the receivers such that they would get the mail if they hit the API with say a certain id.
With the below code i can create an API to display a certain text. But, what do i modify to run the script through this?
Also if i want to place the script in a server instead of localhost, how do i configure the same?
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return ("hello world")
if __name__ == '__main__':
app.run(debug=True)
Python Version is 2.7
A good way to do this would be to put the script into a function, then import that function in your Flask API file and run it using that. For hosting on a web server you can use Python Anywhere if you are a beginner else heroku is also a good option.
If you are tying to achieve something using Python-Flask API than you can have a close look at this documentations and proceed further https://www.flaskapi.org/, http://flask.pocoo.org/docs/1.0/api/
Apart from these here are few basic examples and references you can refer for a quickstart :
1-https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask
2- https://flask-restful.readthedocs.io/en/latest/
3- https://realpython.com/flask-connexion-rest-api/
You could do something like this
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class ExecuteScript:
def printScript:
return "Hello World"
api.add_resource(ExecuteScript, '/printScript')
if __name__ == '__main__':
app.run(debug=True)

Cloud9 "Unable to load http preview" Flask project

I'm following a mooc for building quickly a website in flask.
I'm using Cloud9 but i'm unable to watch my preview on it, i get an :
"Unable to load http preview" :
the code is really simple, here the views.py code
from flask import Flask, render_template
app = Flask(__name__)
# Config options - Make sure you created a 'config.py' file.
app.config.from_object('config')
# To get one variable, tape app.config['MY_VARIABLE']
#app.route('/')
def index():
return "Hello world !"
if __name__ == "__main__":
app.run()
And the preview screen, is what I get when I execute
python views.py
Thank you in advance
you need to make FLASK_APP environment variable, and flask application is not running like python views.py but flask run. Quick start
# give an environment variable, give the absolute path or relative
# path to you flask app, in your case it is `views.py`
export FLASK_APP=views.py
#after this run flask application
flask run
I faced the same problem. There is no way we can preview http endpoints directly. Although in AWS documentation they have asked to follow certain steps, but those too wont work. Only way is to access it using instance public address and exposing required ports. Read here for this.

remove whitespace from JSON response by flask-restplus

How can you get rid of whitespace in the JSON response by flask-restplus routes?
In a similar question, but for flask-restful instead of flask-restplus, the answer suggested setting the config option JSONIFY_PRETTYPRINT_REGULAR = False. This does not seem to work for flask-restplus.
I can't find anything in the documentation for flask-restplus around this either. What's the right way to do this? Anything better than overwriting the response handler?
Glancing at the source, flask-restplus takes it JSON dumps settings from a flask config variable called RESTPLUS_JSON. But also from the source, it looks like it would only pretty-print when running in debug mode.
Here's an example of manually controlling it:
from flask import Flask
from flask_restplus import Api, Resource
app = Flask(__name__)
api = Api(app)
app.config['RESTPLUS_JSON'] = {'indent':None, 'separators':(',',':')}
#api.route('/hello')
class HelloWorld(Resource):
def get(self):
return {'hello': 'world', 'abc':'def'}
if __name__ == '__main__':
app.run(debug=True)

Combining 2 Flask apps using DispatcherMiddleware instance results in 404 for second app

Sorry for ambiguous question, I'm not sure how better I can put it. So let me do the explanation of my problem.
I've the Flask application libindic, which has 2 Flask application one is frontend and other is api. So I've wsgi.py as follows
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
from silpa import api, frontend
import os
conffile = os.path.join(os.path.dirname(__file__), "etc", "silpa.conf")
application = DispatcherMiddleware(frontend.create_app(conffile),
{'/api': api.create_app(conffile)})
if __name__ == "__main__":
run_simple('0.0.0.0', 5000, application,
use_reloader=True, use_debugger=True)
The front end access works properly but when I hit /api/JSONRPC I get 404 error returned. This rule is defined as follows in silpa/api/jsonrpc.py
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
#route(bp, '/JSONRPC', methods=['POST'])
def handle_jsonrpc_call():
...
And when I print value of application and application.app and application.mounts in python interpreter I see folllowing
>>> application.app
<Flask 'silpa.frontend'>
>>> application.mounts
{'/api': <Flask 'silpa.api'>}
I'm unable to figure out why /api/JSONRPC results in 404. I'm not sure how can I debug it. I did check the app.url_map for api application and I can see rule for /api/JSONRPC registered there.
If some one can tell me what I might be doing wrong it would be a great help.
OK after debugging and stepping through Flask code I figured out the reason for the problem. The following line actually caused the problem
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
url_prefix should not be present in code because I'm already mounting this app at /api. Adding a /api url_prefix will result in following url instead /api/api/JSONRPC. Removing the above line fixed the issue.
So if you are mouting your app at different mount point than / using DispatcherMiddleware you should not url_prefix in blueprint.

Categories

Resources