Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Flask custom CLI commands for custom scripts #138

Merged
merged 52 commits into from
Feb 21, 2023
Merged

Conversation

lorenyu
Copy link
Contributor

@lorenyu lorenyu commented Feb 13, 2023

Ticket

Resolves #90

Changes

  • Use Flask custom CLI commands for custom scripts
  • Remove main() entry point from create_user_csv service
  • Remove script_utils
  • Rename api.route package to api.api, and organize all things related to blueprints together:
    • X_blueprint.py
    • X_commands.py
    • X_routes.py
    • X_schemas.py
  • Rewrite test_create_user_csv to use test_cli_runner rather than only test the service
  • Add migration to cascade on delete
  • Rewrite test_create_user_csv to truncate the user table rather than requiring an isolated db schema
  • Remove now unused isolated_db fixture
  • Remove unused transaction rollback functionality in db_session test fixture
  • Rename /user REST resource to /users

Other changes

  • Organize Makefile commands:
    • move setup-local to top
    • group openapi-spec with other CLI commands)
  • Install pytest-lazy-fixture dev dependency
  • Move empty_schema fixture to test_migrations, the only place it's used

Context for reviewers

This PR consolidates the way we run the API server and the way we run background scripts to both use Flask's create_app factory. This removes the need to have two separate main() entrypoints, two separate ways to initialize the database, logger, etc. To do this, we leverage Flask's built-in method of creating custom CLI commands which itself is based on the click library, a popular library for building Python command line applications that's more powerful than argparse. This allows us to remove the script_utils file.

This PR also renames the api.route package to api.api since we want to add "commands" to the user blueprint, so "route" is no longer an appropriate name that applies to everything in the blueprint. We could also consider other names like api.components or api.blueprints, and/or we could consider renaming the top level source code folder to something like src rather than api.

Finally, we made test_create_user_csv test things at using the test_cli_runner to be closer to the way we test routes using the test_client. This approach has more end-to-end test coverage.

Other tangential changes include making REST resources use plural names to follow REST resource naming conventions.

Testing

Running `make cmd args='--help' prints out

... a bunch of general help stuff ...
Commands:
  routes  Show the routes for the app.
  run     Run a development server.
  shell   Run a shell in the app context.
  spec    Show the OpenAPI spec.
  user    User commands

Running make cmd-user-create-csv args='--help' prints out

Usage: flask user create-csv [OPTIONS]

  Create a CSV of all users and their roles

Options:
  --dir TEXT       Directory to save output file in. Can be an S3 path (e.g.
                   's3://bucketname/folder/') Defaults to current directory
                   ('.').
  --filename TEXT  Filename to save output file as. Defaults to
                   '[timestamp]-user-roles.csv.
  --help           Show this message and exit.

Actually running it produces a file like

"User Name","Roles","Is User Active?"
"Jon Doe","","True"
"Jane Doe","","True"
"Jack Dougherty","","True"
"User One","USER","True"
"Player One","USER","True"
"Player Two","USER","True"
"Admin One","ADMIN","True"
"Admin Two","ADMIN","True"
"Godzilla Dinosaur","ADMIN USER","True"

(these were the users i had in my db)

@lorenyu lorenyu mentioned this pull request Feb 21, 2023
@lorenyu
Copy link
Contributor Author

lorenyu commented Feb 21, 2023

@chouinar ok, I made the changes we discussed and created follow-on tickets for:

Copy link
Contributor

@chouinar chouinar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@@ -33,6 +33,19 @@ else
PY_RUN_CMD := docker-compose run $(DOCKER_EXEC_ARGS) --rm $(APP_NAME) poetry run
endif

FLASK_CMD := $(PY_RUN_CMD) flask --env-file local.env
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something in the setup-local command?

Comment on lines 17 to 18
# First make sure the table is empty
db_session.query(User).delete()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call out that they're from other tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

@lorenyu lorenyu merged commit 000bced into main Feb 21, 2023
@lorenyu lorenyu deleted the lorenyu/scripts branch February 21, 2023 22:46
lorenyu added a commit that referenced this pull request Feb 22, 2023
In PR #138 we renamed the route package to api, which makes it api.api.
This PR renames the top level package to src to avoid naming issues and
to represent the idea that the application contains other things like
CLI commands / background jobs. We considered naming it app, but that
would conflict with the app folder at the repo root, and it would also
create ambiguity with the flask app variable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix background job script and consider using flask custom cli commands
2 participants