-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
created seeder container for populating db with mock data (#61)
## Problem The development database does not have mock data to aid development. ## Solution * Created `app/api/seeder/Dockerfile.seed` for development database seeder. * Added `seeder` service in`docker-compose.yaml` - Service `api` now also depends on `seeder` service to ensure seeder is run * Seeder container uses SQLAlchemy ORM models and `get_db` generator from API * Added `seed` target in the project Makefile * Some users created for seeding db. ## Ticket URL https://mediform.atlassian.net/browse/MEDI-3 ## Documentation N/A ## Tests Run Executed `make all` and `make seeder` to test seeder. Could sign in using mock users.
- Loading branch information
Showing
8 changed files
with
201 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Dockerfile.seed for seeding development database | ||
FROM python:3.9.1-slim | ||
|
||
RUN mkdir -p /app/api | ||
WORKDIR /app/api | ||
|
||
COPY seeder/seeder_reqs.txt /app/api | ||
RUN pip install --no-cache-dir -r seeder_reqs.txt | ||
COPY main /app/api/ | ||
COPY models /app/api/ | ||
COPY seeder /app/api/ | ||
WORKDIR /app | ||
|
||
# Setup user to represent developer permissions in container | ||
ARG USERNAME=python | ||
ARG USER_UID=1000 | ||
ARG USER_GID=1000 | ||
RUN useradd -rm -d /home/$USERNAME -s /bin/bash -g root -G sudo -u $USER_UID $USERNAME | ||
USER $USERNAME | ||
|
||
EXPOSE 5000 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
from json import JSONDecodeError | ||
from passlib.hash import argon2 | ||
from typing import List, Dict | ||
|
||
from sqlalchemy.orm import Session | ||
from fastapi.testclient import TestClient | ||
|
||
from api.main.app import api | ||
from api.models import User | ||
from api.main.database import get_db | ||
|
||
from api.seeder.seeds.users import USERS | ||
|
||
def create_authed_client(email: str, password: str, client: TestClient): | ||
""" Create an authenticated client for testing | ||
Args: | ||
email (str): User email | ||
password (str): Plain text password | ||
client (FastAPI.TestClient): Test client to be authenticated | ||
Returns: | ||
FastAPI.TestClient: Authenticated test client | ||
""" | ||
|
||
# Get token | ||
print(f"Creating authed client for {email}") | ||
login_data = {"email": email, "password": password} | ||
r = client.post("/api/login", json=login_data) | ||
|
||
# Check if login was successful | ||
if r.status_code != 200: | ||
print("create_authed_client response: ", r.json()) | ||
raise Exception("Login failed") | ||
|
||
print("create_authed_client response: ", r.json()) | ||
token = r.json()["access_token"] | ||
|
||
# Add authorization token header | ||
client.headers = {"Authorization": f"Bearer {token}"} | ||
|
||
|
||
return client | ||
|
||
|
||
def create_users(users: List[Dict], db: Session) -> List[User]: | ||
""" Create users in database | ||
Args: | ||
users (List[Dict]): List of users to create | ||
db (Session): Database session | ||
Returns: | ||
List[User]: List of created users | ||
""" | ||
|
||
created_users = [] | ||
|
||
# Create users | ||
for user in users: | ||
|
||
# Check if user already exists | ||
user_obj = db.query(User).filter(User.email == user["email"]).first() | ||
if user_obj: | ||
print(f"User {user_obj.email} already exists") | ||
created_users.append(user_obj) | ||
continue | ||
|
||
# Hash password | ||
hashed_password = argon2.hash(user["password"]) | ||
# Create user | ||
user_obj = User( | ||
email=user["email"], | ||
hashed_password=hashed_password, | ||
) | ||
try: | ||
## Add user to database | ||
db.add(user_obj) | ||
db.commit() | ||
db.refresh(user_obj) | ||
print( | ||
f"User {user_obj.email} created with uuid: {user_obj.user_uuid}" | ||
) | ||
created_users.append(user_obj) | ||
except Exception as e: | ||
print(e) | ||
db.rollback() | ||
db.flush() | ||
print(f"User {user_obj.email} already exists") | ||
|
||
return created_users | ||
|
||
def seed_database(): | ||
""" Seed database with mock data. | ||
""" | ||
|
||
db = next(get_db()) | ||
|
||
# Create test client and check if healthy | ||
client = TestClient(api) | ||
r = client.get("/api/") | ||
if r.json()["status"] == "healthy": | ||
print("API is healthy") | ||
|
||
# Create users | ||
created_users = create_users(USERS, db) | ||
|
||
|
||
if __name__ == "__main__": | ||
seed_database() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
argon2-cffi==21.3.0 | ||
argon2-cffi-bindings==21.2.0 | ||
cffi==1.15.0 | ||
email-validator==1.2.1 | ||
fastapi==0.65.1 | ||
passlib==1.7.4 | ||
psycopg2-binary==2.8.6 | ||
py==1.11.0 | ||
pyasn1==0.4.8 | ||
python-dateutil==2.8.2 | ||
python-dotenv==0.20.0 | ||
python-editor==1.0.4 | ||
python-jose==3.3.0 | ||
requests==2.25.1 | ||
SQLAlchemy==1.4.15 | ||
typing_extensions==4.2.0 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
""" | ||
Mock data for user model | ||
""" | ||
|
||
|
||
DEFAULT_USER = { | ||
"email": "default_user@default.com", | ||
"password": "Password123!" | ||
} | ||
|
||
TEST_USER_1 = { | ||
"email": "not_bruce_wayne@gothamcity.com", | ||
"password": "B@tCaveSecret1" | ||
} | ||
|
||
TEST_USER_2 = { | ||
"email": "lethal@company.com", | ||
"password": "WeMetQu0ta!" | ||
} | ||
|
||
USERS = [DEFAULT_USER, TEST_USER_1, TEST_USER_2] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters