Skip to content

Commit b7397d4

Browse files
committed
Merge branch 'master' into issue-166-360Page
# Conflicts: # src/server/api/common_api.py
2 parents a7a9557 + b73a1c6 commit b7397d4

28 files changed

+1071
-45
lines changed

src/docker-compose.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
- postgres:/var/lib/postgresql/data
1111
environment:
1212
POSTGRES_PASSWORD: thispasswordisverysecure
13+
POSTGRES_DB: paws
1314

1415
server:
1516
container_name: paws-compose-server
@@ -23,7 +24,6 @@ services:
2324
environment:
2425
FLASK_ENV: development
2526

26-
2727
client:
2828
build: ./client
2929
container_name: paws-compose-client
@@ -35,8 +35,12 @@ services:
3535
- CHOKIDAR_USEPOLLING=true
3636
stdin_open: true
3737

38+
3839
#using named volumes fixs a windows docker bug relating to container permissions
3940
#https://stackoverflow.com/questions/49148754/docker-container-shuts-down-giving-data-directory-has-wrong-ownership-error-wh
4041
volumes:
4142
postgres:
42-
src_archive:
43+
src_archive:
44+
45+
46+

src/server/Dockerfile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
FROM python:3.7
22

3+
RUN apt-get update && apt-get install -y vim
4+
35
WORKDIR /app
46

57
ENV PYTHONDONTWRITEBYTECODE 1
@@ -32,6 +34,14 @@ RUN chmod 777 /paws-data-pipeline/server
3234

3335
WORKDIR /app
3436

35-
CMD python app.py
37+
# we may want to switch this to a script which logs output, etc?
38+
# CMD python app.py
39+
40+
RUN set FLASK_APP=server/app.py
41+
RUN export FLASK_APP
3642

43+
# This abomination ensures that the PG server has finished its restart cycle
44+
CMD echo "SLEEPING 10"; sleep 10; echo "WAKING"; alembic upgrade head ; python -m flask run --host=0.0.0.0 --no-reload
3745

46+
# --no-reload prevents Flask restart, which usually happens in middle of create_base_users()
47+
#TODO: SECURITY - ensure we are not running in debug mode in production

src/server/alembic.ini

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# A generic, single database configuration.
2+
3+
[alembic]
4+
# path to migration scripts
5+
script_location = alembic
6+
7+
# template used to generate migration files
8+
# file_template = %%(rev)s_%%(slug)s
9+
10+
# timezone to use when rendering the date
11+
# within the migration file as well as the filename.
12+
# string value is passed to dateutil.tz.gettz()
13+
# leave blank for localtime
14+
# timezone =
15+
16+
# max length of characters to apply to the
17+
# "slug" field
18+
# truncate_slug_length = 40
19+
20+
# set to 'true' to run the environment during
21+
# the 'revision' command, regardless of autogenerate
22+
# revision_environment = false
23+
24+
# set to 'true' to allow .pyc and .pyo files without
25+
# a source .py file to be detected as revisions in the
26+
# versions/ directory
27+
# sourceless = false
28+
29+
# version location specification; this defaults
30+
# to alembic/versions. When using multiple version
31+
# directories, initial revisions must be specified with --version-path
32+
# version_locations = %(here)s/bar %(here)s/bat alembic/versions
33+
34+
# the output encoding used when revision files
35+
# are written from script.py.mako
36+
# output_encoding = utf-8
37+
38+
# Container
39+
sqlalchemy.url = postgresql://postgres:thispasswordisverysecure@paws-compose-db/paws
40+
41+
# Local
42+
# sqlalchemy.url = postgresql://postgres:thispasswordisverysecure@localhost/paws
43+
44+
45+
[post_write_hooks]
46+
# post_write_hooks defines scripts or Python functions that are run
47+
# on newly generated revision scripts. See the documentation for further
48+
# detail and examples
49+
50+
# format using "black" - use the console_scripts runner, against the "black" entrypoint
51+
# hooks=black
52+
# black.type=console_scripts
53+
# black.entrypoint=black
54+
# black.options=-l 79
55+
56+
# Logging configuration
57+
[loggers]
58+
keys = root,sqlalchemy,alembic
59+
60+
[handlers]
61+
keys = console
62+
63+
[formatters]
64+
keys = generic
65+
66+
[logger_root]
67+
level = WARN
68+
handlers = console
69+
qualname =
70+
71+
[logger_sqlalchemy]
72+
level = WARN
73+
handlers =
74+
qualname = sqlalchemy.engine
75+
76+
[logger_alembic]
77+
level = INFO
78+
handlers =
79+
qualname = alembic
80+
81+
[handler_console]
82+
class = StreamHandler
83+
args = (sys.stderr,)
84+
level = NOTSET
85+
formatter = generic
86+
87+
[formatter_generic]
88+
format = %(levelname)-5.5s [%(name)s] %(message)s
89+
datefmt = %H:%M:%S

src/server/alembic/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generic single-database configuration.

src/server/alembic/env.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from logging.config import fileConfig
2+
3+
from sqlalchemy import engine_from_config
4+
from sqlalchemy import pool
5+
6+
from alembic import context
7+
8+
# this is the Alembic Config object, which provides
9+
# access to the values within the .ini file in use.
10+
config = context.config
11+
12+
# Interpret the config file for Python logging.
13+
# This line sets up loggers basically.
14+
fileConfig(config.config_file_name)
15+
16+
# add your model's MetaData object here
17+
# for 'autogenerate' support
18+
# from myapp import mymodel
19+
# target_metadata = mymodel.Base.metadata
20+
target_metadata = None
21+
22+
# other values from the config, defined by the needs of env.py,
23+
# can be acquired:
24+
# my_important_option = config.get_main_option("my_important_option")
25+
# ... etc.
26+
27+
28+
def run_migrations_offline():
29+
"""Run migrations in 'offline' mode.
30+
31+
This configures the context with just a URL
32+
and not an Engine, though an Engine is acceptable
33+
here as well. By skipping the Engine creation
34+
we don't even need a DBAPI to be available.
35+
36+
Calls to context.execute() here emit the given string to the
37+
script output.
38+
39+
"""
40+
url = config.get_main_option("sqlalchemy.url")
41+
context.configure(
42+
url=url,
43+
target_metadata=target_metadata,
44+
literal_binds=True,
45+
dialect_opts={"paramstyle": "named"},
46+
)
47+
48+
with context.begin_transaction():
49+
context.run_migrations()
50+
51+
52+
def run_migrations_online():
53+
"""Run migrations in 'online' mode.
54+
55+
In this scenario we need to create an Engine
56+
and associate a connection with the context.
57+
58+
"""
59+
connectable = engine_from_config(
60+
config.get_section(config.config_ini_section),
61+
prefix="sqlalchemy.",
62+
poolclass=pool.NullPool,
63+
)
64+
65+
with connectable.connect() as connection:
66+
context.configure(
67+
connection=connection, target_metadata=target_metadata
68+
)
69+
70+
with context.begin_transaction():
71+
context.run_migrations()
72+
73+
74+
if context.is_offline_mode():
75+
run_migrations_offline()
76+
else:
77+
run_migrations_online()

src/server/alembic/script.py.mako

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""${message}
2+
3+
Revision ID: ${up_revision}
4+
Revises: ${down_revision | comma,n}
5+
Create Date: ${create_date}
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
${imports if imports else ""}
11+
12+
# revision identifiers, used by Alembic.
13+
revision = ${repr(up_revision)}
14+
down_revision = ${repr(down_revision)}
15+
branch_labels = ${repr(branch_labels)}
16+
depends_on = ${repr(depends_on)}
17+
18+
19+
def upgrade():
20+
${upgrades if upgrades else "pass"}
21+
22+
23+
def downgrade():
24+
${downgrades if downgrades else "pass"}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Add pdp_users full_name
2+
3+
Revision ID: 36c4ecbfd11a
4+
Revises: 7138d52f92d6
5+
Create Date: 2020-12-18 15:28:17.367718
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "36c4ecbfd11a"
14+
down_revision = "7138d52f92d6"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
op.add_column("pdp_users", sa.Column("full_name", sa.String))
21+
22+
23+
def downgrade():
24+
pass
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""pdp_users.role FK from roles
2+
3+
Revision ID: 41da831646e4
4+
Revises: 72d50d531bd5
5+
Create Date: 2020-12-16 15:53:28.514053
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "41da831646e4"
14+
down_revision = "72d50d531bd5"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
op.drop_column("pdp_users", "role")
21+
op.add_column(
22+
"pdp_users", sa.Column("role", sa.Integer, sa.ForeignKey("pdp_user_roles._id"))
23+
)
24+
25+
26+
def downgrade():
27+
pass
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Add user journal table
2+
3+
Revision ID: 6b8cf99be000
4+
Revises: 36c4ecbfd11a
5+
Create Date: 2020-12-21 15:08:07.784568
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.sql import func
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "6b8cf99be000"
15+
down_revision = "36c4ecbfd11a"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
op.create_table(
22+
"pdp_user_journal",
23+
sa.Column("_id", sa.Integer, primary_key=True),
24+
sa.Column("stamp", sa.DateTime, nullable=False, server_default=func.now()),
25+
sa.Column("username", sa.String(50), nullable=False),
26+
sa.Column("event_type", sa.String(50)),
27+
sa.Column("detail", sa.String(120)),
28+
)
29+
30+
31+
def downgrade():
32+
pass
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""add uniqueness constraints
2+
3+
Revision ID: 7138d52f92d6
4+
Revises: f3d30db17bed
5+
Create Date: 2020-12-17 17:31:29.154789
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "7138d52f92d6"
14+
down_revision = "f3d30db17bed"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
op.create_unique_constraint("uq_username", "pdp_users", ["username"])
21+
op.create_unique_constraint("uq_role", "pdp_user_roles", ["role"])
22+
23+
24+
def downgrade():
25+
pass

0 commit comments

Comments
 (0)