Skip to content

Commit

Permalink
Sort non-property attrs by name; remove some completed TODOs
Browse files Browse the repository at this point in the history
  • Loading branch information
JWCook committed Jul 4, 2021
1 parent 9a24ea1 commit 320382e
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 42 deletions.
3 changes: 0 additions & 3 deletions pyinaturalist/api_docs/model_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ def get_model_classes() -> List[Type]:
return model_classes


# TODO: Also include regular @properties?
# TODO: CSS to style LazyProperties with a different background color?
# TODO: Remove autodoc member docs for LazyProperties
def get_model_doc(cls: Type) -> List[Tuple[str, str, str]]:
"""Get the name, type and description for all model attributes, properties, and LazyProperties.
If an attribute has metadata for options (possible values for the attribute), include those
Expand Down
2 changes: 1 addition & 1 deletion pyinaturalist/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
ID_CATEGORIES = ['improving', 'supporting', 'leading', 'maverick']
ORDER_DIRECTIONS = ['asc', 'desc']
PLACE_CATEGORIES = ['standard', 'community']
PROJECT_TYPES = ['collection', 'umbrella']
PROJECT_TYPES = ['assessment', 'bioblitz', 'collection', 'umbrella']
QUALITY_GRADES = ['casual', 'needs_id', 'research']
SEARCH_PROPERTIES = ['names', 'tags', 'description', 'place']
SOURCES = ['places', 'projects', 'taxa', 'users']
Expand Down
1 change: 0 additions & 1 deletion pyinaturalist/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ def _format_model_objects(obj: ResponseOrResults, cls: Type[BaseModel], **kwargs
return '\n'.join([str(obj) for obj in objects])


# TODO: Figure out type annotations for these. Or just replace with pprint()?
format_controlled_terms = partial(_format_model_objects, cls=ControlledTerm)
format_identifications = partial(_format_model_objects, cls=Identification)
format_observations = partial(_format_model_objects, cls=Observation)
Expand Down
43 changes: 21 additions & 22 deletions pyinaturalist/models/observation.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# TODO: Possible models for faves, sounds, and votes?
from datetime import datetime
from typing import Any, Dict, List, Optional

Expand Down Expand Up @@ -47,6 +48,7 @@ class Observation(BaseModel):
)
community_taxon_id: int = field(default=None, doc='The current community identification taxon')
description: str = field(default=None, doc='Observation description')
faves: List[Dict] = field(factory=list, doc='Details on users who have favorited the observation')
geoprivacy: str = field(default=None, options=GEOPRIVACY_LEVELS, doc='Location privacy level')
identifications_count: int = field(default=None, doc='Total number of identifications')
identifications_most_agree: bool = field(default=None, doc='Indicates if most identifications agree')
Expand All @@ -68,38 +70,22 @@ class Observation(BaseModel):
default=None,
doc='Indicates if coordinates are obscured (showing a broad approximate location on the map)',
)
observed_on: DateTime = datetime_field(doc='Date and time the organism was observed')
outlinks: List[Dict] = field(
factory=list, doc='Linked observation pages on other sites (e.g., GBIF)'
)
out_of_range: bool = field(
default=None, doc='Indicates if the taxon is observed outside of its known range'
)
owners_identification_from_vision: bool = field(
default=None, doc="Indicates if the owner's ID was selected from computer vision results"
)

place_guess: str = field(default=None, doc='Place name determined from observation coordinates')
place_ids: List[int] = field(factory=list)
positional_accuracy: int = field(
default=None, doc='GPS accuracy in meters (real accuracy, if obscured)'
)
public_positional_accuracy: int = field(
default=None, doc='GPS accuracy in meters (not accurate if obscured)'
)
quality_grade: str = field(default=None, options=QUALITY_GRADES, doc='Quality grade')
site_id: int = field(
default=None, doc='Site ID for iNaturalist network members, or ``1`` for inaturalist.org'
)
species_guess: str = field(default=None, doc="Taxon name from observer's initial identification")
observed_on: DateTime = datetime_field(doc='Date and time the organism was observed')
updated_at: DateTime = datetime_field(doc='Date and time the observation was last updated')
uri: str = field(default=None, doc='Link to observation details page')
uuid: str = field(
default=None, doc='Universally unique ID; generally preferred over ``id`` where possible'
)

# Nested collections
# TODO: Possible models for faves, sounds, and votes?
faves: List[Dict] = field(factory=list, doc='Details on users who have favorited the observation')
outlinks: List[Dict] = field(
factory=list, doc='Linked observation pages on other sites (e.g., GBIF)'
)
place_ids: List[int] = field(factory=list)
preferences: Dict[str, Any] = field(
factory=dict,
doc='Any user observation preferences (related to community IDs, coordinate access, etc.)',
Expand All @@ -111,10 +97,23 @@ class Observation(BaseModel):
project_ids_without_curator_id: List[int] = field(
factory=list, doc='Project IDs without curator identification for this observation'
)
public_positional_accuracy: int = field(
default=None, doc='GPS accuracy in meters (not accurate if obscured)'
)
quality_grade: str = field(default=None, options=QUALITY_GRADES, doc='Quality grade')
quality_metrics: List[Dict] = field(factory=list, doc='Data quality assessment metrics')
reviewed_by: List[int] = field(factory=list, doc='IDs of users who have reviewed the observation')
site_id: int = field(
default=None, doc='Site ID for iNaturalist network members, or ``1`` for inaturalist.org'
)
sounds: List[Dict] = field(factory=list, doc='Observation sound files')
species_guess: str = field(default=None, doc="Taxon name from observer's initial identification")
tags: List[str] = field(factory=list, doc='Arbitrary user tags added to the observation')
updated_at: DateTime = datetime_field(doc='Date and time the observation was last updated')
uri: str = field(default=None, doc='Link to observation details page')
uuid: str = field(
default=None, doc='Universally unique ID; generally preferred over ``id`` where possible'
)
votes: List[Dict] = field(factory=list, doc='Votes on data quality assessment metrics')

# Lazy-loaded model objects
Expand Down
30 changes: 19 additions & 11 deletions pyinaturalist/models/project.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from datetime import datetime
from typing import Dict, List

from pyinaturalist.constants import INAT_BASE_URL, Coordinates, DateTime, JsonResponse, TableRow
from pyinaturalist.constants import (
INAT_BASE_URL,
PROJECT_TYPES,
Coordinates,
DateTime,
JsonResponse,
TableRow,
)
from pyinaturalist.models import (
BaseModel,
LazyProperty,
Expand Down Expand Up @@ -81,21 +88,22 @@ class Project(BaseModel):
doc='Indicates if this is an umbrella project (containing observations from other projects)',
)
location: Coordinates = coordinate_pair()
place_id: int = field(default=None)
prefers_user_trust: bool = field(default=None)
project_type: str = field(default=None) # Enum
slug: str = field(default=None, doc='URL slug')
terms: str = field(default=None, doc='Project terms')
title: str = field(default=None, doc='Project title')
updated_at: DateTime = datetime_field(doc='Date and time the project was last updated')

# Nested collections
project_observation_rules: List[Dict] = field(factory=list)
place_id: int = field(default=None, doc='Project place ID')
prefers_user_trust: bool = field(
default=None,
doc='Indicates if the project wants users to share hidden coordinates with the project admins',
)
project_observation_rules: List[Dict] = field(factory=list, doc='Project observation rules')
project_type: str = field(default=None, options=PROJECT_TYPES, doc='Project type') # Enum
rule_preferences: List[Dict] = field(factory=list)
search_parameters: List[Dict] = field(factory=list, doc='Filters for observations to include')
site_features: List[Dict] = field(
factory=list, doc='Details about if/when the project was featured on inaturalist.org'
)
slug: str = field(default=None, doc='URL slug')
terms: str = field(default=None, doc='Project terms')
title: str = field(default=None, doc='Project title')
updated_at: DateTime = datetime_field(doc='Date and time the project was last updated')
user_ids: List[int] = field(factory=list)

# Lazy-loaded model objects
Expand Down
1 change: 0 additions & 1 deletion pyinaturalist/node_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def get_all_observations(**params) -> List[JsonResponse]:
return paginate_all(get_observations, method='id', **params)['results']


# TODO: Deprecate get_geojson_observations and move to pyinaturalist-convert
def get_geojson_observations(properties: List[str] = None, **params) -> JsonResponse:
"""Get all observation results combined into a GeoJSON ``FeatureCollection``.
By default this includes some basic observation properties as GeoJSON ``Feature`` properties.
Expand Down
1 change: 0 additions & 1 deletion pyinaturalist/request_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
The main purpose of these functions is to support some python-specific conveniences and translate
them into standard request parameters, along with request validation that makes debugging easier.
"""
# TODO: It would be nice to put all the multiple-choice options on the models and use attrs validators
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
from logging import getLogger
Expand Down
1 change: 0 additions & 1 deletion pyinaturalist/v0/observations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# TODO: Decide on consistent terminology for POST/PUT endpoints, rename, and add DeprecationWarnings to previous names
from logging import getLogger
from typing import List, Union

Expand Down
1 change: 0 additions & 1 deletion test/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,6 @@ def test_taxon__conservation_status():
assert cs.status_name == 'imperiled'


# TODO: No sample data for this yet. Only on get_taxa_by_id response for particular taxa.
def test_taxon__conservation_statuses():
css = Taxon.from_json(j_taxon_6_cs_statuses).conservation_statuses[0]
assert isinstance(css, ConservationStatus)
Expand Down

0 comments on commit 320382e

Please sign in to comment.