diff --git a/CONTRIB.md b/CONTRIB.md index 9d9c752cc..826d820df 100644 --- a/CONTRIB.md +++ b/CONTRIB.md @@ -56,53 +56,66 @@ or ### Migrating the Database -If you e.g. add a new column or table, you'll need to migrate the database. +If you e.g. add a new column or table, you'll need to migrate the database using the Flask CLI. First we need to 'stamp' the current version of the database: -You can use the management interface to first generate migrations: +```sh +$ cd OpenOversight/ # change directory to source dir +$ flask db stamp head +``` + +(Hint: If you get errors when running `flask` commands, e.g. because of differing Python versions, you may need to run the commands in the docker container by prefacing them as so: `docker exec -it openoversight_web_1 flask db stamp head`) + +Next make your changes to the database models in `models.py`. You'll then generate the migrations: ```sh -$ python manage.py db migrate +$ flask db migrate ``` And then you should inspect/edit the migrations. You can then apply the migrations: ```sh -$ python manage.py db upgrade +$ flask db upgrade ``` -You can also downgrade the database using `python manage.py db downgrade`. +You can also downgrade the database using `flask db downgrade`. ## OpenOversight Management Interface -In addition to running the development server, `manage.py` (OpenOversight's management interface) can be used to do the following: +In addition to generating database migrations, the Flask CLI can be used to run additional commands: ```sh -$ python manage.py --------------------------------------------------------------------------------- -INFO in __init__ [/vagrant/OpenOversight/app/__init__.py:57]: -OpenOversight startup --------------------------------------------------------------------------------- -usage: manage.py [-?] - {runserver,db,shell,make_admin_user,link_images_to_department} - ... - -positional arguments: - {runserver,db,shell,make_admin_user,link_images_to_department} - runserver Runs the Flask development server i.e. app.run() - db Perform database migrations - shell Runs a Python shell inside Flask application context. - make_admin_user Add confirmed administrator account - link_images_to_department - Link existing images to first department - -optional arguments: - -?, --help show this help message and exit +$ flask --help +Usage: flask [OPTIONS] COMMAND [ARGS]... + + A general utility script for Flask applications. + + Provides commands from Flask, extensions, and the application. Loads the + application defined in the FLASK_APP environment variable, or from a + wsgi.py file. Setting the FLASK_ENV environment variable to 'development' + will enable debug mode. + + $ export FLASK_APP=hello.py + $ export FLASK_ENV=development + $ flask run + +Options: + --version Show the flask version + --help Show this message and exit. + +Commands: + db Perform database migrations. + link-images-to-department Link existing images to first department + link-officers-to-department Links officers and units to first department + make-admin-user Add confirmed administrator account + routes Show the routes for the app. + run Runs a development server. + shell Runs a shell in the app context. ``` In development, you can make an administrator account without having to confirm your email: ```sh -$ python manage.py make_admin_user +$ flask make-admin-user Username: redshiftzero Email: jen@redshiftzero.com Password: diff --git a/OpenOversight/app/__init__.py b/OpenOversight/app/__init__.py index a3ee12e48..b6c642d25 100644 --- a/OpenOversight/app/__init__.py +++ b/OpenOversight/app/__init__.py @@ -8,6 +8,7 @@ from flask_limiter.util import get_remote_address from flask_login import LoginManager from flask_mail import Mail +from flask_migrate import Migrate from .config import config @@ -86,6 +87,14 @@ def get_age_from_birth_year(birth_year): if birth_year: return int(datetime.datetime.now().year - birth_year) + # Add commands + Migrate(app, db) # Adds 'db' command + from .commands import (make_admin_user, link_images_to_department, + link_officers_to_department) + app.cli.add_command(make_admin_user) + app.cli.add_command(link_images_to_department) + app.cli.add_command(link_officers_to_department) + return app diff --git a/OpenOversight/manage.py b/OpenOversight/app/commands.py similarity index 78% rename from OpenOversight/manage.py rename to OpenOversight/app/commands.py index 8d24a6cdb..566e6294a 100644 --- a/OpenOversight/manage.py +++ b/OpenOversight/app/commands.py @@ -3,26 +3,16 @@ from getpass import getpass import sys -from flask_script import Manager, Shell -from flask_migrate import Migrate, MigrateCommand +import click +from flask.cli import with_appcontext +from flask import current_app -from app import app -from app.models import db, User +from .models import db, User -migrate = Migrate(app, db) -manager = Manager(app) -manager.add_command("db", MigrateCommand) - - -def make_shell_context(): - return dict(app=app, db=db) - - -manager.add_command("shell", Shell(make_context=make_shell_context)) - - -@manager.command +# @manager.command +@click.command() +@with_appcontext def make_admin_user(): "Add confirmed administrator account" while True: @@ -54,11 +44,13 @@ def make_admin_user(): db.session.add(u) db.session.commit() print("Administrator {} successfully added".format(username)) - app.logger.info('Administrator {} added with email {}'.format(username, - email)) + current_app.logger.info('Administrator {} added with email {}'.format(username, + email)) -@manager.command +# @manager.command +@click.command() +@with_appcontext def link_images_to_department(): """Link existing images to first department""" from app.models import Image, db @@ -73,7 +65,9 @@ def link_images_to_department(): db.session.commit() -@manager.command +# @manager.command +@click.command() +@with_appcontext def link_officers_to_department(): """Links officers and units to first department""" from app.models import Officer, Unit, db @@ -89,7 +83,3 @@ def link_officers_to_department(): else: print("Skipped! Object already assigned to department!") db.session.commit() - - -if __name__ == "__main__": - manager.run() diff --git a/OpenOversight/migrations/versions/59e9993c169c_change_faces_to_thumbnails.py b/OpenOversight/migrations/versions/59e9993c169c_change_faces_to_thumbnails.py index 99ffd0662..dc536a8cd 100644 --- a/OpenOversight/migrations/versions/59e9993c169c_change_faces_to_thumbnails.py +++ b/OpenOversight/migrations/versions/59e9993c169c_change_faces_to_thumbnails.py @@ -5,9 +5,14 @@ Create Date: 2018-06-04 19:04:23.524079 """ - -from app.models import Face, db -from app.utils import get_uploaded_cropped_image +from flask import current_app +import os +import sys +# Add our Flask app to the search paths for modules +sys.path.insert(0, os.path.dirname(current_app.root_path)) + +from app.models import Face, db # noqa: E402 +from app.utils import get_uploaded_cropped_image # noqa: E402 # revision identifiers, used by Alembic. diff --git a/requirements.txt b/requirements.txt index f511724b5..f691dbdf4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,6 @@ Flask-Limiter==1.0.1 Flask-Login==0.4.1 Flask-Mail==0.9.1 Flask-Migrate==2.1.1 -Flask-Script==2.0.6 Flask-SQLAlchemy==2.3.2 Flask-WTF==0.14.2 Pillow==5.1.0