Skip to content

Commit

Permalink
Merge 2d4e310 into 7d84b0e
Browse files Browse the repository at this point in the history
  • Loading branch information
JWCook committed Jul 5, 2021
2 parents 7d84b0e + 2d4e310 commit 9fe9695
Show file tree
Hide file tree
Showing 35 changed files with 229 additions and 78 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Thanks to the following individuals for providing pull requests, feedback, bug r
questions, and other contributions that have helped to improve pyinaturalist:

* [AE Hamrick](https://github.com/AEHamrick)
* [Ben Armstrong](https://github.com/synrg)
* [Felipe S Barros](https://github.com/FelipeSBarros)
* [Ken-ichi Ueda](https://github.com/kueda/)
* [Matt Muir](https://forum.inaturalist.org/u/muir)
Expand Down
4 changes: 2 additions & 2 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# History

## 0.14 (2021-TBD)
## 0.14 (2021-07-TBD)
[See all Issues & PRs for 0.14](https://github.com/niconoe/pyinaturalist/milestone/5?closed=1)

### New Endpoints
Expand Down Expand Up @@ -61,8 +61,8 @@ Model features:
### Other Changes
* Consolidated response formatting into a single `pprint()` function (instead of one per resource type)
* Refactored and reorganized the following internal utility modules (see API docs for details):
* `api_docs`
* `converters`
* `docs`
* `formatters`
* `request_params`
* Added a default response timeout of 5 seconds
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ about iNaturalist, the [iNaturalist Community Forum](https://forum.inaturalist.o
place to start.

## Related Projects
Other python projects related to iNaturalist:

* [Dronefly](https://github.com/synrg/dronefly): A Discord bot with iNaturalist data access features,
* [pyinaturalist-convert](https://github.com/JWCook/pyinaturalist-convert): Tools to convert observation data to and from multiple formats
* [pyinaturalist-open-data](https://github.com/JWCook/pyinaturalist-open-data): Tools for working with [iNaturalist open data](https://registry.opendata.aws/inaturalist-open-data/)
* [pyinaturalist-notebook](https://github.com/JWCook/pyinaturalist-notebook): Jupyter notebook Docker image for pyinaturalist
* [pyinaturalist-convert](https://github.com/JWCook/pyinaturalist-convert): (WIP) Tools to convert observation data to and from multiple formats
used by the iNaturalist Discord server.
6 changes: 3 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* ``forge`` is used to define and reuse documentation for API request parameters
* ``apidoc`` is used to generate rst sources for **modules**
* ``autosummary`` is used to generate rst sources for **packages and summaries**
* ``automodapi`` + ``pyinaturalist.api_docs.model_docs`` are used to generate model
* ``automodapi`` + ``pyinaturalist.docs.model_docs`` are used to generate model
documentation based on ``attrs`` fields + metadata
* ``intersphinx`` is used to insert links to other projects' docs
* Jinja templates provide some additional customization:
Expand Down Expand Up @@ -34,7 +34,7 @@
sys.path.insert(0, '..')
from pyinaturalist import __version__
from pyinaturalist.constants import DOCS_DIR, PROJECT_DIR, EXAMPLES_DIR, SAMPLE_DATA_DIR
from pyinaturalist.api_docs.model_docs import document_models
from pyinaturalist.docs.model_docs import document_models

# Relevant doc directories used in extension settings
CSS_DIR = join(DOCS_DIR, '_static')
Expand Down Expand Up @@ -118,7 +118,7 @@
# apidoc settings
apidoc_module_dir = PACKAGE_DIR
apidoc_output_dir = MODULE_DOCS_DIR
apidoc_excluded_paths = ['api_docs/*', 'models/*', 'node_api.py', 'rest_api.py']
apidoc_excluded_paths = ['docs/*', 'models/*', 'node_api.py', 'rest_api.py']
apidoc_extra_args = ['--templatedir=_templates']
apidoc_module_first = True
apidoc_separate_modules = True
Expand Down
2 changes: 1 addition & 1 deletion pyinaturalist/api_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from requests import Response, Session

import pyinaturalist
from pyinaturalist.api_docs import copy_signature
from pyinaturalist.constants import (
MAX_DELAY,
REQUESTS_PER_DAY,
Expand All @@ -19,6 +18,7 @@
MultiInt,
RequestParams,
)
from pyinaturalist.docs import copy_signature
from pyinaturalist.request_params import prepare_request

# Mock response content to return in dry-run mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
* Dynamic docs: Function signatures + docstrings based on API request params
* Static docs: Sphinx documentation on readthedocs.io
"""
from pyinaturalist.api_docs.forge_utils import (
from pyinaturalist.docs.emoji import EMOJI
from pyinaturalist.docs.forge_utils import (
copy_doc_signature,
copy_docstrings,
copy_signature,
Expand Down
137 changes: 137 additions & 0 deletions pyinaturalist/docs/emoji.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
"""Extended list of emoji to represent taxa"""
EMOJI = {
# Birds
3: '🐦',
574: '🦃',
879: '🐔',
71261: '🦅',
6888: '🦆',
1199: '🦚',
67569: '🦩',
2708: '🕊️',
6913: '🦢',
67564: '🐧',
19350: '🦉',
18874: '🦜',
# Amphibians + reptiles
20978: '🐸',
26036: '🦎',
26039: '🐊',
39532: '🐢',
85553: '🐍',
# Mammals
786045: '🐵',
43579: '🦍',
846280: '🦧',
47144: '🐶',
42048: '🐺',
42054: '🦊',
41660: '🦝',
41944: '🐱',
846273: '🐯',
43328: '🐴',
42158: '🦌',
42406: '🦬',
568826: '🐮',
848343: '🐷',
568847: '🐑',
42348: '🐐',
846209: '🐪',
925150: '🦙',
43691: '🐘',
43698: '🐹',
43094: '🐰',
45933: '🐿️',
43791: '🦫',
533971: '🦔',
40268: '🦇',
41636: '🐻',
848319: '🦘',
42981: '🐨',
53537: '🦥',
41770: '🦡',
526556: '🦦',
41871: '🦨',
846287: '🦡',
# Fish
47178: '🐟',
47233: '🐠',
47177: '🐡',
372843: '🦭',
152871: '🐋',
41479: '🐬',
47273: '🦈',
# Molluscs
47115: '🐌',
47459: '🐙',
127352: '🦑',
# Arthropods
85493: '🦀',
144114: '🦐',
311310: '🦞',
47119: '🕷️',
48894: '🦂',
172373: '🦂',
48900: '🦂',
372739: '🐛',
144128: '🐛',
47822: '🪰',
153429: '🦟',
81769: '🪳',
47651: '🦗',
47157: '🦋',
47201: '🐝',
47336: '🐜',
48511: '🐜',
47208: '🪲',
471714: '🐞',
# Plants
47126: '🌱',
136329: '🌲',
47903: '🌵',
47162: '🌾',
121943: '🌿',
70233: '🍀',
48866: '🌴',
544534: '🥥',
47605: '🌼',
605446: '🌻',
47690: '🌺',
48796: '🌺',
47329: '🌷',
47148: '🌹',
47727: '🍁',
53548: '🌳',
47853: '🌳',
151882: '🌳',
50998: '🌳',
47567: '🌳',
71434: '🌳',
47194: '🌳',
48699: '🥕',
47204: '🥦',
71291: '🍇',
48620: '🍈',
62910: '🍌',
50623: '🍊',
723302: '🍎',
49570: '🍍',
48874: '🥭',
47351: '🍒',
47733: '🫒',
55849: '🧄',
48516: '🍅',
48517: '🌶️',
62848: '🥑',
635417: '🌽',
55150: '🥝',
50299: '🍓',
634914: '🫐',
# Other
1: '🐾',
47491: '🪱',
47170: '🍄',
48222: '🟢',
67333: '🦠',
131236: '🦠',
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pyinaturalist/models/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@define_model
class Comment(BaseModel):
"""An observation comment, based on the schema of comments
"""📝 An observation comment, based on the schema of comments
from `GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_.
"""

Expand Down
6 changes: 3 additions & 3 deletions pyinaturalist/models/controlled_term.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@define_model
class Annotation(BaseModel):
"""An annotation, meaning a **controlled term value** applied by a **user** to an **observation**.
"""📝 An annotation, meaning a **controlled term value** applied by a **user** to an **observation**.
Based on the schema of annotations from
`GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_.
"""
Expand Down Expand Up @@ -45,7 +45,7 @@ def __str__(self) -> str:

@define_model
class ControlledTermValue(BaseModel):
"""A controlled term **value**, based on the schema of
"""📋 A controlled term **value**, based on the schema of
`GET /controlled_terms <https://api.inaturalist.org/v1/docs/#!/Controlled_Terms/get_controlled_terms>`_.
"""

Expand All @@ -62,7 +62,7 @@ def __str__(self):

@define_model
class ControlledTerm(BaseModel):
"""A controlled term, based on the schema of
"""📋 A controlled term, based on the schema of
`GET /controlled_terms <https://api.inaturalist.org/v1/docs/#!/Controlled_Terms/get_controlled_terms>`_.
"""

Expand Down
2 changes: 1 addition & 1 deletion pyinaturalist/models/identification.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

@define_model
class Identification(BaseModel):
"""An observation identification, based on the schema of
"""🔎 An observation identification, based on the schema of
`GET /identifications <https://api.inaturalist.org/v1/docs/#!/Identifications/get_identifications>`_.
"""

Expand Down
15 changes: 12 additions & 3 deletions pyinaturalist/models/life_list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from itertools import groupby
from typing import List

from pyinaturalist.constants import JsonResponse
from pyinaturalist.constants import JsonResponse, TableRow
from pyinaturalist.models import (
Taxon,
TaxonCount,
Expand All @@ -14,7 +14,7 @@

@define_model
class LifeListTaxon(TaxonCount):
"""A single taxon in a user's life list"""
"""🐦 A single :py:class:`.Taxon` in a user's :py:class:`.LifeList`"""

descendant_obs_count: int = field(default=0, doc='Number of observations of taxon children')
direct_obs_count: int = field(
Expand All @@ -26,14 +26,23 @@ def indent_level(self) -> int:
"""Indentation level corresponding to this item's rank level"""
return int(((70 - self.rank_level) / 5))

@property
def row(self) -> TableRow:
return {
'ID': self.id,
'Rank': self.rank,
'Name': {self.name},
'Count': self.count,
}

def __str__(self) -> str:
padding = " " * self.indent_level
return f'[{self.id:<8}] {padding} {self.rank.title()} {self.name}: {self.count}'


@define_model_collection
class LifeList(TaxonCounts):
"""A user's life list, based on the schema of ``GET /observations/taxonomy``"""
"""🐦✅📓 A user's life list, based on the schema of ``GET /observations/taxonomy``"""

count_without_taxon: int = field(default=0)
data: List[LifeListTaxon] = field(factory=list, converter=LifeListTaxon.from_json_list) # type: ignore
Expand Down
4 changes: 2 additions & 2 deletions pyinaturalist/models/observation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

@define(auto_attribs=False, init=False, field_transformer=add_lazy_attrs)
class Observation(BaseModel):
"""An observation, based the schema of
"""👤🔎🐦 An observation, based the schema of
`GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_.
"""

Expand Down Expand Up @@ -224,7 +224,7 @@ def __str__(self) -> str:

@define_model_collection
class Observations(BaseModelCollection):
"""A collection of observations"""
"""👥🔍🐦 A collection of observations"""

data: List[Observation] = field(factory=list, converter=Observation.from_json_list)

Expand Down
4 changes: 2 additions & 2 deletions pyinaturalist/models/observation_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

@define_model
class ObservationField(BaseModel):
"""An observation field **definition**, based on the schema of
"""📋 An observation field **definition**, based on the schema of
`GET /observation_fields <https://www.inaturalist.org/pages/api+reference#get-observation_fields>`_.
"""

Expand Down Expand Up @@ -59,7 +59,7 @@ def __str__(self) -> str:

@define_model
class ObservationFieldValue(BaseModel):
"""An observation field **value**, matching the schema of ``ofvs``
"""📝 An observation field **value**, based on the schema of ``Observation.ofvs``
from `GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_.
"""

Expand Down
6 changes: 4 additions & 2 deletions pyinaturalist/models/photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

@define_model
class Photo(BaseModel):
"""An observation photo, based on the schema of photos from
`GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_.
"""📷 An observation photo, based on the schema of photos from:
* `GET /observations <https://api.inaturalist.org/v1/docs/#!/Observations/get_observations>`_
* `GET /taxa <https://api.inaturalist.org/v1/docs/#!/Taxa/get_taxa>`
"""

attribution: str = field(default=None, doc='License attribution')
Expand Down
2 changes: 1 addition & 1 deletion pyinaturalist/models/place.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def convert_optional_lat_long(obj: Union[Dict, List, None, str]):

@define_model
class Place(BaseModel):
"""A curated or community-contributed place. Handles data from the following endpoints:
"""📍 A curated or community-contributed place. Handles data from the following endpoints:
* `GET /places/{id} <https://api.inaturalist.org/v1/docs/#!/Places/get_places_id>`_
* `GET /places/nearby <https://api.inaturalist.org/v1/docs/#!/Places/get_places_nearby>`_
Expand Down
Loading

0 comments on commit 9fe9695

Please sign in to comment.