This question already has answers here:
Split Python Flask app into multiple files
(4 answers)
Closed 2 years ago.
I'm building a small flask application and I want to have a modular structure in my project.
In Django I could just write two separate folders with their own urls.py, register them in my settings.py and create routes to them in base urls.py.
How to achieve this kind of modularity in flask?
Preferably with as little code as possible.
Bonus points if all this can be easily done without extensions.
You are looking for blueprints.
app.py
blueprints/
sample_blueprint.py
another_blueprint.py
Blueprints are like apps but not apps. (very lame explanation but let me show you some code)
# sample_blueprint.py
from flask import Blueprint
# just like `app = Flask(__name__)`
SAMPLE_BLUEPRINT = Blueprint('sample_blueprint', __name__)
# just like `#app.route('/sample')`
#SAMPLE_BLUEPRINT.route('/sample')
def sample():
return 'Sample'
And then in app.py you have to register it.
# app.py
from flask import Flask
from blueprints.sample import SAMPLE_BLUEPRINT
app = Flask(__name__)
# Register all the blueprints, url_prefix is optional
app.register_blueprint(SAMPLE_BLUEPRINT, url_prefix='/sample-br')
if __name__ == '__main__':
app.run(debug=True)
You can now run the app (python3 app.py) and goto localhost:5000/sample-br/sample and see the response of the blueprint route.
This code is not tested. It is just to give you a starting idea. Please read the docs and try it out on your own and find out how blueprints fit into a Flask project.
Related
I'm trying to implement the get_my_ip() method from flask. I'm getting an unresolved reference despite importing the relevant packages. I found solutions for similar issues that say that I have folder named 'app', which causes the problem, but I couldn't find such folder.
The code:
from flask import request
from flask import jsonify
#app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
return jsonify({'ip': request.remote_addr}), 200
The function is called as follows:
with open('file.txt, 'a') as f:
f.write(f'ip: {get_my_ip()}')
Thanks.
To answer the question title
You haven't actually defined app. You can't use the decorator to add routes to an application that you haven't even defined.
from flask import Flask, request, jsonify
app = Flask(__name__) # See here
#app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
return jsonify({'ip': request.remote_addr}), 200
I strongly suggest The Flask Megatutorial because this is a fundamental misunderstanding.
To answer what you're trying to do - this is horribly misguided. You're trying to snag on to some functionality from Flask without actually running an application. Flask is not a server. You could have any number of levels of actual servers before things got to the level of your code. For example, Apache or Nginx, then gunicorn. All of those could capture the IP.
Consider, I have a flask server deployed which routes to multiple webpages. If I want to change content of one route, by changing its code, is it possible to reflect those changes in webpages without rerunning the flask server? It is possible to host and rerun other scripts on the linux server or entriely another flask server as long as the website url(port number and route) doesn't change.
Please suggest any way you can come up with!
setting flask environment will do the thing for you in the shell.
export FLASK_ENV=development
Assuming you are using flask development server,
Yes, its possible using use_reloader=True,
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
# You business logic code
return some_data
if __name__ == '__main__':
app.run(debug=False, host='0.0.0.0', port=8000,
use_reloader=True, threaded=True)
However it is not good idea to use it in production, related Is the server bundled with Flask safe to use in production?
My assumption is that you want your deployment service to recognize that a change has occurred in a file, which prompts it to automatically restart to reflect the changes, rather than you manually restarting the service.
Assuming that you are deploying on a production uWSGI server, starting the service with touch-reload=/path/to/folder would allow uWSGI to reload when the specified file/folder is modified or touched. https://uwsgi-docs.readthedocs.io/en/latest/Options.html#touch-reload
--touch-reload=/path/to/file.txt
I think you can only do this with the Apache Webserver. Refer to the Flask documentation.
I haven't tried it (yet), but when you have deployed your new code any small change in the wsgi-file should automatically reload the code.
You mentioned two requirements
I have a flask server deployed
I would assume you mean it is deployed in a production environment. This automatically rules out debug-mode from the development server, because it is not stable, efficient or secure for production use.
Without rerunning the flask server
This rules out autoreload, because this will completely restart your server. Any requests that come in until the server is ready again will fail.
One way of going about is by running your application with debug mode ON through app.run(debug=True)
The problem with this approach is that your application would be exposed over the internet with the application's internal debugger on which shouldn't be done.
A better way I can think of is to call the functions you need to change frequently from a different file other than where your core flask code exists and change in that file whenever needed. This way you don't need to change your Flask code and you won't need to restart the application
Edit:
A sample Flask route would be
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
# Route's business logic usually goes here
return data
Now, instead of writing your application's business logic in the same file as your route, you could simply write it in a different file as follows and import it in the file with the route:
File with the business logic
def process_hello_world(params):
# Write your business logic here which you want to change without reloading the application
return data
And in the application file with the route call the business logic as follows:
from flask import Flask
from
app = Flask(__name__)
#app.route('/')
def hello_world():
data = process_hello_world()
return data
This question already has an answer here:
Capture arbitrary path in Flask route
(1 answer)
Closed 5 years ago.
In Flask, is it possible to have a generic endpoint which can serve different requests, I take an example, suppose I have a handler for "/" and I want that all request is handled by this handler to generate a reply. A request like "/person/767" or "/car/324" should also handled by the same endpoint and it is going to generate the reply base on resource requested. Is that possible and if yes, how ?
If you want an endpoint to literally capture everything after a particular slash, you can use a path placeholder in your route definition.
#app.route('/<path:path>')
A more detailed example in this answer:
Capture Arbitrary Path in Flask Route
You can register multiple routes to one view function
from flask import Flask
app = Flask(__name__)
#app.route('/')
#app.route('/car/<id>')
#app.route('/person/<id>')
def generic_endpoint(id=None):
...
or, as pointed out by #sql_knievel, use <path:path>.
I am trying to use WebApp2 outside of AppEngine and can't find anywhere in the documentation how to set up static routes to files.
For example, I have the following folder structure
Presentation
-->js
-->-->main.js
-->templates
-->-->index.html (loaded via Jinja)
How do I reference the main.js as using ../js/main.js gives me a 404
Here's the documentation that deals with this: Quick start (to use webapp2 outside of App Engine). Did this not work?
Serving static files should occur outside of your WSGI application (the webapp2 app), so it depends on what server you are using to run your webapp2 app (which is a WSGI app), because that server will need to be configured to serve the static files. Could you please add to your question what kind of server you are using, and/or how you are running the webapp2 app?
Appreciate your response, found similar after much digging. Problem was my lack of understanding of exactly what WebApp2 was as normal point AppEngine Dev App Server at it.
I only need a simple HTTP server, so doing the following
static_app = StaticURLParser("Presentation/")
# Create a cascade that looks for static files first, then tries the webapp
app = Cascade([static_app, web_app])
def main():
httpserver.serve(app, host='127.0.0.1', port='8080')
if __name__ == '__main__':
main()
and then run python main.py
I am trying to have one service which will fulfill two related functions. I would like to have something like this for my REST api:
/route1/get/as_text
/route2/get/as_json
In nodejs, you can pass off a collection of routes from some base URL by saying:
app.use('/route1/', route1.js)
app.use('/route2/', route2.js)
and then the route1.js will have routes defined like this:
app.router('/as_text', function(){//some stuff})
When I do this, can define a set of routes, that all have /route1/ as the basis of the URL. I would like to do something similar in flask, where I just define the first section of the url, and add all logic of that section of the API into a file which is separate to another section of the api.
Is this possible in flask? Or should I look for a new approach?
You'll want to take a look at Blueprints.
When defining your application, you can register Blueprints with a path prefix:
app = Flask(__name__, template_folder='views')
app.register_blueprint(controllers.route1, url_prefix="/route1")
app.register_blueprint(controllers.route2, url_prefix="/route2")
Then define the controllers for these routes in separate files.
route1 = Blueprint('route1', __name__, template_folder='views')
#route1.route('/get/as_text',methods=['GET'])
def get_as_text_route():
return json.jsonify(data="my data")
You could also checkout Flask Restful for creating REST APIs in with Flask.