Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .template.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Autogenerated - DO NOT EDIT
# Parameters of the project as generated from template
_commit: 33b991b
_commit: 179dc2a
_src_path: gh:kraysent/python-template
project_name: db_app
6 changes: 1 addition & 5 deletions app/data/repositories/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from app.data import model, template
from app.lib import concurrency
from app.lib.storage import postgres
from app.lib.web.errors import DatabaseError


@dataclass
Expand Down Expand Up @@ -40,9 +39,6 @@ def create_bibliography(self, code: str, year: int, authors: list[str], title: s
params=[code, year, authors, title],
)

if result is None:
raise DatabaseError("no result returned from query")

return int(result["id"])

def get_source_entry(self, source_name: str) -> model.Bibliography:
Expand Down Expand Up @@ -77,7 +73,7 @@ def get_schema(self, schema_name: str, table_name: str) -> TableSchemaInfo:

table_row = table_task.result()
table_description = ""
if table_row is not None and table_row.get("param") is not None:
if table_row.get("param") is not None:
param = table_row["param"]
if isinstance(param, dict):
table_description = param.get("description") or ""
Expand Down
4 changes: 0 additions & 4 deletions app/data/repositories/layer0/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ def register_records(self, table_name: str, record_ids: list[str]) -> None:
raise RuntimeError("no records to upsert")

table_id_row = self._storage.query_one(template.FETCH_RAWDATA_REGISTRY, params=[table_name])
if table_id_row is None:
raise DatabaseError(f"unable to fetch table with name {table_name}")

table_id = table_id_row["id"]

Expand Down Expand Up @@ -121,8 +119,6 @@ def get_processed_records(

def get_table_statistics(self, table_name: str) -> model.TableStatistics:
table_id_row = self._storage.query_one(template.FETCH_RAWDATA_REGISTRY, params=[table_name])
if table_id_row is None:
raise DatabaseError(f"unable to fetch table with name {table_name}")

table_id = table_id_row["id"]

Expand Down
6 changes: 0 additions & 6 deletions app/data/repositories/layer0/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from app.data import model, repositories, template
from app.data.repositories.layer0.common import INTERNAL_ID_COLUMN_NAME, RAWDATA_SCHEMA
from app.lib.storage import postgres
from app.lib.web.errors import DatabaseError

log: structlog.stdlib.BoundLogger = structlog.get_logger()

Expand Down Expand Up @@ -419,8 +418,6 @@ def fetch_metadata(self, table_name: str) -> model.Layer0TableMeta:

def fetch_metadata_by_name(self, table_name: str) -> model.Layer0TableMeta:
row = self._storage.query_one(template.FETCH_RAWDATA_REGISTRY, params=[table_name])
if row is None:
raise DatabaseError(f"unable to fetch table with name {table_name}")

modification_dt: datetime.datetime | None = row.get("modification_dt")
return self._fetch_metadata_by_name(table_name, modification_dt)
Expand Down Expand Up @@ -455,9 +452,6 @@ def _fetch_metadata_by_name(
table_metadata = self._storage.query_one(template.FETCH_TABLE_METADATA, params=[RAWDATA_SCHEMA, table_name])
registry_item = self._storage.query_one(template.FETCH_RAWDATA_REGISTRY, params=[table_name])

if table_metadata is None:
raise DatabaseError(f"unable to metadata for table {table_name}")

return model.Layer0TableMeta(
table_name,
descriptions,
Expand Down
21 changes: 7 additions & 14 deletions app/domain/responders/fits_responder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,10 @@ def extract_object_data(objects: list[model.Layer2CatalogObject]) -> dict[str, n
catalog_name = catalog_obj.catalog().value
catalog_data = catalog_obj.layer2_data()

if isinstance(catalog_data, dict):
for field, _ in catalog_data.items():
full_field_name = f"{catalog_name}_{field}"
if full_field_name not in data_dict:
data_dict[full_field_name] = []
else:
if catalog_name not in data_dict:
data_dict[catalog_name] = []
for field, _ in catalog_data.items():
full_field_name = f"{catalog_name}_{field}"
if full_field_name not in data_dict:
data_dict[full_field_name] = []

for obj in objects:
for field in data_dict:
Expand All @@ -37,12 +33,9 @@ def extract_object_data(objects: list[model.Layer2CatalogObject]) -> dict[str, n
catalog_name = catalog_obj.catalog().value
catalog_data = catalog_obj.layer2_data()

if isinstance(catalog_data, dict):
for field, value in catalog_data.items():
full_field_name = f"{catalog_name}_{field}"
data_dict[full_field_name][-1] = value
else:
data_dict[catalog_name][-1] = catalog_data
for field, value in catalog_data.items():
full_field_name = f"{catalog_name}_{field}"
data_dict[full_field_name][-1] = value

for field, values in data_dict.items():
if all(v is None for v in values):
Expand Down
2 changes: 1 addition & 1 deletion app/domain/responders/json_responder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ def objects_to_response(objects: list[model.Layer2CatalogObject]) -> list[dataap


class JSONResponder(interface.ObjectResponder):
def build_response(self, objects: list[model.Layer2CatalogObject]) -> Any:
def build_response_from_catalog(self, objects: list[model.Layer2CatalogObject]) -> Any:
return objects_to_response(objects)
4 changes: 2 additions & 2 deletions app/lib/astronomy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from astropy import constants
from astropy import units as u
from uncertainties import ufloat
from uncertainties.umath import cos, sin # type: ignore
from uncertainties.umath import cos, sin

warnings.filterwarnings("ignore", message="Using UFloat objects with std_dev==0 may give unexpected results")

Expand Down Expand Up @@ -72,7 +72,7 @@ def velocity_wr_apex(
lat_apex_u = ufloat(lat_apex.value, lat_apex_err_val)

result = vel_u - vel_apex_u * (
sin(lat_u) * sin(lat_apex_u) + cos(lat_u) * cos(lat_apex_u) * cos(lon_u - lon_apex_u) # type: ignore
sin(lat_u) * sin(lat_apex_u) + cos(lat_u) * cos(lat_apex_u) * cos(lon_u - lon_apex_u)
)

return u.Quantity(result.nominal_value, unit="km/s"), u.Quantity(result.std_dev, unit="km/s")
24 changes: 12 additions & 12 deletions app/presentation/adminapi/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,49 +338,49 @@ class SetCrossmatchResultsResponse(pydantic.BaseModel):

class Actions(abc.ABC):
@abc.abstractmethod
def add_data(self, request: AddDataRequest) -> AddDataResponse:
def add_data(self, r: AddDataRequest) -> AddDataResponse:
pass

@abc.abstractmethod
def create_table(self, request: CreateTableRequest) -> tuple[CreateTableResponse, bool]:
def create_table(self, r: CreateTableRequest) -> tuple[CreateTableResponse, bool]:
pass

@abc.abstractmethod
def get_table(self, request: GetTableRequest) -> GetTableResponse:
def get_table(self, r: GetTableRequest) -> GetTableResponse:
pass

@abc.abstractmethod
def get_table_list(self, request: GetTableListRequest) -> GetTableListResponse:
def get_table_list(self, r: GetTableListRequest) -> GetTableListResponse:
pass

@abc.abstractmethod
def patch_table(self, request: PatchTableRequest) -> PatchTableResponse:
def patch_table(self, r: PatchTableRequest) -> PatchTableResponse:
pass

@abc.abstractmethod
def create_source(self, request: CreateSourceRequest) -> CreateSourceResponse:
def create_source(self, r: CreateSourceRequest) -> CreateSourceResponse:
pass

@abc.abstractmethod
def login(self, request: LoginRequest) -> LoginResponse:
def login(self, r: LoginRequest) -> LoginResponse:
pass

@abc.abstractmethod
def get_records(self, request: GetRecordsRequest) -> GetRecordsResponse:
def get_records(self, r: GetRecordsRequest) -> GetRecordsResponse:
pass

@abc.abstractmethod
def get_crossmatch_records(self, request: GetRecordsCrossmatchRequest) -> GetRecordsCrossmatchResponse:
def get_crossmatch_records(self, r: GetRecordsCrossmatchRequest) -> GetRecordsCrossmatchResponse:
pass

@abc.abstractmethod
def get_record_crossmatch(self, request: GetRecordCrossmatchRequest) -> GetRecordCrossmatchResponse:
def get_record_crossmatch(self, r: GetRecordCrossmatchRequest) -> GetRecordCrossmatchResponse:
pass

@abc.abstractmethod
def save_structured_data(self, request: SaveStructuredDataRequest) -> SaveStructuredDataResponse:
def save_structured_data(self, r: SaveStructuredDataRequest) -> SaveStructuredDataResponse:
pass

@abc.abstractmethod
def set_crossmatch_results(self, request: SetCrossmatchResultsRequest) -> SetCrossmatchResultsResponse:
def set_crossmatch_results(self, r: SetCrossmatchResultsRequest) -> SetCrossmatchResultsResponse:
pass
6 changes: 0 additions & 6 deletions app/presentation/adminapi/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,20 @@ def __init__(self, actions: interface.Actions) -> None:
def add_data(
self,
request: interface.AddDataRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.AddDataResponse]:
response = self.actions.add_data(request)
return server.APIOkResponse(data=response)

def create_source(
self,
request: interface.CreateSourceRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.CreateSourceResponse]:
response = self.actions.create_source(request)
return server.APIOkResponse(data=response)

def create_table(
self,
request: interface.CreateTableRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.CreateTableResponse]:
response, _ = self.actions.create_table(request)
return server.APIOkResponse(data=response)
Expand All @@ -60,7 +57,6 @@ def get_records(
def patch_table(
self,
request: interface.PatchTableRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.PatchTableResponse]:
response = self.actions.patch_table(request)
return server.APIOkResponse(data=response)
Expand All @@ -84,15 +80,13 @@ def get_record_crossmatch(
def save_structured_data(
self,
request: interface.SaveStructuredDataRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.SaveStructuredDataResponse]:
response = self.actions.save_structured_data(request)
return server.APIOkResponse(data=response)

def set_crossmatch_results(
self,
request: interface.SetCrossmatchResultsRequest,
token: str = fastapi.Security(api_key_header),
) -> server.APIOkResponse[interface.SetCrossmatchResultsResponse]:
response = self.actions.set_crossmatch_results(request)
return server.APIOkResponse(data=response)
Expand Down
20 changes: 15 additions & 5 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,41 @@ check:
else \
echo "$$output"; \
fi

@find . \
-name "*.py" \
-not -path "./.venv/*" \
-not -path "./.git/*" \
-exec uv run python -m py_compile {} +
@echo "Compilation ok."

@uvx ruff format \
--quiet \
--config=pyproject.toml \
--check
@echo "Formatting ok."

@uvx ruff check \
--quiet \
--config=pyproject.toml
@echo "Linter ok."

@output=$$(uvx basedpyright 2>&1); exit_code=$$?; \
if [ $$exit_code -ne 0 ]; then echo "$$output"; fi; \
exit $$exit_code
@echo "Typechecking ok."

@uv run pytest \
--quiet \
--config-file=pyproject.toml \
tests/env_test.py tests/unit
@echo "Testing ok."

fix:
@uvx ruff format \
--quiet \
--config=pyproject.toml

@uvx ruff check \
--quiet \
--config=pyproject.toml \
Expand Down Expand Up @@ -109,7 +123,7 @@ build-docs:

cleanup:
rm -rf uv.lock .venv \
.pytest_cache .mypy_cache .vizier_cache .ruff_cache \
.pytest_cache .ruff_cache \
__pycache__ */__pycache__ \
.coverage htmlcov site \
docs/gen
Expand All @@ -126,10 +140,6 @@ test-all: check
test-regression:
uv run tests.py regression-tests

mypy:
uvx mypy app --config-file pyproject.toml
uvx mypy tests --config-file pyproject.toml

coverage:
uvx coverage run -m unittest discover -s tests -p "*_test.py" -v
uvx coverage html
Expand Down
Loading
Loading