flask-bones An example of a large scale Flask application using blueprints and extensions. Setup Quickly run the project using docker and docker-compose: docker-compose up -d Create the database and seed it with some data: docker-compose run --rm app flask create-db docker-compose run --rm app flask populate-db --num_users 5 Download front-end dependencies with yarn: yarn install --modules-folder ./app/static/node_modules Configuration The following environment variables are optional: Name Purpose APP_NAME The name of the application. i.e Flask Bones MAIL_PORT The port number of an SMTP server. MAIL_SERVER The hostname of an SMTP server. MEMCACHED_HOST The hostname of a memcached server. MEMCACHED_PORT The port number of a memcached server. POSTGRES_HOST The hostname of a postgres database server. POSTGRES_PASS The password of a postgres database user. POSTGRES_PORT The port number of a postgres database server. POSTGRES_USER The name of a postgres database user. REDIS_HOST The hostname of a redis database server. REDIS_PORT The port number of a redis database server. SECRET_KEY A secret key required to provide authentication. SERVER_NAME The hostname and port number of the server. Features Caching with Memcached from app.extensions import cache # Cache something cache.set('some_key', 'some_value') # Fetch it later cache.get('some_key') Email delivery from app.extensions import mail from flask_mail import Message # Build an email msg = Message('User Registration', sender='admin@flask-bones.com', recipients=[user.email]) msg.body = render_template('mail/registration.mail', user=user, token=token) # Send mail.send(msg) Asynchronous job scheduling with RQ RQ is a simple job queue for python backed by redis. Define a job: @rq.job def send_email(msg): mail.send(msg) Start a worker: flask rq worker Queue the job for processing: send_email.queue(msg) Monitor the status of the queue: flask rq info --interval 3 For help on all available commands: flask rq --help Stupid simple user management from app.extensions import login_user, logout_user, login_required # Login user login_user(user) # You now have a global proxy for the user current_user.is_authenticated # Secure endpoints with a decorator @login_required # Log out user logout_user() Password security that can keep up with Moores Law from app.extensions import bcrypt # Hash password pw_hash = bcrypt.generate_password_hash('password') # Validate password bcrypt.check_password_hash(pw_hash, 'password') Easily swap between multiple application configurations from app.config import dev_config, test_config app = Flask(__name__) class dev_config(): DEBUG = True class test_config(): TESTING = True # Configure for testing app.config.from_object(test_config) # Configure for development app.config.from_object(dev_config) Form validation & CSRF protection with WTForms Place a csrf token on a form: {{ form.csrf_token }} Validate it: form.validate_on_submit() Rate-limit routes from app.extensions import limiter @limiter.limit("5 per minute") @auth.route('/login', methods=['GET', 'POST']) def login(): # ... return 'your_login_page_contents' Automated tests Run the test suite: pytest Use any relational database using the SQLAlchemy ORM from app.user.models import User # Fetch user by id user = User.get_by_id(id) # Save current state of user user.update() # Fetch a paginated set of users users = User.query.paginate(page, 50) Front-end asset management Download front-end dependencies with yarn: yarn install --modules-folder ./app/static/node_modules Merge and compress them together with Flask-Assets: flask assets build Version your database schema Display the current revision: flask db current Create a new migration: flask db revision Upgrade the database to a later version: flask db upgrade Internationalize the application for other languages (i18n) Extract strings from source and compile a catalog (.pot): pybabel extract -F babel.cfg -o i18n/messages.pot . Create a new resource (.po) for German translators: pybabel init -i i18n/messages.pot -d i18n -l de Compile translations (.mo): pybabel compile -d i18n Merge changes into resource files: pybabel update -i i18n/messages.pot -d i18n