Comments (3)
@niconoe One fairly simple way to accomplish this would be to use dryable
to wrap python requests
. In dry run mode, it would then log the request method, URL, parameters, headers, and any other kwargs instead of making a real API call. Here's a minimal example:
>>> import dryable
>>> import logging
>>> import requests
# Enable stdout logging for urllib and dryable; you could configure a FileHandler for this instead, if needed
>>> logging.basicConfig(level="DEBUG")
>>> @dryable.Dryable()
>>> def request(method, url, *args, **kwargs):
>>> return requests.request(method, url, *args, **kwargs)
>>> def get_observation(observation_id):
>>> return request(
>>> "GET",
>>> f"https://api.inaturalist.org/v1/observations/{observation_id}",
>>> headers={"Accept": "application/json"},
>>> )
# Dry run
>>> dryable.set(True)
>>> get_observation(43039160)
INFO:dryable:dryable[default] skip: request( GET, https://api.inaturalist.org/v1/observations/43039160, headers={'Accept': 'application/json'} )
# Real API call
>>> dryable.set(False)
>>> response = get_observation(43039160)
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.inaturalist.org:443
DEBUG:urllib3.connectionpool:https://api.inaturalist.org:443 "GET /v1/observations/43039160 HTTP/1.1" 200 None
>>> print(response.json())
{'total_results': 1, 'page': 1, 'per_page': 1, 'results': ['...']}
Some incremental improvements that could be added onto that, depending on the kind of testing you want to do:
- Toggle
dryable
using an environment variable or config value - Add more granular dry-run options using labels (
@dryable.Dryable(label='some_label')
). For example have one mode to dry-run all requests, and another mode to dry-runPOST
,PUT
, andDELETE
but allowGET
requests.
I could submit a PR for this soon, if you don't have the time for it.
from pyinaturalist.
Thanks for the explanations @JWCook, that looks prefect! A few quick comments:
- a basic boolean option would already be amazing!
- if we decide to provide more granularity, I agree the separation should be between read and write operations (
GET
vs the rest...) - if we decide to provide more granularity, I'd keep the API as simple as possible to end users (sensible defaults, ...)
- it might be good to provide this option in a similar way to global user-agent selection:
pyinaturalist.dry_run = True
(I prefer some generic name such asdry_run
thandryable
for our API - I noticed
dryable
is a relatively "low-activity" python package (number of users, commit, ...). I'm always wary of depending on other packages (for long term maintenance and compatibility reasons), so it might be good to quickly check if there are more "popular" alternatives (or maybe locally reinventing the wheel, but only if "easy and safe".
from pyinaturalist.
Good points. I was not able to find any more actively-maintained alternatives, but dryable
may be low-activity because it's pretty simple and doesn't need much maintenance. Looks like the most relevant part is really just a few lines of code: https://github.com/haarcuba/dryable/blob/master/dryable/__init__.py#L23-L30
Since this would be mainly for testing and not for use in a production system, two options to avoid adding a dependency would be:
- Just implement a similar decorator internally
- Add to dev dependencies only, and make it an optional import, for example:
def request(...):
...
# Apply dry-run decorator to request() only if dryable is installed
try:
import dryable
dryable.set(DRY_RUN_ENABLED)
request = dryable.Dryable(request)
except ImportError:
pass
from pyinaturalist.
Related Issues (20)
- Add missing annotation details to observation results HOT 2
- Full taxon load overwrites matched term HOT 1
- Add option to iNatClient.taxa.autocomplete() to fetch full records for matched taxa
- Apply default_params to client.taxa(id) HOT 3
- ConservationStatus model complete code to name mapping HOT 4
- Reloading full record does not pass all_names parameter HOT 6
- Send only changed items when updating project observation rules HOT 6
- pprint cannot handle field with value None HOT 2
- Async loop gets included in request params HOT 2
- Controller methods that take one or more IDs should take a single list arg instead of variable args
- Add GET /users/me endpoint from v1 API
- Feature request: Support community ID votes calculation
- Feature request: Access the place name from taxon_summary in TaxonSummary object HOT 2
- Use trusted publisher (OIDC) to publish distributions to PyPI
- Taxonomic tree features
- Add Search controller for main /search endpoint
- make_tree: tree with omitted ranks has out of order children HOT 2
- Add undocumented GET /taxa/lifelist_metadata endpoint
- Fix type annotations in API docs HOT 1
- Add lifelist metadata to response in ObservationController.life_list()
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyinaturalist.