Skip to content

Commit 440ac6a

Browse files
amyfromandigithub-actions[bot]
authored andcommitted
Format code and sort imports
1 parent cfef5c1 commit 440ac6a

File tree

4 files changed

+85
-26
lines changed

4 files changed

+85
-26
lines changed

services/api-v3/api/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
import api.routes.security
1111
from api.database import connect_engine, dispose_engine
12+
from api.routes.dev import dev_router
1213
from api.routes.ingest import router as ingest_router
1314
from api.routes.object import router as object_router
1415
from api.routes.sources import router as sources_router
15-
from api.routes.dev import dev_router
1616

1717

1818
@asynccontextmanager

services/api-v3/api/models/field_site.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
from pydantic import BaseModel
2-
from typing import Optional, Literal
31
from datetime import datetime
42
from enum import Enum
3+
from typing import Literal, Optional
4+
5+
from pydantic import BaseModel
6+
57

68
class Location(BaseModel):
79
"""
810
Location model representing a geographical location with latitude and longitude.
911
"""
12+
1013
latitude: float
1114
longitude: float
1215
elevation: Optional[float] = None
@@ -20,49 +23,59 @@ class Location(BaseModel):
2023
class IdentifiedModel(BaseModel):
2124
id: int
2225

26+
2327
class Photo(IdentifiedModel):
2428
"""
2529
A photo.
2630
"""
31+
2732
# URL at which the photo should be fetchable
2833
url: str
2934
width: int
3035
height: int
3136
checksum: str
3237

38+
3339
class BeddingFacing(Enum):
3440
upright = "upright"
3541
overturned = "overturned"
3642
unknown = "unknown"
3743

44+
3845
class PlanarOrientation(BaseModel):
3946
strike: float
4047
dip: float
4148
facing: BeddingFacing = BeddingFacing.upright
4249
notes: Optional[str] = None
4350
associated: list["Orientation"] = []
4451

52+
4553
class LinearOrientation(BaseModel):
4654
plunge: float
4755
trend: float
4856
notes: Optional[str] = None
4957

58+
5059
class Texture(BaseModel):
5160
name: str
5261

62+
5363
Orientation = PlanarOrientation | LinearOrientation
5464

65+
5566
class GeologicAgeInterval(IdentifiedModel):
5667
name: str
5768
t_age: Optional[float] = None
5869
b_age: Optional[float] = None
5970

71+
6072
class Lithology(IdentifiedModel):
6173
name: str
6274
parents: Optional[list[int]] = None
6375
color: Optional[str] = None
6476
pattern: Optional[str] = None
6577

78+
6679
class LithodemeType(Enum):
6780
Formation = "formation"
6881
Member = "member"
@@ -76,30 +89,37 @@ class LithodemeType(Enum):
7689
Intrusion = "intrusion"
7790
...
7891

92+
7993
class LithodemeName(GeologicAgeInterval):
80-
"""A lithodeme or stratigraphic unit name """
94+
"""A lithodeme or stratigraphic unit name"""
95+
8196
parent: Optional[int] = None
8297
type: LithodemeType
8398
t_interval: Optional[float] = None
8499
b_interval: Optional[float] = None
85100

101+
86102
class RockUnit(IdentifiedModel):
87103
name: str
88104
abbreviation: Optional[str] = None
89105
liths: list[Lithology] = []
90106
age: Optional[GeologicAgeInterval] = None
91107
entity: Optional[LithodemeName] = None
92108

109+
93110
class Fossil(IdentifiedModel):
94111
description: str
95112
taxa: Optional[str] = None
96113

114+
97115
AnyData = Orientation | Photo | RockUnit | Texture | Lithology | Fossil
98116

117+
99118
class Observation(BaseModel):
100119
notes: Optional[str] = None
101120
data: AnyData
102121

122+
103123
class Person(IdentifiedModel):
104124
name: str
105125
email: Optional[str] = None
@@ -112,22 +132,26 @@ class Sample(IdentifiedModel):
112132
"""
113133
A sample of a rock or sediment
114134
"""
135+
115136
name: str
116137
description: Optional[str] = None
117138
sample_type: Literal["rock", "sediment", "soil", "water"]
118139
igsn: Optional[str] = None
119140
collected: datetime
120141

142+
121143
class SocialInfo(BaseModel):
122144
likes: int
123145
comments: int
124146
rating: Optional[int] = None
125147

148+
126149
class FieldSite(BaseModel):
127150
"""
128151
A site of with associated field observations
129152
"""
130-
id: int|str
153+
154+
id: int | str
131155
name: Optional[str] = None
132156
location: Location
133157
created: datetime
@@ -139,4 +163,3 @@ class FieldSite(BaseModel):
139163
social: Optional[SocialInfo] = None
140164
children: Optional[list["FieldSite"]] = None
141165
contributors: Optional[list[Person]] = None
142-

services/api-v3/api/routes/dev.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from fastapi import APIRouter
21
from api.routes.dev_routes.interchange_data import interchange_router
2+
from fastapi import APIRouter
33

44
dev_router = APIRouter(prefix="/dev", tags=["dev"])
5-
dev_router.include_router(interchange_router)
5+
dev_router.include_router(interchange_router)

services/api-v3/api/routes/dev_routes/interchange_data.py

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,43 @@
1-
from fastapi import Request, Body
2-
from typing import Any, Iterable, Union, List
3-
import httpx
1+
from typing import Any, Iterable, List, Union
2+
43
import dotenv
5-
from fastapi import APIRouter, Depends, HTTPException, Response, status
4+
import httpx
5+
from fastapi import APIRouter, Body, Depends, HTTPException, Request, Response, status
66
from slugify import slugify
77
from sqlalchemy import func, insert, select, update
88
from sqlalchemy.exc import NoResultFound, NoSuchTableError
9+
910
dotenv.load_dotenv()
1011

12+
from datetime import datetime, timezone
13+
from typing import Optional
14+
1115
from api.database import (
1216
get_async_session,
1317
get_engine,
1418
get_table,
1519
patch_sources_sub_table,
1620
select_sources_sub_table,
1721
)
22+
from api.models.field_site import (
23+
BeddingFacing,
24+
FieldSite,
25+
Location,
26+
Observation,
27+
Photo,
28+
PlanarOrientation,
29+
)
1830
from api.query_parser import ParserException
1931
from api.routes.security import has_access
20-
from datetime import datetime, timezone
21-
from api.models.field_site import FieldSite, Location, Photo, PlanarOrientation, Observation, BeddingFacing
22-
from typing import Optional
2332

2433
interchange_router = APIRouter(
2534
prefix="/interchange-data",
2635
tags=["interchange-data"],
2736
responses={404: {"description": "Not found"}},
2837
)
2938

30-
#helpers
39+
# helpers
40+
3141

3242
def _parse_date_time(x: Optional[str]) -> Optional[datetime]:
3343
if not x:
@@ -40,6 +50,7 @@ def _parse_date_time(x: Optional[str]) -> Optional[datetime]:
4050
except Exception:
4151
return None
4252

53+
4354
def _to_float(v) -> Optional[float]:
4455
try:
4556
if v is None:
@@ -48,7 +59,8 @@ def _to_float(v) -> Optional[float]:
4859
except Exception:
4960
return None
5061

51-
#normalize and require lat/lngs
62+
63+
# normalize and require lat/lngs
5264
def _valid_coords(lat, lng) -> bool:
5365
try:
5466
lat = float(lat)
@@ -57,6 +69,7 @@ def _valid_coords(lat, lng) -> bool:
5769
return False
5870
return -90.0 <= lat <= 90.0 and -180.0 <= lng <= 180.0
5971

72+
6073
def _first_planar_from_spot(props) -> Optional[PlanarOrientation]:
6174
"""Find first planar orientation with numeric strike & dip in StraboSpot props."""
6275
orientation = props.get("orientation_data")
@@ -69,9 +82,12 @@ def _first_planar_from_spot(props) -> Optional[PlanarOrientation]:
6982
strike = _to_float(item.get("strike"))
7083
dip = _to_float(item.get("dip"))
7184
if strike is not None and dip is not None:
72-
return PlanarOrientation(strike=strike, dip=dip, facing=BeddingFacing.upright)
85+
return PlanarOrientation(
86+
strike=strike, dip=dip, facing=BeddingFacing.upright
87+
)
7388
return None
7489

90+
7591
def _first_planar_from_checkin(checkin) -> Optional[PlanarOrientation]:
7692
"""Find first observation with numeric strike & dip in Rockd checkin."""
7793
obs = checkin.get("observations")
@@ -84,9 +100,12 @@ def _first_planar_from_checkin(checkin) -> Optional[PlanarOrientation]:
84100
strike = _to_float(orientation.get("strike"))
85101
dip = _to_float(orientation.get("dip"))
86102
if strike is not None and dip is not None:
87-
return PlanarOrientation(strike=strike, dip=dip, facing=BeddingFacing.upright)
103+
return PlanarOrientation(
104+
strike=strike, dip=dip, facing=BeddingFacing.upright
105+
)
88106
return None
89107

108+
90109
def _first_planar_from_fieldsite(fs: FieldSite) -> Optional[PlanarOrientation]:
91110
"""Return first PlanarOrientation in FieldSite.observations."""
92111
for ob in fs.observations or []:
@@ -126,14 +145,16 @@ def spot_to_fieldsite(feat) -> FieldSite:
126145
url=f"rockd://photo/{pid}",
127146
width=int(img.get("width", 0) or 0),
128147
height=int(img.get("height", 0) or 0),
129-
checksum=""
148+
checksum="",
130149
)
131150
)
132151
observations: list[Observation] = []
133152
planar = _first_planar_from_spot(props)
134153
if planar:
135154
observations.append(Observation(data=planar))
136-
created = _parse_date_time(props.get("time") or props.get("date")) or datetime.now(timezone.utc)
155+
created = _parse_date_time(props.get("time") or props.get("date")) or datetime.now(
156+
timezone.utc
157+
)
137158

138159
mt = props.get("modified_timestamp")
139160
if mt is not None:
@@ -154,8 +175,11 @@ def spot_to_fieldsite(feat) -> FieldSite:
154175
observations=observations,
155176
)
156177

178+
157179
@interchange_router.post("/spot-to-fieldsite")
158-
def multiple_spot_to_fieldsite(feat: Union[dict, List[dict]] = Body(...)) -> List[FieldSite]:
180+
def multiple_spot_to_fieldsite(
181+
feat: Union[dict, List[dict]] = Body(...)
182+
) -> List[FieldSite]:
159183
"""
160184
Accept a single FeatureCollection or a list of FeatureCollections and
161185
return a FieldSite for each qualifying Point feature (non-image-basemap).
@@ -199,12 +223,16 @@ def fieldsite_to_checkin(fs: FieldSite) -> dict:
199223
d["photo"] = fs.photos[0].id
200224
planar = _first_planar_from_fieldsite(fs)
201225
if planar:
202-
d["observations"] = [{"orientation": {"strike": float(planar.strike), "dip": float(planar.dip)}}]
226+
d["observations"] = [
227+
{"orientation": {"strike": float(planar.strike), "dip": float(planar.dip)}}
228+
]
203229
return d
204230

205231

206232
@interchange_router.post("/fieldsite-to-checkin")
207-
def multiple_fieldsite_to_checkin(fieldsites: list[FieldSite] = Body(...)) -> list[dict]:
233+
def multiple_fieldsite_to_checkin(
234+
fieldsites: list[FieldSite] = Body(...),
235+
) -> list[dict]:
208236
out: list[dict] = []
209237
for fs in fieldsites:
210238
try:
@@ -213,11 +241,19 @@ def multiple_fieldsite_to_checkin(fieldsites: list[FieldSite] = Body(...)) -> li
213241
continue
214242
return out
215243

244+
216245
@interchange_router.post("/spot-to-checkin")
217-
async def spot_to_checkin(request: Request, spot: Union[dict, List[dict]] = Body(...)) -> list[dict]:
246+
async def spot_to_checkin(
247+
request: Request, spot: Union[dict, List[dict]] = Body(...)
248+
) -> list[dict]:
218249
"""Pipeline: Spot JSON (FeatureCollection[s]) or FieldSite list -> Checkin list."""
219250
# If it's already a list of FieldSite-like dicts (has 'location'), skip the first hop
220-
if isinstance(spot, list) and spot and isinstance(spot[0], dict) and "location" in spot[0]:
251+
if (
252+
isinstance(spot, list)
253+
and spot
254+
and isinstance(spot[0], dict)
255+
and "location" in spot[0]
256+
):
221257
fieldsites: List[FieldSite] = spot # already FieldSite-shaped
222258
else:
223259
# Convert FeatureCollection (or list of them) -> FieldSite list

0 commit comments

Comments
 (0)