So you can keep your file structure with comments, nicely separating your dependencies from the dependencies of your dependencies. This way you'll have a much nicer time the day you need to remove one of them :)
And beware of git urls being replaced by egg names in the process.
I find it a lot pleasant to look up all routes at the same place rather than guessing or searching. Also, I give an explicit name to all endpoints.
I do the same with blueprints. Blueprints have their own urls.py, and blueprints don't specify the url prefix. For eg, a comment blueprint will define '/', rather than '/comments'. I leave the url prefix to the main application.
For migrations, I prefer alembic to sql migrations - https://alembic.readthedocs.org/en/latest/tutorial.html I find Alembic simpler than SQLAlchemy(without compromising on power). Alembic can autogenerate migrations based on your model definitions. The way I work is I add a new model, and then run alembic to autogenerate the migration. Same goes for altering models.
For settings, I maintain setting.py, dev_settings.py, prod_settings.py. settings.py contains all the common settings. If environment is not defined, I do a `from dev_settings import *`, else I do a relevant import for the environment.
I also prefer having BEFORE_REQUESTS, AFTER_REQUESTS, MIDDLEWARES, LOG_HANDLERS, TEMPLATE_FILTERS, CONTEXT_PROCESSORS, ERROR_HANDLERS... in settings, and in main.py, call the relevant functions. That way, I don't have to hunt down the codebase. For blueprints, I define the same variables in __init__.py.
Model forms are another time saver(use wtforms, or preferably flask-wtform)
from flask.ext.wtf import Form
from wtforms.ext.sqlalchemy.orm import model_form
import models
PostForm = model_form(models.Post, models.db.session, Form, field_args = {
'name': {'validators': []},
'title': {'validators': []},
'content': {'validators': []},
})
models.Post is flask-sqlalchemy model, models.db.session is sqlalcheymy session. You don't need to list all model fields for your model form. I find keeping models and forms in sync a pain. This way, I only keep the validations in sync(field_args isn't required - that's an example of adding validations).
I use flask-debugtoolbar for basic profiling and debugging. flask-webassets is awesome for managing assets and dynamic compilation. flask-script for writing manage.py jobs(python manage.py get_deps, python manage.py db_createall etc etc)
I use both Flask and Django(and Sinatra and Rails). I tend to like Flask more than Django. It's just that big applications tend to have similar structure.
Armin have done a great job with Flask. The framework is quite malleable. I have written both 1 file flask app with inline routes, as well as 'bake-my-own-framework' flask apps. I believe that's a good thing.
On the routes side it also means you don't fact around having to import a module to get your app - if you can instantiate the app (as it were) and then set up routes you can create a factory much more easily and pass it around with little worries - but anchored to a module import as in the docs is less than helpful
Would love to see or hear more about your default setups though. Is there an example in OSS?
1. Routes in a separate file. Check config/urls.py
2. Blueprints are level of abstraction. Check blueprints/post. It's a simple blogging app. Blueprints have their own forms, models, urls, views.
3. Add blueprints to the app under config/blueprints.py You can mount the blueprint at '/' or an url prefix viz '/posts'
4. Blueprints define their own hooks. Check blueprints/post/__init__.py for an example.
5. Schema migration using alembic. Write your model:
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
title = db.Column(db.String(200))
content = db.Column(db.Text)
def __init__(self, name, title, content):
self.name = name
self.title = title
self.content = content
Save your file and add the blueprint to config/blueprints.py(if it's a blueprint), and run:
alembic revision --autogenerate -m "Create post table."
Check the generated schema in migrate/versions/ Tweak the migration and then `alembic upgrade head`
6. Flask-WTF and wtforms in general used for validation.
7. settings.py used for hooks. See config/settings.py and main.py
main.py is the glue. The code is quite simple as it doesn't do much. Ignore manage.py. That's my personal scaffold generator(like rails). Also ignore the custom template formats. That again is my personal slimish jinja templates.
I use some variation of this template in my projects. This is just guidelines. You can modify it to your heart's content to suit your needs.
The biggest problem I have with Python frameworks is the fact that it's hard (at least for me) to configure server and just write aplications. I came from PHP background, where you install few packages, configure apache/nginx (which is quite fast) and things just work. I'm learning python for some time now, but I still can't create working python environment... I know django basics, and use its server for developing, but I don't know how to configure nginx on my VPS so I can have multiple python webapps (my simple apps, django apps, flask etc.). Someone has good resources for that (believe me, I read a lot of tutorials)?
Since most Python frameworks are just WSGI application (except when you go Tornado or Twisted route), you can easily apply deployment instruction for one framework with others. I've found Deploying Flask to be a good tutorial on how to deploy WSGI application:
There's also uWSGI, which is possibly the most underrated deployment option in Python world but Nginx has native support for it (and its documentation is pretty good nowadays):
It's the docs are poor, the actual procedure is very easy.
Eg. if you installed php on apache, your process may be to apt-get or build from source a mod_php then get the relevant LoadModule line into your apache config.
For python you'd do the same, except you'd use mod_wsgi instead of php.
Part of the problem with python is there are so many ways to achieve the same thing. No doubt others are reading this and thinking "no, you should do x" - hell i'm feeling that myself as i type! This highlights the fact there just is:
1) Too little documentation
2) Too little info on what approaches work best in what situations
I haven't yet deployed a big app with flask yet, but for my "playground" (Intranet App, very low load) I use Gunicorn (http://gunicorn.org/ ), which is extremely easy to set-up. For a deployment you would want to put nginx in front of it to serve static data.
If you just want do develop and test some things the server it comes with is absolutely enough and helps a lot with the debugging. Its as easy as typing "python myapp.py".
For deployment, it's also important to have something like nginx in front of Gunicorn to buffer requests from slow clients. Otherwise, this sort of thing can DoS your server pretty bad:
Skip it and go with uWSGI ;) Emperor mode is fantastic.
Say you have /srv/mysite/uwsgi.ini and /srv/myothersite/uwsgi.ini (uwsgi config files for two different sites) you can run uwsgi --emperor /srv/*/uwsgi.ini and bam, it'll launch processes for all your sites.
I found myself similarly vexed when I first tried to deploy a Django project. Turns out I was making the process far more complicated by trying to wrestle with mod_wsgi and Apache.
I found that nginx + FastCGI[1] was by far the easiest configuration to get up and running. Took about 5 minutes to install the relevant packages and hack out a working configuration.
When you used php, your application server(mod_php) and web server(apache) looked the same to you. With python wsgi applications(most of the web frameworks are wsgi compliant), you generally need a separate application server and a web server which talks with the application server. Application server can directly serve the application and static files, but it isn't advisable.
So, you run an nginx on port 80 https://gist.github.com/rahulkmr/5232161 and proxy_pass to your application server running on some other port(8080 in the example).
You have a lot of choices when it comes to application servers. What you use depends on your use case.
> but I don't know how to configure nginx on my VPS so I can have multiple python webapps (my simple apps, django apps, flask etc.).
Look up sites-available and sites-enabled for nginx.
Yes, I considered Webfraction. The thing is, I want to learn how to configure everyting by myself, because (1) I like learning and (2) I thnk it will be valuable lesson and let me understand better, how server work.
I'm more interested in nginx config, but I'll definetely read docs from the link you provided.
If the application in question is using WSGI to serve the content, I would e.g. advise to use nginx's built-in uwsgi protocol support (here 'uwsgi' denoting protocol and not the popular application server uWSGI itself) for performance reasons. I agree with sirn that uWSGI should not be easily overlooked. :)
First of all copy the uwsgi_params file (available in the nginx directory of the uWSGI distribution [uWSGI here meaning the uWSGI application server, to be installed separately via your distro's package manager or e.g. pip]) into your Nginx configuration directory, then in a location directive in your Nginx configuration add:
uwsgi_pass unix:///tmp/uwsgi.sock;
include uwsgi_params;
– or if you are using TCP sockets,
uwsgi_pass 127.0.0.1:3031;
include uwsgi_params;
(I would advise the former for performance reasons (unix sockets are faster))
Then simply reload Nginx and you are ready to rock your uWSGI powered applications through Nginx.
Here are my nginx relevant directives - in server {} scope,
set $server_root /home/z/www/<basically,your_web_root>;
set $uwsgi_socket unix:$server_root/backend/var/uwsgi.sock;
Then (still in server {} scope),
location /api { # my flask app serves <domain>.tld/api
uwsgi_pass $uwsgi_socket;
include uwsgi_params;
}
That's it! That way I can reuse $uwsgi_socket as many times as is needed, etc.
The most simple way to launch the uWSGI app server would be to e.g.
So we add a parent directory ("lba" containing the actual application files, e.g. __init__.py (can be empty) so that the directory could be imported (lba:app in uWSGI launch), etc.), tell uWSGI that this is to be the parent uwsgi process (-M), point it to its socket (-s), set number or processes (-p), tell it to actually load our 'WSGI module' (-w), and supply other per-application parameters which are not necessary if you just want to test things out.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
That way you can test the sample app by simply sudo service nginx reload and ./test.sh (you might need sudo for the latter, too; also, might need to touch ../var/uwsgi.sock and look into uwsgi --help | grep "user") You can then put the test.sh (or the uwsgi call line itself) into e.g. supervisor - if the user privilege nuances are sorted out, you more or less have a production-worth setup (as far as nginx <-> uwsgi <-> your app is concerned), methinks.
edit sirn and antihero make a good point about Emperor mode
Actually, for anything that resembles production environment, I'd recommend using uWSGI in Emperor mode[1] to manage its instance than using Supervisor. Emperor mode will gracefully reload the app if config file's modification time changed (via `touch`) or stop and start the process automatically if you remove or add a configuration file.
My setup usually uses Upstart[2] (Ubuntu) or init script (Debian, etc.) to run uWSGI Emperor and make it scan /etc/uwsgi. When I need to deploy a new version, I just push the code then `touch /etc/uwsgi/myapp.ini` and my app is live with the code I just pushed.
I have nginx + gunicorn controlled by supervisord running and I must admit coming from LAMP it went not as smooth as I hoped.
For me the main problem was that all these parts have to be configured correctly or nothing much will happen at all. My advice is to first set up a static site in nginx, then try starting your project (using gunicorn) from the command line. Once your sure that both nginx and gunicorn work and know how to do it you can Google around for a supervisord + gunicorn tutorial for managing your apps.
All I can say is: keep at it. If you plan on using Django in the long term, you'll eventually get to the point where you know the steps and they don't seem that bad anymore.
I'd like to quickly plug Flask-Admin here, it's a much nicer experience than writing constant CRUD code for your administrative interface: https://github.com/MrJoes/Flask-Admin/
So I've always wanted to start learnin some python and python web dev. I've only done webdev in node.js so far, and now I have the question : Django or Flask?
Question: Is there a way to create application modules in the same style of Django modules (shippable extensions to an application) in Flask?
I've read about Flask blueprints, but that didn't seem to have the same angle... seemed to be more shippable libraries rather than a module of an application.
Blueprints are the same angle(better IMO). Develop the blueprint as a standalone module[1](templates, url rules, static files, before handlers...), and the mount it on the main application.
[1] Not python modules. I say module in the abstraction sense.
For eg, you can create a blueprint comments, define url rules('/', '/new', ':id/edit'...), add authentication to before handler(check before create, delete, edit), and then mount it on the main application.
You can have blueprints which are self contained modules(comments), blueprints which just add jinja extensions, blueprints which bring in static assets etc etc. What does Django apps do which blueprints don't?
> I thought Flask was a minimal micro framework but this looks as bloated as Django.
What kind of web applications have you written, and in what language/frameworks? My experience doesn't match yours. Flask is minimal in the sense that it doesn't add ORM, auth, assets etc to the core framework. There is nothing bloated about Flask, or even Django.
I think the fact that the tutorial shows off tons of plugins is a little confusing in this case. They aren't necessary at all and with them, it does look bloated.
That's to be expected. Flask builds on top of Werkzeug, itsdangerous and blinker whereas Bottle reimplements part of what Flask and the dependency libraries provides itself. However for the vast majority of applications having strong foundations to build upon is the right thing to do.
The difference between Flask's and Bottle's ram usage will be negligible. Out of box, flask is a wrapper over werkzeug and ships with Jinja2. The main memory usage will come from other libraries and extensions, and your own application code.
I think this is a really bad advice. Instead create a file called requirements.txt and add the required livraries, one per line.
Then you can install it with
Edit: More information in the documentation[0][0]: http://www.pip-installer.org/en/latest/requirements.html