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
73 changes: 0 additions & 73 deletions api/observation.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this file grows, it would make sense to refactor the api/observation.py section into smaller, more focused modules (e.g., api/observation/get.py, api/observation/post.py, etc.) to improve maintainability and clarity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you suggest that for all routers? Every one has GET, POST, PATCH, and DELETE methods defined in them.

Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,9 @@
GroundwaterLevelObservationResponse,
CreateWaterChemistryObservation,
WaterChemistryObservationResponse,
# CreateGeothermalObservation,
# GeothermalObservationResponse,
ObservationResponse,
UpdateGroundwaterLevelObservation,
UpdateWaterChemistryObservation,
# UpdateGeothermalObservation,
)
from services.crud_helper import model_deleter, model_adder
from services.query_helper import simple_get_by_id
Expand Down Expand Up @@ -81,19 +78,6 @@ async def add_water_chemistry_observation(
return model_adder(session, Observation, obs_data, user=user)


# @router.post("/geothermal", status_code=HTTP_201_CREATED)
# async def add_geothermal_observation(
# obs_data: CreateGeothermalObservation,
# session: session_dependency,
# user: admin_dependency,
# ) -> GeothermalObservationResponse:
# """
# Add a new geothermal observation to the database.
# This endpoint is currently a placeholder and does not implement any functionality.
# """
# return model_adder(session, Observation, obs_data, user=user)


# PATCH ========================================================================


Expand Down Expand Up @@ -125,20 +109,6 @@ async def update_water_chemistry_observation(
return observation_model_patcher(session, request, observation_id, obs_data, user)


# @router.patch("/geothermal/{observation_id}", status_code=HTTP_200_OK)
# async def update_geothermal_observation(
# observation_id: int,
# obs_data: UpdateGeothermalObservation,
# session: session_dependency,
# user: admin_dependency,
# request: Request,
# ) -> GeothermalObservationResponse:
# """
# Update an existing geothermal observation in the database.
# """
# return observation_model_patcher(session, request, observation_id, obs_data, user)


# ============= Get ==============================================


Expand Down Expand Up @@ -237,49 +207,6 @@ async def get_water_chemistry_observation_by_id(
)


# @router.get("/geothermal", summary="Get geothermal observations")
# async def get_geothermal_observations(
# request: Request,
# session: session_dependency,
# user: viewer_dependency,
# thing_id: int | None = None,
# sensor_id: int | None = None,
# sample_id: int | None = None,
# start_time: datetime | None = None,
# end_time: datetime | None = None,
# sort: str | None = None,
# order: str | None = None,
# filter_: str = Query(alias="filter", default=None),
# ) -> CustomPage[GeothermalObservationResponse]:
# """
# Retrieve all geothermal observations from the database.
# """
# return get_observations(
# request=request,
# session=session,
# thing_id=thing_id,
# sensor_id=sensor_id,
# sample_id=sample_id,
# start_time=start_time,
# end_time=end_time,
# sort=sort,
# order=order,
# filter_=filter_,
# )


# @router.get("/geothermal/{observation_id}", summary="Get geothermal observation by ID")
# async def get_geothermal_observation_by_id(
# session: session_dependency,
# request: Request,
# user: amp_viewer_dependency,
# observation_id: int,
# ) -> GeothermalObservationResponse:
# return get_observation_of_an_activity_type_by_id(
# session=session, request=request, observation_id=observation_id
# )


@router.get("", summary="Get all observations")
async def get_all_observations(
request: Request,
Expand Down
49 changes: 25 additions & 24 deletions core/lexicon.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{"name": "field_contact_role", "description": null},
{"name": "geochronology", "description": null},
{"name": "horizontal_datum", "description": null},
{"name": "level_status", "description": null},
{"name": "value_reason", "description": null},
{"name": "measurement_method", "description": null},
{"name": "monitoring_status", "description": null},
{"name": "observed_property", "description": null},
Expand Down Expand Up @@ -284,29 +284,30 @@
{"categories": ["thing_type"], "term": "perennial stream", "definition": "that has a continuous flow of water throughout the year, even during drier periods."},
{"categories": ["thing_type"], "term": "ephemeral stream", "definition": "a stream that flows only briefly during and after precipitation events"},
{"categories": ["thing_type"], "term": "meteorological station", "definition": "a station that measures the weather conditions at a particular location"},
{"categories": ["level_status"], "term": "Water level affected by atmospheric pressure", "definition": "Water level affected by atmospheric pressure"},
{"categories": ["level_status"], "term": "Water level was frozen (no level recorded).", "definition": "Water level was frozen (no level recorded)."},
{"categories": ["level_status"], "term": "Site was dry", "definition": "Site was dry"},
{"categories": ["level_status"], "term": "Site was flowing recently.", "definition": "Site was flowing recently."},
{"categories": ["level_status"], "term": "Site was flowing. Water level or head couldn't be measured w/out additional equipment.", "definition": "Site was flowing. Water level or head couldn't be measured w/out additional equipment."},
{"categories": ["level_status"], "term": "Nearby site that taps the same aquifer was flowing.", "definition": "Nearby site that taps the same aquifer was flowing."},
{"categories": ["level_status"], "term": "Nearby site that taps the same aquifer had been flowing recently.", "definition": "Nearby site that taps the same aquifer had been flowing recently."},
{"categories": ["level_status"], "term": "Recharge water was being injected into the aquifer at this site.", "definition": "Recharge water was being injected into the aquifer at this site."},
{"categories": ["level_status"], "term": "Recharge water was being injected into nearby site that taps the same aquifer.", "definition": "Recharge water was being injected into nearby site that taps the same aquifer."},
{"categories": ["level_status"], "term": "Water was cascading down the inside of the well.", "definition": "Water was cascading down the inside of the well."},
{"categories": ["level_status"], "term": "Water level was affected by brackish or saline water.", "definition": "Water level was affected by brackish or saline water."},
{"categories": ["level_status"], "term": "Well was not in hydraulic contact w/formation (from source other than defined in USGS C714 or C93).", "definition": "Well was not in hydraulic contact w/formation (from source other than defined in USGS C714 or C93)."},
{"categories": ["level_status"], "term": "Measurement was discontinued (no level recorded).", "definition": "Measurement was discontinued (no level recorded)."},
{"categories": ["level_status"], "term": "Obstruction was encountered in the well (no level recorded)", "definition": "Obstruction was encountered in the well (no level recorded)"},
{"categories": ["level_status"], "term": "Site was being pumped", "definition": "Site was being pumped"},
{"categories": ["level_status"], "term": "Site was pumped recently", "definition": "Site was pumped recently"},
{"categories": ["level_status"], "term": "Nearby site that taps the same aquifer was being pumped", "definition": "Nearby site that taps the same aquifer was being pumped"},
{"categories": ["level_status"], "term": "Nearby site that taps the same aquifer was pumped recently", "definition": "Nearby site that taps the same aquifer was pumped recently"},
{"categories": ["level_status"], "term": "Foreign substance present on the water surface", "definition": "Foreign substance present on the water surface"},
{"categories": ["level_status"], "term": "Well was destroyed (no subsequent water levels should be recorded)", "definition": "Well was destroyed (no subsequent water levels should be recorded)"},
{"categories": ["level_status"], "term": "Water level affected by stage in nearby surface-water site", "definition": "Water level affected by stage in nearby surface-water site"},
{"categories": ["level_status"], "term": "Other conditions exist that would affect the level (remarks)", "definition": "Other conditions exist that would affect the level (remarks)"},
{"categories": ["level_status"], "term": "Water level not affected by status", "definition": "Water level not affected by status"},
{"categories": ["value_reason"], "term": "Water level affected by atmospheric pressure", "definition": "Water level affected by atmospheric pressure"},
{"categories": ["value_reason"], "term": "Water level was frozen (no level recorded).", "definition": "Water level was frozen (no level recorded)."},
{"categories": ["value_reason"], "term": "Site was dry", "definition": "Site was dry"},
{"categories": ["value_reason"], "term": "Site was flowing recently.", "definition": "Site was flowing recently."},
{"categories": ["value_reason"], "term": "Site was flowing. Water level or head couldn't be measured w/out additional equipment.", "definition": "Site was flowing. Water level or head couldn't be measured w/out additional equipment."},
{"categories": ["value_reason"], "term": "Nearby site that taps the same aquifer was flowing.", "definition": "Nearby site that taps the same aquifer was flowing."},
{"categories": ["value_reason"], "term": "Nearby site that taps the same aquifer had been flowing recently.", "definition": "Nearby site that taps the same aquifer had been flowing recently."},
{"categories": ["value_reason"], "term": "Recharge water was being injected into the aquifer at this site.", "definition": "Recharge water was being injected into the aquifer at this site."},
{"categories": ["value_reason"], "term": "Recharge water was being injected into nearby site that taps the same aquifer.", "definition": "Recharge water was being injected into nearby site that taps the same aquifer."},
{"categories": ["value_reason"], "term": "Water was cascading down the inside of the well.", "definition": "Water was cascading down the inside of the well."},
{"categories": ["value_reason"], "term": "Water level was affected by brackish or saline water.", "definition": "Water level was affected by brackish or saline water."},
{"categories": ["value_reason"], "term": "Well was not in hydraulic contact w/formation (from source other than defined in USGS C714 or C93).", "definition": "Well was not in hydraulic contact w/formation (from source other than defined in USGS C714 or C93)."},
{"categories": ["value_reason"], "term": "Measurement was discontinued (no level recorded).", "definition": "Measurement was discontinued (no level recorded)."},
{"categories": ["value_reason"], "term": "Obstruction was encountered in the well (no level recorded)", "definition": "Obstruction was encountered in the well (no level recorded)"},
{"categories": ["value_reason"], "term": "Site was being pumped", "definition": "Site was being pumped"},
{"categories": ["value_reason"], "term": "Site was pumped recently", "definition": "Site was pumped recently"},
{"categories": ["value_reason"], "term": "Nearby site that taps the same aquifer was being pumped", "definition": "Nearby site that taps the same aquifer was being pumped"},
{"categories": ["value_reason"], "term": "Nearby site that taps the same aquifer was pumped recently", "definition": "Nearby site that taps the same aquifer was pumped recently"},
{"categories": ["value_reason"], "term": "Foreign substance present on the water surface", "definition": "Foreign substance present on the water surface"},
{"categories": ["value_reason"], "term": "Well was destroyed (no subsequent water levels should be recorded)", "definition": "Well was destroyed (no subsequent water levels should be recorded)"},
{"categories": ["value_reason"], "term": "Water level affected by stage in nearby surface-water site", "definition": "Water level affected by stage in nearby surface-water site"},
{"categories": ["value_reason"], "term": "Other conditions exist that would affect the level (remarks)", "definition": "Other conditions exist that would affect the level (remarks)"},
{"categories": ["value_reason"], "term": "Water level not affected by status", "definition": "Water level not affected by status"},
{"categories": ["value_reason"], "term": "Observed value not affected", "definition": "Observed value not affected"},
{"categories": ["status"], "term": "Abandoned", "definition": "Abandoned"},
{"categories": ["status"], "term": "Active, pumping well", "definition": "Active, pumping well"},
{"categories": ["status"], "term": "Destroyed, exists but not usable", "definition": "Destroyed, exists but not usable"},
Expand Down
12 changes: 6 additions & 6 deletions db/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

from db.base import Base, AutoBaseMixin, ReleaseMixin, lexicon_term


if TYPE_CHECKING:
from db.field import FieldEventParticipant, FieldEvent
from db.thing import Thing
from db.field import FieldEvent
from db.field import FieldEventParticipants
from db.publication import Author, AuthorContactAssociation
from db.permission import Permission
from db.publication import AuthorContactAssociation, Author


class ThingContactAssociation(Base, AutoBaseMixin):
Expand All @@ -42,7 +42,7 @@ class ThingContactAssociation(Base, AutoBaseMixin):
)
thing: Mapped["Thing"] = relationship(
"Thing", back_populates="contact_associations"
) # noqa: F821
)


class Contact(Base, AutoBaseMixin, ReleaseMixin):
Expand Down Expand Up @@ -85,8 +85,8 @@ class Contact(Base, AutoBaseMixin, ReleaseMixin):
cascade="all, delete-orphan",
)
# One-To-Many: A Contact can participate in many Field Events.
field_event_participants: Mapped[list["FieldEventParticipants"]] = relationship(
"FieldEventParticipants",
field_event_participants: Mapped[list["FieldEventParticipant"]] = relationship(
"FieldEventParticipant",
back_populates="contact",
cascade="all, delete-orphan",
passive_deletes=True,
Expand Down
27 changes: 16 additions & 11 deletions db/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
from sqlalchemy import DateTime, ForeignKey
from sqlalchemy.orm import mapped_column, relationship, Mapped
from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy
from typing import TYPE_CHECKING

from db.base import Base, AutoBaseMixin, ReleaseMixin, lexicon_term
from db.contact import Contact

if TYPE_CHECKING:
from db.contact import Contact
from db.sample import Sample
from db.thing import Thing

class FieldEventParticipants(Base, AutoBaseMixin, ReleaseMixin):

class FieldEventParticipant(Base, AutoBaseMixin, ReleaseMixin):
"""
This association table is to create a many-to-many relationship between
FieldEvent and Contact. These are participants in the field event.
Expand All @@ -34,15 +39,15 @@ class FieldEventParticipants(Base, AutoBaseMixin, ReleaseMixin):
field_event: Mapped["FieldEvent"] = relationship(
"FieldEvent", back_populates="field_event_participants"
)
contact: Mapped["Contact"] = relationship( # noqa: F821
contact: Mapped["Contact"] = relationship(
"Contact", back_populates="field_event_participants"
)

# map associated contacts to samples to restrict the people who could have
# taken a sample to those present at the field event
samples: Mapped[list["Sample"]] = relationship( # noqa: F821
samples: Mapped[list["Sample"]] = relationship(
"Sample",
back_populates="field_event_contact",
back_populates="field_event_participant",
passive_deletes=True,
)

Expand All @@ -60,7 +65,7 @@ class FieldEvent(Base, AutoBaseMixin, ReleaseMixin):

Its purpose is to store the "where and when" of the event.
Information about who participated is managed in the
FieldEventContactAssociation table. Information about the "what" of the
FieldEventParticipant table. Information about the "what" of the
event is managed in the FieldActivity and Sample tables.
"""

Expand All @@ -82,20 +87,20 @@ class FieldEvent(Base, AutoBaseMixin, ReleaseMixin):
comment="Notes or comments about the field event.",
)
# --- Relationships ---
thing: Mapped["Thing"] = relationship(back_populates="field_events") # noqa: F821
thing: Mapped["Thing"] = relationship(back_populates="field_events")
field_activities: Mapped[list["FieldActivity"]] = relationship(
"FieldActivity", back_populates="field_event"
)
field_event_participants: Mapped[list["FieldEventParticipants"]] = relationship(
"FieldEventParticipants",
field_event_participants: Mapped[list["FieldEventParticipant"]] = relationship(
"FieldEventParticipant",
back_populates="field_event",
cascade="all, delete-orphan",
passive_deletes=True,
)

# --- Association Proxies ---
# Proxy to directly access the Contact objects participating in this event.
contacts: AssociationProxy[list["Contact"]] = association_proxy( # noqa: F821
contacts: AssociationProxy[list["Contact"]] = association_proxy(
"field_event_participants", "contact"
)

Expand Down Expand Up @@ -136,7 +141,7 @@ class FieldActivity(Base, AutoBaseMixin, ReleaseMixin):
field_event: Mapped["FieldEvent"] = relationship(
"FieldEvent", back_populates="field_activities"
)
samples: Mapped[list["Sample"]] = relationship( # noqa: F821
samples: Mapped[list["Sample"]] = relationship(
"Sample",
back_populates="field_activity",
cascade="all, delete-orphan",
Expand Down
11 changes: 6 additions & 5 deletions db/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
# ===============================================================================
import datetime

from typing import TYPE_CHECKING
from geoalchemy2 import Geometry, WKBElement
from geoalchemy2.shape import to_shape

Expand All @@ -34,6 +34,9 @@
from db.base import Base, AutoBaseMixin, ReleaseMixin
from db.lexicon import lexicon_term

if TYPE_CHECKING:
from db.thing import Thing


class Location(Base, AutoBaseMixin, ReleaseMixin):
__versioned__ = {}
Expand Down Expand Up @@ -67,7 +70,7 @@ class Location(Base, AutoBaseMixin, ReleaseMixin):
)

# --- Proxy Definitions ---
things: AssociationProxy[list["Thing"]] = association_proxy( # noqa: F821
things: AssociationProxy[list["Thing"]] = association_proxy(
"thing_associations", "thing"
)

Expand Down Expand Up @@ -97,9 +100,7 @@ class LocationThingAssociation(Base, AutoBaseMixin):

# --- Relationship Definitions ---
location: Mapped["Location"] = relationship(back_populates="thing_associations")
thing: Mapped["Thing"] = relationship( # noqa: F821
back_populates="location_associations"
)
thing: Mapped["Thing"] = relationship(back_populates="location_associations")


# ============= EOF =============================================
Loading
Loading