Source code for pyinaturalist.request_params

""" Helper functions for processing request parameters """
from datetime import date, datetime
from typing import Any, Dict, Optional

from dateutil.parser import parse as parse_timestamp
from dateutil.tz import tzlocal
from pyinaturalist.constants import DATETIME_PARAMS


# For Python < 3.5 compatibility
[docs]def merge_two_dicts(x, y): z = x.copy() z.update(y) return z
[docs]def preprocess_request_params(params: Optional[Dict[str, Any]]) -> Dict[str, Any]: """Perform type conversions, sanity checks, etc. on request parameters""" if not params: return {} params = convert_bool_params(params) params = convert_datetime_params(params) params = convert_list_params(params) params = strip_empty_params(params) return params
[docs]def is_int(value: Any) -> bool: """Determine if a value is a valid integer""" try: int(value) return True except (TypeError, ValueError): return False
[docs]def convert_bool_params(params: Dict[str, Any]) -> Dict[str, Any]: """Convert any boolean request parameters to javascript-style boolean strings""" for k, v in params.items(): if isinstance(v, bool): params[k] = str(v).lower() return params
[docs]def convert_datetime_params(params: Dict[str, Any]) -> Dict[str, Any]: """Convert any dates, datetimes, or timestamps in other formats into ISO 8601 strings. API behavior note: params that take date but not time info will accept a full timestamp and just ignore the time, so it's safe to parse both date and datetime strings into timestamps :raises: :py:exc:`dateutil.parser._parser.ParserError` if a date/datetime format is invalid """ for k, v in params.items(): if isinstance(v, datetime) or isinstance(v, date): params[k] = _isoformat(v) if k in DATETIME_PARAMS: params[k] = _isoformat(parse_timestamp(v)) return params
[docs]def convert_list_params(params: Dict[str, Any]) -> Dict[str, Any]: """Convert any list parameters into an API-compatible (comma-delimited) string. Will be url-encoded by requests. For example: `['k1', 'k2', 'k3'] -> k1%2Ck2%2Ck3` """ for k, v in params.items(): if isinstance(v, list): params[k] = ",".join(map(str, v)) return params
[docs]def strip_empty_params(params: Dict[str, Any]) -> Dict[str, Any]: """Remove any request parameters with empty or ``None`` values.""" return {k: v for k, v in params.items() if v or v is False}
def _isoformat(d): """Return a date or datetime in ISO format. If it's a datetime and doesn't already have tzinfo, set it to the system's local timezone. """ if isinstance(d, datetime) and not d.tzinfo: d = d.replace(tzinfo=tzlocal()) return d.isoformat()