Skip to content

Commit

Permalink
Merge pull request #30 from GSA-TTS/domain-language-update
Browse files Browse the repository at this point in the history
Update code to reflect domain language
  • Loading branch information
akuny authored Feb 14, 2024
2 parents 91e20a8 + b1237ea commit 736cc7b
Show file tree
Hide file tree
Showing 19 changed files with 289 additions and 243 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Rename data_providers to data_producers and rename column in data_submissions
Revision ID: 342dce4f5753
Revises: 851709d3a162
Create Date: 2024-02-14 08:40:16.897824
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "342dce4f5753"
down_revision: Union[str, None] = "851709d3a162"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
op.rename_table("data_providers", "data_producers")
op.alter_column(
"data_submissions", "data_provider_id", new_column_name="data_producer_id"
)


def downgrade() -> None:
op.alter_column(
"data_submissions", "data_producer_id", new_column_name="data_provider_id"
)
op.rename_table("data_producers", "data_providers")
2 changes: 1 addition & 1 deletion alembic/versions/851709d3a162_add_report_column.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ def upgrade():
)


def add_column():
def downgrade():
op.drop_column("data_submissions", "report")
14 changes: 14 additions & 0 deletions documentation/terminology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# NAD Collaboration Hub Terminology

## Acronyms

- GIS: geographic information system
- NAD: National Address Database

## Key Concepts

- Data Producer: a representative from a state, local, or tribal government
who wants to submit address data for inclusion in the NAD.

- Data Submission: a GIS dataset that a Data Producer submits for inclusion
in the NAD.
6 changes: 3 additions & 3 deletions nad_ch/application/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Optional, Protocol
from nad_ch.application.dtos import DownloadResult
from nad_ch.domain.repositories import DataProviderRepository, DataSubmissionRepository
from nad_ch.domain.repositories import DataProducerRepository, DataSubmissionRepository


class Logger(Protocol):
Expand Down Expand Up @@ -37,8 +37,8 @@ def run_load_and_validate(

class ApplicationContext:
@property
def providers(self) -> DataProviderRepository:
return self._providers
def producers(self) -> DataProducerRepository:
return self._producers

@property
def submissions(self) -> DataSubmissionRepository:
Expand Down
72 changes: 36 additions & 36 deletions nad_ch/application/use_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,42 @@
from nad_ch.application.interfaces import ApplicationContext
from nad_ch.application.view_models import (
get_view_model,
DataProviderViewModel,
DataProducerViewModel,
DataSubmissionViewModel,
)
from nad_ch.domain.entities import DataProvider, DataSubmission
from nad_ch.domain.entities import DataProducer, DataSubmission


def add_data_provider(
ctx: ApplicationContext, provider_name: str
) -> DataProviderViewModel:
if not provider_name:
ctx.logger.error("Provider name required")
def add_data_producer(
ctx: ApplicationContext, producer_name: str
) -> DataProducerViewModel:
if not producer_name:
ctx.logger.error("Producer name required")
return

matching_provider = ctx.providers.get_by_name(provider_name)
if matching_provider:
ctx.logger.error("Provider name must be unique")
matching_producer = ctx.producers.get_by_name(producer_name)
if matching_producer:
ctx.logger.error("Producer name must be unique")
return

provider = DataProvider(provider_name)
ctx.providers.add(provider)
ctx.logger.info("Provider added")
producer = DataProducer(producer_name)
saved_producer = ctx.producers.add(producer)
ctx.logger.info("Producer added")

return get_view_model(provider)
return get_view_model(saved_producer)


def list_data_providers(ctx: ApplicationContext) -> List[DataProviderViewModel]:
providers = ctx.providers.get_all()
ctx.logger.info("Data Provider Names:")
for p in providers:
def list_data_producers(ctx: ApplicationContext) -> List[DataProducerViewModel]:
producers = ctx.producers.get_all()
ctx.logger.info("Data Producer Names:")
for p in producers:
ctx.logger.info(p.name)

return get_view_model(providers)
return get_view_model(producers)


def ingest_data_submission(
ctx: ApplicationContext, file_path: str, provider_name: str
ctx: ApplicationContext, file_path: str, producer_name: str
) -> DataSubmissionViewModel:
if not file_path:
ctx.logger.error("File path required")
Expand All @@ -50,20 +50,20 @@ def ingest_data_submission(
ctx.logger.error("Invalid file format. Only ZIP or CSV files are accepted.")
return

provider = ctx.providers.get_by_name(provider_name)
if not provider:
ctx.logger.error("Provider with that name does not exist")
producer = ctx.producers.get_by_name(producer_name)
if not producer:
ctx.logger.error("Producer with that name does not exist")
return

try:
filename = DataSubmission.generate_filename(file_path, provider)
filename = DataSubmission.generate_filename(file_path, producer)
ctx.storage.upload(file_path, filename)

submission = DataSubmission(filename, provider)
ctx.submissions.add(submission)
ctx.logger.info(f"Submission added: {submission.filename}")
submission = DataSubmission(filename, producer)
saved_submission = ctx.submissions.add(submission)
ctx.logger.info(f"Submission added: {saved_submission.filename}")

return get_view_model(submission)
return get_view_model(saved_submission)
except Exception as e:
ctx.storage.delete(filename)
ctx.logger.error(f"Failed to process submission: {e}")
Expand All @@ -80,18 +80,18 @@ def get_data_submission(
return get_view_model(submission)


def list_data_submissions_by_provider(
ctx: ApplicationContext, provider_name: str
def list_data_submissions_by_producer(
ctx: ApplicationContext, producer_name: str
) -> List[DataSubmissionViewModel]:
provider = ctx.providers.get_by_name(provider_name)
if not provider:
ctx.logger.error("Provider with that name does not exist")
producer = ctx.producers.get_by_name(producer_name)
if not producer:
ctx.logger.error("Producer with that name does not exist")
return

submissions = ctx.submissions.get_by_provider(provider)
ctx.logger.info(f"Data submissions for {provider.name}")
submissions = ctx.submissions.get_by_producer(producer)
ctx.logger.info(f"Data submissions for {producer.name}")
for s in submissions:
ctx.logger.info(f"{s.provider.name}: {s.filename}")
ctx.logger.info(f"{s.producer.name}: {s.filename}")

return get_view_model(submissions)

Expand Down
20 changes: 10 additions & 10 deletions nad_ch/application/view_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import json
import numpy as np
from typing import Union, List, Tuple
from nad_ch.domain.entities import Entity, DataProvider, DataSubmission
from nad_ch.domain.entities import Entity, DataProducer, DataSubmission


def get_view_model(entity: Union[Entity, List[Entity]]) -> Union[Entity, List[Entity]]:
Expand All @@ -12,7 +12,7 @@ def get_view_model(entity: Union[Entity, List[Entity]]) -> Union[Entity, List[En
get a static view model object that it can return to its caller.
"""
entity_to_vm_function_map = {
DataProvider: create_data_provider_vm,
DataProducer: create_data_producer_vm,
DataSubmission: create_data_submission_vm,
}

Expand All @@ -31,17 +31,17 @@ def get_view_model(entity: Union[Entity, List[Entity]]) -> Union[Entity, List[En


@dataclass
class DataProviderViewModel:
class DataProducerViewModel:
id: int
date_created: str
name: str


def create_data_provider_vm(provider: DataProvider) -> DataProviderViewModel:
return DataProviderViewModel(
id=provider.id,
date_created=present_date(provider.created_at),
name=provider.name,
def create_data_producer_vm(producer: DataProducer) -> DataProducerViewModel:
return DataProducerViewModel(
id=producer.id,
date_created=present_date(producer.created_at),
name=producer.name,
)


Expand All @@ -50,7 +50,7 @@ class DataSubmissionViewModel:
id: int
date_created: str
filename: str
provider_name: str
producer_name: str
report: str


Expand All @@ -65,7 +65,7 @@ def create_data_submission_vm(submission: DataSubmission) -> DataSubmissionViewM
id=submission.id,
date_created=present_date(submission.created_at),
filename=submission.filename,
provider_name=submission.provider.name,
producer_name=submission.producer.name,
report=report_json,
)

Expand Down
8 changes: 4 additions & 4 deletions nad_ch/config/development_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from nad_ch.application.interfaces import ApplicationContext
from nad_ch.infrastructure.database import (
create_session_factory,
SqlAlchemyDataProviderRepository,
SqlAlchemyDataProducerRepository,
SqlAlchemyDataSubmissionRepository,
)
from nad_ch.infrastructure.logger import BasicLogger
Expand Down Expand Up @@ -33,14 +33,14 @@
class DevLocalApplicationContext(ApplicationContext):
def __init__(self):
self._session_factory = create_session_factory(DATABASE_URL)
self._providers = self.create_provider_repository()
self._producers = self.create_producer_repository()
self._submissions = self.create_submission_repository()
self._logger = self.create_logger()
self._storage = self.create_storage()
self._task_queue = self.create_task_queue()

def create_provider_repository(self):
return SqlAlchemyDataProviderRepository(self._session_factory)
def create_producer_repository(self):
return SqlAlchemyDataProducerRepository(self._session_factory)

def create_submission_repository(self):
return SqlAlchemyDataSubmissionRepository(self._session_factory)
Expand Down
8 changes: 4 additions & 4 deletions nad_ch/config/development_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from nad_ch.application.interfaces import ApplicationContext
from nad_ch.infrastructure.database import (
create_session_factory,
SqlAlchemyDataProviderRepository,
SqlAlchemyDataProducerRepository,
SqlAlchemyDataSubmissionRepository,
)
from nad_ch.infrastructure.logger import BasicLogger
Expand Down Expand Up @@ -40,14 +40,14 @@ def get_credentials(service_name, default={}):
class DevRemoteApplicationContext(ApplicationContext):
def __init__(self):
self._session_factory = create_session_factory(DATABASE_URL)
self._providers = self.create_provider_repository()
self._producers = self.create_producer_repository()
self._submissions = self.create_submission_repository()
self._logger = self.create_logger()
self._storage = self.create_storage()
self._task_queue = self.create_task_queue()

def create_provider_repository(self):
return SqlAlchemyDataProviderRepository(self._session_factory)
def create_producer_repository(self):
return SqlAlchemyDataProducerRepository(self._session_factory)

def create_submission_repository(self):
return SqlAlchemyDataSubmissionRepository(self._session_factory)
Expand Down
8 changes: 4 additions & 4 deletions nad_ch/config/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from nad_ch.application.interfaces import ApplicationContext
from nad_ch.infrastructure.logger import BasicLogger
from tests.fakes_and_mocks import (
FakeDataProviderRepository,
FakeDataProducerRepository,
FakeDataSubmissionRepository,
FakeStorage,
)
Expand All @@ -17,14 +17,14 @@
class TestApplicationContext(ApplicationContext):
def __init__(self):
self._session = None
self._providers = self.create_provider_repository()
self._producers = self.create_producer_repository()
self._submissions = self.create_submission_repository()
self._logger = self.create_logger()
self._storage = self.create_storage()
self._task_queue = self.create_task_queue()

def create_provider_repository(self):
return FakeDataProviderRepository()
def create_producer_repository(self):
return FakeDataProducerRepository()

def create_submission_repository(self):
return FakeDataSubmissionRepository()
Expand Down
28 changes: 14 additions & 14 deletions nad_ch/controllers/cli.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import click
from nad_ch.application.use_cases import (
add_data_provider,
list_data_providers,
add_data_producer,
list_data_producers,
ingest_data_submission,
list_data_submissions_by_provider,
list_data_submissions_by_producer,
validate_data_submission,
)

Expand All @@ -16,34 +16,34 @@ def cli(ctx):

@cli.command()
@click.pass_context
@click.argument("provider_name")
def add_provider(ctx, provider_name):
@click.argument("producer_name")
def add_producer(ctx, producer_name):
context = ctx.obj
add_data_provider(context, provider_name)
add_data_producer(context, producer_name)


@cli.command()
@click.pass_context
def list_providers(ctx):
def list_producers(ctx):
context = ctx.obj
list_data_providers(context)
list_data_producers(context)


@cli.command()
@click.pass_context
@click.argument("file_path")
@click.argument("provider")
def ingest(ctx, file_path, provider):
@click.argument("producer")
def ingest(ctx, file_path, producer):
context = ctx.obj
ingest_data_submission(context, file_path, provider)
ingest_data_submission(context, file_path, producer)


@cli.command()
@click.pass_context
@click.argument("provider")
def list_submissions_by_provider(ctx, provider):
@click.argument("producer")
def list_submissions_by_producer(ctx, producer):
context = ctx.obj
list_data_submissions_by_provider(context, provider)
list_data_submissions_by_producer(context, producer)


@cli.command()
Expand Down
Loading

0 comments on commit 736cc7b

Please sign in to comment.