Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/app/express-4.19.2
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerthome committed Jun 26, 2024
2 parents 3e8ee13 + 6451a89 commit 9a291c9
Show file tree
Hide file tree
Showing 135 changed files with 11,617 additions and 39,909 deletions.
12 changes: 12 additions & 0 deletions .github/ISSUE_TEMPLATE/post-an-open-role.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
name: Post an open role
about: Recruit volunteers for specific open roles template
title: 'HUU: Open Role for: [Replace with NAME OF ROLE]'
labels: 'Complexity: Small, feature: recruitment, role: missing'
assignees: ''

---

<img src="https://user-images.githubusercontent.com/26660349/114799694-38cb3a80-9d66-11eb-8b08-78bdc1b653b3.png" />

[INSERT DRAFT FROM THE Recruit volunteers for team open roles issue]
14 changes: 7 additions & 7 deletions .github/workflows/build-deploy-ec2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: 'pip'
python-version: "3.10"
cache: "pip"
- name: Upgrade pip
run: python -m pip install --upgrade pip
- name: Build API Deployment Package
Expand All @@ -51,12 +51,12 @@ jobs:
shell: bash
working-directory: ./app
steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.x
uses: actions/setup-node@v3
- uses: actions/checkout@v4
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: "16.x"
cache: 'npm'
node-version: 20
cache: "npm"
cache-dependency-path: app/package-lock.json
- name: Run npm CI
run: npm ci
Expand Down
17 changes: 9 additions & 8 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
branches: [main]
# This is also a reusable workflow that can be called from other workflows
workflow_call:
workflow_dispatch:
jobs:
test-api:
runs-on: ubuntu-latest
Expand All @@ -19,8 +20,8 @@ jobs:
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: 'pip'
python-version: "3.10"
cache: "pip"
- name: Upgrade pip
run: python -m pip install --upgrade pip
- name: Install API dev Dependencies
Expand All @@ -45,12 +46,12 @@ jobs:
shell: bash
working-directory: ./app
steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.x
uses: actions/setup-node@v3
- uses: actions/checkout@v4
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: '16.x'
cache: 'npm'
node-version: 20
cache: "npm"
cache-dependency-path: app/package-lock.json
- name: Run npm CI
run: npm ci
Expand All @@ -62,4 +63,4 @@ jobs:
install: false
start: npm run dev
working-directory: ./app
wait-on: http://localhost:4040
wait-on: "http://[::1]:4040/"
47 changes: 16 additions & 31 deletions api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

This is the *Home Unite Us* web API server.
This is the _Home Unite Us_ web API server.

This server uses the [Connexion](https://github.com/zalando/connexion) framework on top of Flask.

Expand All @@ -24,12 +24,12 @@ Run `python -V` to check the Python version.

The API application configuration must be specified before running the application. Configuration variables can be specified either as environment variables, or as entries within a `.env` file located within the `api` directory. To get started, copy the values from one of these configurations into a `.env` file:

* `.env.dev.example`
* [Recommended] This is the easiest configuration to use. It enables debugging, and mocks third party API calls so no secrets are needed to run the API.
* `.env.staging.example`
* This configuration strips all mocking from the application, but allows debugging and other testing related features.
* `.env.prod.example`
* This configuration strips all mocking and strictly validates the configuration to ensure that debugging is disabled and that the deployment is production-ready.
- `.env.dev.example`
- [Recommended] This is the easiest configuration to use. It enables debugging, and mocks third party API calls so no secrets are needed to run the API.
- `.env.staging.example`
- This configuration strips all mocking from the application, but allows debugging and other testing related features.
- `.env.prod.example`
- This configuration strips all mocking and strictly validates the configuration to ensure that debugging is disabled and that the deployment is production-ready.

Using the `staging` or `production` configurations will require access to deployment secrets. If access to these secrets are needed to test a feature locally then you can request the secrets in the HUU slack channel.

Expand Down Expand Up @@ -78,19 +78,22 @@ To launch the tests, run `tox`.

`tox` will run the tests for this (`api`) project using `pytest` in an isolated virtual environment that is distinct from the virtual environment that you created following the instructions from [Usage - Development](#usage---development). By default `tox` will invoke `pytest` in `debug` mode, which uses 3rd party API mocking. The test cases can optionally be run without mocking by testing the application in `release` mode, using `tox -e releasetest` or `pytest --mode=release`.

### Alembic migrations
### Database Management

When changing the database, you can automatically generate an alembic migration. Simply change the model however you want in `database.py`, run `alembic revision --autogenerate -m <name_of_migration>` to generate a new migration, and then run `alembic upgrade head` to upgrade your database to the latest revision.
In the case of someone else adding a revision to the database, simply pull their changes to your repo and run `alembic upgrade head` to upgrade your local database to the latest revision.
Running the API requires an up-to-date version of the HomeUniteUs database. You can generate an empty database by running this command from the `api` directory with a virtual environment enabled.

`alembic upgrade head`

The current database version can be viewed using the `alembic current` command, or by inspecting the database `alembic_version` table. See the `model` [readme](./openapi_server/models/) for more information about the database project.

### Dependency Management

Core dependencies of this project are listed in `pyproject.toml` under the `[project]` table's `dependencies` key. Additionally, this project has two extra variants, `dev` and `prod`, that add to the core dependencies. The `dev` extra variant installs dependencies for developers. The `prod` extra variant installs dependencies for production.

To aid in testing and building a reproducible, predictable, and deterministic API, this project also includes auto-generated requirements files that contains a list of all core and transitive dependencies with pinned versions. These files are:

* `requirements.txt` for a base set dependencies
* `requirements-dev.txt` that also includes developer dependencies
- `requirements.txt` for a base set dependencies
- `requirements-dev.txt` that also includes developer dependencies

Developers will use `pip install -r requirements-dev.txt` in their own Python virtual environment when working on this API.

Expand Down Expand Up @@ -193,26 +196,8 @@ docker exec `docker ps -qf "ancestor=homeuniteus-api"` pytest

Debugging is enabled when using the `development` configuration. It can also be enabled on the `staging` configuration by setting the `FLASK_DEBUG` environment variable to `True`, or adding a `FLASK_DEBUG=True` to your local `.env` file. When debugging is enabled, the API server will automatically reload each time you save a change to the source code.

For Visual Studio Code users:

* Set breakpoint(s).
* Add the following config below to your `/.vscode/launch.json` configuration.

```json
{
"name": "Openapi_server module",
"type": "python",
"request": "launch",
"module": "openapi_server",
"justMyCode": false,
"cwd": "${workspaceFolder}/api"
}
```

With this configuration selecting "Run" -> "Start with Debugging" will start the API with the debugger enabled.

## Usage - Production

A WSGI server is needed to run our application. A WSGI (Web Server Gateway Interface) server is a bridge between a web server and web applications. The server handles requests, invokes the web application, translates responses back to HTTP, and also manages concurrency to ensure the server can handle multiple requests simultaneously.

While Flask does provide a built-in development server, it is not intended for production use. Therefore, we utilize a third-party, production-grade WSGI server to manage our application. Various options exist, but we've chosen `gunicorn`. `gunicorn` does not support Windows, but you can use another WSGI server like `waitress` if Windows support is needed.
Expand Down
1 change: 0 additions & 1 deletion api/alembic/README

This file was deleted.

15 changes: 10 additions & 5 deletions api/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,16 @@ def run_migrations_online() -> None:
"""
print("ONLINE")
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
# Check for an existing connection before creating a new engine.
# pytest-alembic will hook into alembic by creating a connection
# with the test engine configuration.
connectable = context.config.attributes.get("connection", None)
if connectable is None:
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)

with connectable.connect() as connection:
context.configure(
Expand Down
72 changes: 72 additions & 0 deletions api/alembic/versions/e4c8bb426528_add_user_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Add user types
Revision ID: e4c8bb426528
Revises: ec8b1c17739a
Create Date: 2024-03-10 21:47:13.942845
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import text
from openapi_server.models.user_roles import UserRole

# revision identifiers, used by Alembic.
revision = 'e4c8bb426528'
down_revision = 'ec8b1c17739a'
branch_labels = None
depends_on = None

def upgrade() -> None:
'''
1. Add one table:
1. role - Store available application user roles
2. Prepopulate the role table with four role types: Admin, Host, Guest, Coordinator
3. Update the user table to add the first, middle, last name, and role_id columns.
* All existing users will be given the first, last name "UNKNOWN"
* Assign all existing users to the Guest role.
4. Drop the host table.
* There is no way to map host users back to the user table. We would need a user id foreign
key, or at least an email address.
'''
role_table = op.create_table('role',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.bulk_insert(role_table,
[{'name': UserRole.ADMIN.value},
{'name': UserRole.HOST.value},
{'name': UserRole.GUEST.value},
{'name': UserRole.COORDINATOR.value}])
op.create_index(op.f('ix_role_id'), 'role', ['id'])

conn = op.get_bind()
guest_role_id = conn.execute(text("SELECT id FROM role WHERE name = 'Guest'")).fetchone()[0]

with op.batch_alter_table('user', schema=None) as batch_op:
# Each existing user will get the first and last names "Unknown" by default
# and they will be assigned to the "Guest" user role.
batch_op.add_column(sa.Column('firstName', sa.String(length=255), nullable=False, server_default='Unknown'))
batch_op.add_column(sa.Column('middleName', sa.String(length=255), nullable=True))
batch_op.add_column(sa.Column('lastName', sa.String(length=255), nullable=True))
batch_op.add_column(sa.Column('role_id', sa.Integer, nullable=False, server_default=str(guest_role_id)))
batch_op.create_foreign_key('fk_user_role_id', 'role', ['role_id'], ['id'])

op.drop_table('host')

def downgrade() -> None:
with op.batch_alter_table('user', schema=None) as batch_op:
batch_op.drop_constraint('fk_user_role_id', type_='foreignkey')
batch_op.drop_column('lastName')
batch_op.drop_column('middleName')
batch_op.drop_column('firstName')

op.drop_index(op.f('ix_role_id'), table_name='role')
op.drop_table('role')
op.create_table('host',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_host_id'), 'host', ['id'])
Loading

0 comments on commit 9a291c9

Please sign in to comment.