From 488116b532e9a58ad49f8c35e1dff1fdab16bc73 Mon Sep 17 00:00:00 2001 From: Giacomo Licari Date: Wed, 28 Feb 2024 14:21:12 +0100 Subject: [PATCH] Add migrations --- api/api/api.py | 6 ++--- api/api/services/database.py | 6 ++--- api/migrations/versions/71441c34724e_.py | 32 ++++++++++++++++++++++++ api/scripts/run_migrations.sh | 14 +++++++++++ api/scripts/run_test_env.sh | 23 ----------------- api/tests/conftest.py | 2 ++ api/tests/temp_env_var.py | 2 +- api/tests/test_database.py | 8 +++--- 8 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 api/migrations/versions/71441c34724e_.py create mode 100644 api/scripts/run_migrations.sh delete mode 100644 api/scripts/run_test_env.sh diff --git a/api/api/api.py b/api/api/api.py index bff7e1d..b1c36b6 100644 --- a/api/api/api.py +++ b/api/api/api.py @@ -2,10 +2,11 @@ from flask import Flask from flask_cors import CORS +from flask_migrate import Migrate from .routes import apiv1 from .services import Cache, Web3Singleton -from .services.database import db, migrate +from .services.database import db def setup_logger(log_level): @@ -39,8 +40,7 @@ def create_app(): with app.app_context(): db.init_app(app) - migrate.init_app(app, db) - db.create_all() # Create database tables for our data models + Migrate(app, db) # Initialize Web3 class w3 = Web3Singleton(app.config['FAUCET_RPC_URL'], app.config['FAUCET_PRIVATE_KEY']) diff --git a/api/api/services/database.py b/api/api/services/database.py index 17a93d2..88d53df 100644 --- a/api/api/services/database.py +++ b/api/api/services/database.py @@ -1,10 +1,8 @@ import sqlite3 -from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() -migrate = Migrate() class Database: @@ -68,8 +66,8 @@ def delete(self, commit=True): class AccessKey(BaseModel): __tablename__ = "access_keys" access_key_id = db.Column(db.String(16), primary_key=True) - secret_access_key = db.Column(db.String(32)) - enabled = db.Column(db.Boolean(), default=True) + secret_access_key = db.Column(db.String(32), nullable=False) + enabled = db.Column(db.Boolean(), default=True, nullable=False) def __repr__(self): return f"" diff --git a/api/migrations/versions/71441c34724e_.py b/api/migrations/versions/71441c34724e_.py new file mode 100644 index 0000000..5360806 --- /dev/null +++ b/api/migrations/versions/71441c34724e_.py @@ -0,0 +1,32 @@ +"""empty message + +Revision ID: 71441c34724e +Revises: +Create Date: 2024-02-28 14:11:13.601403 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '71441c34724e' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('access_keys', + sa.Column('access_key_id', sa.String(length=16), nullable=False), + sa.Column('secret_access_key', sa.String(length=32), nullable=False), + sa.Column('enabled', sa.Boolean(), nullable=False), + sa.PrimaryKeyConstraint('access_key_id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('access_keys') + # ### end Alembic commands ### diff --git a/api/scripts/run_migrations.sh b/api/scripts/run_migrations.sh new file mode 100644 index 0000000..6f1ab68 --- /dev/null +++ b/api/scripts/run_migrations.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -x + +# DB MIGRATIONS: +FLASK_APP=api FAUCET_DATABASE_URI=sqlite:///:memory python3 -m flask db init # only the first time we initialize the DB +FLASK_APP=api FAUCET_DATABASE_URI=sqlite:///:memory python3 -m flask db migrate +# Reflect migrations onto the database: +# FLASK_APP=api python3 -m flask db upgrade + +# Valid SQLite URL forms are: +# sqlite:///:memory: (or, sqlite://) +# sqlite:///relative/path/to/file.db +# sqlite:////absolute/path/to/file.db \ No newline at end of file diff --git a/api/scripts/run_test_env.sh b/api/scripts/run_test_env.sh deleted file mode 100644 index 9ca35df..0000000 --- a/api/scripts/run_test_env.sh +++ /dev/null @@ -1,23 +0,0 @@ -touch /tmp/faucet_test.db - -# !! PRIVATE KEY FOR TEST PURPOSE ONLY !! -# 0x21b1ae205147d4e2fcdee7b3fc762aa21f955f3dace8a185306ac104be797081 -# !! DO NOT USE IN ANY OTHER CONTEXTS !! - -FAUCET_RPC_URL=https://rpc.chiadochain.net \ -FAUCET_PRIVATE_KEY="0x21b1ae205147d4e2fcdee7b3fc762aa21f955f3dace8a185306ac104be797081" \ -FAUCET_CHAIN_ID=10200 \ -FAUCET_DATABASE_URI=sqlite:///tmp/faucet_test.db \ -CAPTCHA_VERIFY_ENDPOINT=localhost \ -CAPTCHA_SECRET_KEY=testkey \ -python3 -m flask --app api run --port 8000 - -# DB MIGRATIONS: -## Generate migrations -### ENV_VARIABLES python3 -m flask --app api db init -### ENV_VARIABLES python3 -m flask --app api db migrate - -# Valid SQLite URL forms are: -# sqlite:///:memory: (or, sqlite://) -# sqlite:///relative/path/to/file.db -# sqlite:////absolute/path/to/file.db \ No newline at end of file diff --git a/api/tests/conftest.py b/api/tests/conftest.py index 22420b4..68082ed 100644 --- a/api/tests/conftest.py +++ b/api/tests/conftest.py @@ -1,6 +1,7 @@ import os import pytest +from flask_migrate import upgrade from temp_env_var import (CAPTCHA_TEST_RESPONSE_TOKEN, ERC20_TOKEN_ADDRESS, ERC20_TOKEN_AMOUNT, NATIVE_TOKEN_ADDRESS, NATIVE_TOKEN_AMOUNT, NATIVE_TRANSFER_TX_HASH, @@ -30,6 +31,7 @@ def app(self, mocker): mocker = self._mock(mocker, TEMP_ENV_VARS) app = self._create_app() with app.app_context(): + upgrade() yield app @pytest.fixture diff --git a/api/tests/temp_env_var.py b/api/tests/temp_env_var.py index ca6e29c..4122565 100644 --- a/api/tests/temp_env_var.py +++ b/api/tests/temp_env_var.py @@ -23,7 +23,7 @@ 'FAUCET_PRIVATE_KEY': token_bytes(32).hex(), 'FAUCET_RATE_LIMIT_TIME_LIMIT_SECONDS': '10', 'FAUCET_ENABLED_TOKENS': json.dumps(FAUCET_ENABLED_TOKENS), - 'FAUCET_DATABASE_URI': 'sqlite:///', # run in-memory + 'FAUCET_DATABASE_URI': 'sqlite:///:memory', # run in-memory 'CAPTCHA_SECRET_KEY': CAPTCHA_TEST_SECRET_KEY } diff --git a/api/tests/test_database.py b/api/tests/test_database.py index b70ff5e..3e9ad4f 100644 --- a/api/tests/test_database.py +++ b/api/tests/test_database.py @@ -1,15 +1,13 @@ from conftest import BaseTest -# from mock import patch -from temp_env_var import (CAPTCHA_TEST_RESPONSE_TOKEN, ERC20_TOKEN_ADDRESS, - ERC20_TOKEN_AMOUNT, NATIVE_TOKEN_ADDRESS, - NATIVE_TOKEN_AMOUNT, NATIVE_TRANSFER_TX_HASH, - TEMP_ENV_VARS, TOKEN_TRANSFER_TX_HASH, ZERO_ADDRESS) from api.services.database import AccessKey from api.utils import generate_access_key class TestDatabase(BaseTest): + + # db.create_all() # Create database tables for our data models + def test_models(self, client): access_key_id, secret_access_key = generate_access_key() assert len(access_key_id) == 16