Giter VIP home page Giter VIP logo

Comments (3)

JWCook avatar JWCook commented on June 1, 2024

@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-run POST, PUT, and DELETE but allow GET requests.

I could submit a PR for this soon, if you don't have the time for it.

from pyinaturalist.

niconoe avatar niconoe commented on June 1, 2024

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 as dry_run than dryable 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.

JWCook avatar JWCook commented on June 1, 2024

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:

  1. Just implement a similar decorator internally
  2. 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.