Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add models for API response objects #145

Closed
31 tasks done
Tracked by #217
JWCook opened this issue May 21, 2021 · 1 comment · Fixed by #157, #146, #160 or #174
Closed
31 tasks done
Tracked by #217

Add models for API response objects #145

JWCook opened this issue May 21, 2021 · 1 comment · Fixed by #157, #146, #160 or #174
Labels
enhancement New feature or request
Milestone

Comments

@JWCook
Copy link
Member

JWCook commented May 21, 2021

I would like to add models for all of our API response objects, as an alternative to working with just JSON. This would be a big improvement toward making this a fully-featured python API client.

To do this I'd like to use the attrs library. It's lightweight, fast, used everywhere (with a subset of very similar features added to the stdlib in 3.7 as dataclasses), integrated with python type annotations and mypy, and makes for super clean code.

Update: see pyinaturalist/models for what I've added so far.

Example

Quick example model for observation comments:

from attr import define, field
from datetime import datetime
from typing import Dict, List

@define
class Comment:
    body: str = field(default=None)
    hidden: bool = field(default=None)
    id: int = field(default=None)
    uuid: str = field(default=None)
    flags: List = field(factory=list)
    moderator_actions: List = field(factory=list)
    created_at: datetime = field(converter=try_datetime, factory=datetime.utcnow)

Some more examples here: naturtag/models.

Benefits

That gives you a ton of features that make responses easier to work with interactively, for example a nice default __str__ method and tab-completion:
tabs

More benefits:

  • The type hints make it easier to spot bugs in client code (compared to consuming JSON)
  • The type hints can also potentially be used to convert to other data formats (via cattrs); also see the recently started pyinaturalist-convert repo
  • Models could potentially be reused to create objects to submit to POST and PUT endpoints (which would mean a lot less referring to the docs to figure out what format it needs to be in).
  • attrs can generate slotted classes, which are faster and more memory-efficient than dicts (maybe only noticeable when working with larger datasets, though).
  • The features for defaults, validators, and converters would simplify and/or replace many of the functions currently in the request_params and response_format modules.

Integrating with API functions

This issue will just be for creating the models. Integrating them with the API can be a separate issue. I imagine that can work by either:

  1. Adding an option to pass to existing API functions
  2. Adding wrappers for the API functions to the models (e.g., Observation.search(...))

Tasks

Models:

  • Base
  • ControlledTerm
    • ControlledTermValue
    • Annotation
  • Comment
  • Identification
  • LifeList
    • LifeListTaxon
  • Observation
  • ObservationField
    • ObservationFieldValue
  • Photo
  • Place
  • Project
    • ProjectObservation
    • ProjectObservationField
    • ProjectUser
  • SearchResult
  • Taxon
    • ConservationStatus
    • EstablishmentMeans
    • TaxonCount
    • TaxonCounts
  • User

Other tasks:

@JWCook
Copy link
Member Author

JWCook commented Jun 18, 2021

Going to call this one done, and add separate issues for remaining tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
1 participant