Skip to content

Commit

Permalink
Merge pull request #107 from uclahs-cds/aholmes-update-feature-flags
Browse files Browse the repository at this point in the history
Add Feature Flags module to Ligare.web and Ligare.platform
  • Loading branch information
aholmes authored Oct 4, 2024
2 parents 9250d40 + 62e47bd commit b015d00
Show file tree
Hide file tree
Showing 37 changed files with 2,419 additions and 592 deletions.
23 changes: 11 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@ TOX_DIR := .tox
DEFAULT_TARGET ?= dev
.DEFAULT_GOAL := $(DEFAULT_TARGET)


ifeq ($(DEFAULT_TARGET),dev)
BUILD_TARGET := $(SETUP_DEV_SENTINEL)
else ifeq ($(DEFAULT_TARGET),cicd)
BUILD_TARGET := $(SETUP_CICD_SENTINEL)
else
$(error DEFAULT_TARGET must be one of "dev" or "cicd")
endif


ACTIVATE_VENV := . $(VENV)/bin/activate
REPORT_VENV_USAGE := echo '\nActivate your venv with `. $(VENV)/bin/activate`'

Expand All @@ -73,6 +63,15 @@ SETUP_DEV_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/setup_dev_sentinel
SETUP_CICD_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/setup_cicd_sentinel
PYPROJECT_FILES_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/pyproject_sentinel

ifeq ($(DEFAULT_TARGET),dev)
BUILD_TARGET := $(SETUP_DEV_SENTINEL)
else ifeq ($(DEFAULT_TARGET),cicd)
BUILD_TARGET := $(SETUP_CICD_SENTINEL)
else
$(error DEFAULT_TARGET must be one of "dev" or "cicd")
endif


$(PYPROJECT_FILES_SENTINEL): $(VENV)
$(MAKE) $(PYPROJECT_FILES)
touch $@
Expand Down Expand Up @@ -196,10 +195,10 @@ test-bandit : $(VENV) $(BUILD_TARGET)
-r .

test-pytest : $(VENV) $(BUILD_TARGET)
-$(ACTIVATE_VENV) && \
$(ACTIVATE_VENV) && \
PYTEST_TARGET=$(PYTEST_TARGET) tox && PYTEST_EXIT_CODE=0 || PYTEST_EXIT_CODE=$$?; \
coverage html --data-file=$(REPORTS_DIR)/$(PYTEST_REPORT)/.coverage; \
junit2html $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.xml $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.html; \
junit2html $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.xml $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.html && \
exit $$PYTEST_EXIT_CODE

.PHONY: test test-pytest test-bandit test-pyright test-ruff test-isort
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ reportUnnecessaryTypeIgnoreComment = "information"
reportUnusedCallResult = "information"
reportMissingTypeStubs = "information"
reportWildcardImportFromLibrary = "warning"
reportDeprecated = "error"

[tool.pytest.ini_options]
pythonpath = [
Expand Down
9 changes: 9 additions & 0 deletions src/database/Ligare/database/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from Ligare.programming.config import AbstractConfig
from pydantic import BaseModel
from pydantic.config import ConfigDict
from typing_extensions import override


class DatabaseConnectArgsConfig(BaseModel):
Expand Down Expand Up @@ -36,6 +37,10 @@ def __init__(self, **data: Any):
elif self.connection_string.startswith("postgresql://"):
self.connect_args = PostgreSQLDatabaseConnectArgsConfig(**model_data)

@override
def post_load(self) -> None:
return super().post_load()

connection_string: str = "sqlite:///:memory:"
sqlalchemy_echo: bool = False
# the static field allows Pydantic to store
Expand All @@ -44,4 +49,8 @@ def __init__(self, **data: Any):


class Config(BaseModel, AbstractConfig):
@override
def post_load(self) -> None:
return super().post_load()

database: DatabaseConfig
11 changes: 9 additions & 2 deletions src/database/Ligare/database/dependency_injection.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
from injector import Binder, CallableProvider, Injector, Module, inject, singleton
from injector import Binder, CallableProvider, Injector, inject, singleton
from Ligare.database.config import Config, DatabaseConfig
from Ligare.database.engine import DatabaseEngine
from Ligare.database.types import MetaBase
from Ligare.programming.config import AbstractConfig
from Ligare.programming.dependency_injection import ConfigModule
from Ligare.programming.patterns.dependency_injection import ConfigurableModule
from sqlalchemy.orm.scoping import ScopedSession
from sqlalchemy.orm.session import Session
from typing_extensions import override

from .config import DatabaseConfig


class ScopedSessionModule(Module):
class ScopedSessionModule(ConfigurableModule):
"""
Configure SQLAlchemy Session depedencies for Injector.
"""

@override
@staticmethod
def get_config_type() -> type[AbstractConfig]:
return DatabaseConfig

_bases: list[MetaBase | type[MetaBase]] | None = None

@override
Expand Down
209 changes: 0 additions & 209 deletions src/database/Ligare/database/migrations/alembic.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def _run_migrations(
try:
if connection.engine.name == "postgresql":
_ = connection.execute(
f"SET search_path TO {','.join(schemas)},public;"
f"SET search_path TO {','.join(schemas + ['public'])};"
)
context.run_migrations()
except ProgrammingError as error:
Expand Down
4 changes: 2 additions & 2 deletions src/database/Ligare/database/schema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
_dialect_type_map = {"sqlite": SQLiteDialect, "postgresql": PostgreSQLDialect}


def get_type_from_dialect(dialect: Dialect):
def get_type_from_dialect(dialect: Dialect) -> PostgreSQLDialect | SQLiteDialect:
if not _dialect_type_map.get(dialect.name):
raise ValueError(
f"Unexpected dialect with name `{dialect.name}`. Expected one of {list(_dialect_type_map.keys())}."
Expand All @@ -16,6 +16,6 @@ def get_type_from_dialect(dialect: Dialect):
return _dialect_type_map[dialect.name](dialect)


def get_type_from_op(op: Operations):
def get_type_from_op(op: Operations) -> PostgreSQLDialect | SQLiteDialect:
dialect: Dialect = op.get_bind().dialect
return get_type_from_dialect(dialect)
8 changes: 4 additions & 4 deletions src/database/Ligare/database/schema/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class DialectBase(ABC):
supports_schemas: bool = False

@staticmethod
def get_schema(meta: MetaBase):
def get_schema(meta: MetaBase) -> str | None:
table_args = hasattr(meta, "__table_args__") and meta.__table_args__ or None

if isinstance(table_args, dict):
Expand All @@ -21,7 +21,7 @@ def iterate_table_names(
dialect: "DialectBase",
schema_tables: dict[MetaBase, list[str]],
table_name_callback: TableNameCallback,
):
) -> None:
"""
Call `table_name_callback` once for every table in every Base.
Expand All @@ -40,13 +40,13 @@ def iterate_table_names(
dialect_schema, full_table_name, base_table, meta_base
)

def get_dialect_schema(self, meta: MetaBase):
def get_dialect_schema(self, meta: MetaBase) -> str | None:
if self.supports_schemas:
return DialectBase.get_schema(meta)

return None

def get_full_table_name(self, table_name: str, meta: MetaBase):
def get_full_table_name(self, table_name: str, meta: MetaBase) -> str:
"""
If the dialect supports schemas, then the table name does not have the schema prepended.
In dialects that don't support schemas, e.g., SQLite, the table name has the schema prepended.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def test__LigareAlembic__passes_through_to_alembic_with_default_config_when_not_
)

ligare_alembic = LigareAlembic(None, MagicMock())
ligare_alembic._write_ligare_alembic_config = MagicMock() # pyright: ignore[reportPrivateUsage]
ligare_alembic.run()

assert alembic_main.called
Expand Down
Loading

0 comments on commit b015d00

Please sign in to comment.