Centralizing Flask routes - python

My colleague would like to place all routes for the web server in a single routing file instead of spreading them around on a bunch of functions. This is how he does it in Java/Play:
GET /recovery controllers.application.recovery()
GET /signup controllers.application.signup(lang="sv")
GET /<:lang>/signup controllers.application.signup(lang: String)
Is it feasible/easy to do in Flask?

Yes, very easy:
from flask import Flask
import controllers.application
app = Flask(__name__)
routes = '''\
GET /recovery controllers.application.recovery
GET /signup controllers.application.signup
GET /<lang>/signup controllers.application.signup'''
for route in routes.splitlines():
method,path,func = route.split()
app.add_url_rule(rule=path, view_func=eval(func), methods=[method])
app.run()

Related

Python REST-API with Flask-RestX and JavaScript REST-Client served together

I run this example: https://flask-restx.readthedocs.io/en/latest/example.html
(A Python REST-API with Flask-RESTX)
Code snippet
app = Flask(__name__)
api = Api(app, ...)
ns = api.namespace('todos', ...)
#ns.route('/')
...
#ns.route('/<int:id>')
...
Result
I get the following URLs for the REST-API:
http://127.0.0.1:5000 -> Swagger Documentation
http://127.0.0.1:5000/swagger.json
http://127.0.0.1:5000/todos/
http://127.0.0.1:5000/todos/{id}
Question
I would like to implement a Webclient with Javascript, which should be reached under following URLs:
http://127.0.0.1:5000 -> index.html
http://127.0.0.1:5000/style.css
http://127.0.0.1:5000/app.js
The URLs for the REST-API should change to:
http://127.0.0.1:5000/api -> Swagger Documentation
http://127.0.0.1:5000/api/swagger.json
http://127.0.0.1:5000/api/todos/
http://127.0.0.1:5000/api/todos/{id}
How can I expand the example to generate the wanted URLs?
Not sure if you have gotten an answer by now. I often clone the below github project for flask restx boilerplate. It is designed as a rest boilerplate to help get you up and running.
https://github.com/cosmic-byte/flask-restplus-boilerplate
The templates and static files can be added to the application and to the controllers to host the pages. Added the below documentation for the static pages. Every this should be there to get you running with a full site
https://flask.palletsprojects.com/en/1.1.x/tutorial/static/
You can wrap flask-restx application with flask.Blueprint to move swagger logic under a specific url_path.
The following example shows how this can be achieved:
import flask
import flask_restx
APP = flask.Flask("my-app")
api_bp = flask.Blueprint("api", __name__, url_prefix="/api")
API = flask_restx.Api(api_bp)
APP.register_blueprint(api_bp)
NAMESPACE = API.namespace("todos")
#NAMESPACE.route("/")
class TODOSAPI(flask_restx.Resource):
def get(self):
return ['todo-1', 'todo-2']

Make a python script API

I have a script on python, which prints some data. The script is on Centos7, nginx.
How could I connect to the script via URL (GET query) to be able to parse the data?
You can use a framework like Django or flask to make an api out of it. I'll suggest flask since it's very light-weight, making it ideal for such small tasks.
E.g.
def your_function(input):
# do something
return output
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/my_api')
def your_api_function():
input = request.args.get('my_query_string')
return your_function(input)
if __name__ == '__main__':
app.run(debug=True)
And then use the endpoint
/my_api?my_query_string=my_input
You can further play around with it to return JSON, take parameters from request body and so on and so forth.
Read more here http://flask.pocoo.org/

Flask dynamic route not working - Real Python

I'm working through RealPython and I'm having trouble with the flask dynamic route.
Everything seemed to work until the dynamic route. Now if I try to enter a "search query" (i.e. localhost:5000/test/hi) the page is not found. localhost:5000 still works fine.
# ---- Flask Hello World ---- #
# import the Flask class from the flask module
from flask import Flask
# create the application object
app = Flask(__name__)
# use decorators to link the function to a url
#app.route("/")
#app.route("/hello")
# define the view using a function, which returns a string
def hello_world():
return "Hello, World!"
# start the development server using the run() method
if __name__ == "__main__":
app.run()
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
I can't see that other people using RealPython have had an issue with the same code, so I'm not sure what I'm doing wrong.
The reason why this is not working is because flask never learns that you have another route other / and /hello because your program gets stuck on app.run().
If you wanted to add this, all you need to do would be to add the new route before calling app.run() like so:
# ---- Flask Hello World ---- #
# import the Flask class from the flask module
from flask import Flask
# create the application object
app = Flask(__name__)
# use decorators to link the function to a url
#app.route("/")
#app.route("/hello")
# define the view using a function, which returns a string
def hello_world():
return "Hello, World!"
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
# start the development server using the run() method
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True, port=5000)
Now this will work.
Note: You don't need to change the run configurations inside of app.run. You can just use app.run() without any arguments and your app will run fine on your local machine.
Try using the entire URL instead of just the IP address.

Combining resources in Python with Flask

I' trying to combine two independent Flask apps like the example below:
from geventwebsocket import WebSocketServer, Resource
...
server = WebSocketServer(('', 8080), Resource({
'/': frontend,
'/one': flask_app_one,
'/two': flask_app_two}))
server.serve_forever()
Inside each Flask app I declare the full path, isn't that suppose to be relative path, inside flask_app_one:
from flask import Flask
app = Flask(__name__)
#app.route('/one/ping')
def ping():
return 'hello\n'
Why I should specify in #app.route('/one/ping') instead of just #app.route('/ping') since all traffic to /one will be forwarded to the corresponding app?
Let me know if you need any additional info I kept my example clean
Thank you
Finally I have managed to do it with the so called Application Dispatching and the resources found in this page:
http://flask.pocoo.org/docs/0.10/patterns/appdispatch/#app-dispatch
Thanks

How to obtain values of parameters of get request in flask?

The answer that I found on the web is to use request.args.get. However, I cannot manage it to work. I have the following simple example:
from flask import Flask
app = Flask(__name__)
#app.route("/hello")
def hello():
print request.args['x']
return "Hello World!"
if __name__ == "__main__":
app.run()
I go to the 127.0.0.1:5000/hello?x=2 in my browser and as a result I get:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
What am I doing wrong?
The simple answer is you have not imported the request global object from the flask package.
from flask import Flask, request
This is easy to determine yourself by running the development server in debug mode by doing
app.run(debug=True)
This will give you a stacktrace including:
print request.args['x']
NameError: global name 'request' is not defined
http://localhost:5000/api/iterators/opel/next?n=5
For something like the case before
from flask import Flask, request
n = request.args.get("n")
Can do the trick

Categories