diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1cc9b3e..aca4e55 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,14 @@ +**2023-12-28: Version 5.2.0:** + +* Expanded use of type hints in place of ``:rtype`` Sphinx directive +* Remove unused dependency ``deprecation`` +* Fix bug: path ``/tags/{id}/{entity_type}`` breaks entity wrapping logic (`issue #130 `_) + +**2023-11-15: Version 5.1.3:** + +* Remove deprecated escape sequences, which were causing downstream linter/unit test errors, from docstrings +* Remove references to removed properties from the module reference that were causing Sphinx warnings + **2023-09-12: Version 5.1.2:** * Address issue `#115 `_ by adding default values to :attr:`pdpyras.PDSession.retry` for Events and Change Events API client classes diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js index 08f3913..26378ff 100644 --- a/docs/_static/documentation_options.js +++ b/docs/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '5.1.3', + VERSION: '5.2.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/changelog.html b/docs/changelog.html index 17619cd..2730967 100644 --- a/docs/changelog.html +++ b/docs/changelog.html @@ -6,7 +6,7 @@ - Changelog — PagerDuty Python REST API Sessions 5.1.3 documentation + Changelog — PagerDuty Python REST API Sessions 5.2.0 documentation @@ -37,6 +37,17 @@

Changelog

+

2023-12-28: Version 5.2.0:

+
    +
  • Expanded use of type hints in place of :rtype Sphinx directive

  • +
  • Remove unused dependency deprecation

  • +
  • Fix bug: path /tags/{id}/{entity_type} breaks entity wrapping logic (issue #130)

  • +
+

2023-11-15: Version 5.1.3:

+
    +
  • Remove deprecated escape sequences, which were causing downstream linter/unit test errors, from docstrings

  • +
  • Remove references to removed properties from the module reference that were causing Sphinx warnings

  • +

2023-09-12: Version 5.1.2:

-
Return type:
-

str

+
Returns:
+

The deduplication key of the incident, if any.

@@ -769,15 +769,23 @@

API Client Classes
class pdpyras.ChangeEventsAPISession(api_key: str, debug=False)
-

Session class for submitting change events to the PagerDuty v2 Change Events API.

+

Session class for submitting events to the PagerDuty v2 Change Events API.

Implements methods for submitting change events to PagerDuty’s change events API. See the Change Events API documentation for more details.

Inherits from PDSession.

-prepare_headers(method, user_headers={})
+prepare_headers(method, user_headers={}) dict

Add user agent and content type headers for Change Events API requests.

+
+
Parameters:
+

user_headers – User-supplied headers that will override defaults

+
+
Returns:
+

The final list of headers to use in the request

+
+
@@ -798,7 +806,7 @@

API Client Classes
-submit(summary, source=None, custom_details=None, links=None, timestamp=None)
+submit(summary, source=None, custom_details=None, links=None, timestamp=None) str

Submit an incident change

Parameters:
@@ -810,8 +818,8 @@

API Client ClassesReturn type: -

str

+
Returns:
+

The response ID

@@ -969,8 +977,8 @@

URL Handling
-pdpyras.canonical_path(base_url: str, url: str)
-

Returns the canonical REST API path corresponding to a URL.

+pdpyras.canonical_path(base_url: str, url: str) str +

The canonical path from the API documentation corresponding to a URL

This is used to identify and classify URLs according to which particular API within REST API v2 it belongs to.

Explicitly supported canonical paths are defined in the list @@ -985,16 +993,16 @@

URL HandlingReturn type: -

str

+
Returns:
+

The canonical REST API v2 path corresponding to a URL.

-pdpyras.endpoint_matches(endpoint_pattern: str, method: str, path: str)
-

Returns true if a method and path match an endpoint pattern.

+pdpyras.endpoint_matches(endpoint_pattern: str, method: str, path: str) bool +

Whether an endpoint (method and canonical path) matches a given pattern

This is the filtering logic used for finding the appropriate entry in ENTITY_WRAPPER_CONFIG to use for a given method and API path.

@@ -1007,29 +1015,29 @@

URL Handlingcanonical_path())

-
Return type:
-

boolean

+
Returns:
+

True or False based on whether the pattern matches the endpoint

-pdpyras.is_path_param(path_node: str)
-

Returns true if a given node in a canonical path represents a parameter.

+pdpyras.is_path_param(path_node: str) bool +

Whether a part of a canonical path represents a variable parameter

Parameters:

path_node – The node (value between slashes) in the path

-
Return type:
-

bool

+
Returns:
+

True if the node is an arbitrary variable, False if it is a fixed value

-pdpyras.normalize_url(base_url: str, url: str)
+pdpyras.normalize_url(base_url: str, url: str) str

Normalize a URL to a complete API URL.

The url argument may be a path relative to the base URL or a full URL.

@@ -1043,9 +1051,6 @@

URL HandlingReturns:

The full API endpoint URL

-
Return type:
-

str

-

@@ -1055,13 +1060,8 @@

Entity Wrapping
-pdpyras.entity_wrappers(method: str, path: str)
+pdpyras.entity_wrappers(method: str, path: str) tuple

Obtains entity wrapping information for a given endpoint (path and method)

-

Returns a 2-tuple. The first element is the wrapper name that should be used -for the request body, and the second is the wrapper name to be used for the -response body. For either elements, if None is returned, that signals to -disable wrapping and pass the user-supplied request body or API response -body object unmodified.

Parameters:
-
Return type:
-

tuple

+
Returns:
+

A 2-tuple. The first element is the wrapper name that should be used for +the request body, and the second is the wrapper name to be used for the +response body. For either elements, if None is returned, that +signals to disable wrapping and pass the user-supplied request body or +API response body object unmodified.

-pdpyras.infer_entity_wrapper(method: str, path: str)
+pdpyras.infer_entity_wrapper(method: str, path: str) str

Infer the entity wrapper name from the endpoint using orthodox patterns.

This is based on patterns that are broadly applicable but not universal in the v2 REST API, where the wrapper name is predictable from the path and @@ -1091,16 +1095,13 @@

Entity Wrappingcanonical_path

-
Return type:
-

str

-
-pdpyras.unwrap(response: Response, wrapper)
-

Unwraps and returns a wrapped entity.

+pdpyras.unwrap(response: Response, wrapper) Union[dict, list] +

Unwraps a wrapped entity.

Parameters:
@@ -1194,7 +1199,7 @@

Helpers
-pdpyras.http_error_message(r: Response, context=None)
+pdpyras.http_error_message(r: Response, context=None) str

Formats a message describing a HTTP error.

Parameters:
@@ -1203,18 +1208,29 @@

HelpersReturns: +

The message to include in the HTTP error

+

-pdpyras.last_4(secret: str)
-

Returns an abbreviation of the input

+pdpyras.last_4(secret: str) str +

Truncate a sensitive value to its last 4 characters

+
+
Parameters:
+

secret – text to truncate

+
+
Returns:
+

The truncated text

+
+
-pdpyras.plural_name(obj_type: str)
+pdpyras.plural_name(obj_type: str) str

Pluralizes a name, i.e. the API name from the type property

Parameters:
@@ -1224,9 +1240,6 @@

Helpers

The name of the resource, i.e. the last part of the URL for the resource’s index URL

-
Return type:
-

str

-
@@ -1250,7 +1263,7 @@

Helpers
-pdpyras.truncate_text(text: str)
+pdpyras.truncate_text(text: str) str

Truncates a string longer than TEXT_LEN_LIMIT

Parameters:
@@ -1261,7 +1274,7 @@

Helpers
-pdpyras.try_decoding(r: Response)
+pdpyras.try_decoding(r: Response) Union[dict, list, str]

JSON-decode a response body

Returns the decoded body if successful; raises PDServerError otherwise.

diff --git a/docs/objects.inv b/docs/objects.inv index 0288105..be752f8 100644 Binary files a/docs/objects.inv and b/docs/objects.inv differ diff --git a/docs/py-modindex.html b/docs/py-modindex.html index 8a4fea3..2d0daed 100644 --- a/docs/py-modindex.html +++ b/docs/py-modindex.html @@ -5,7 +5,7 @@ - Python Module Index — PagerDuty Python REST API Sessions 5.1.3 documentation + Python Module Index — PagerDuty Python REST API Sessions 5.2.0 documentation diff --git a/docs/search.html b/docs/search.html index 868c7b9..5b06fd7 100644 --- a/docs/search.html +++ b/docs/search.html @@ -5,7 +5,7 @@ - Search — PagerDuty Python REST API Sessions 5.1.3 documentation + Search — PagerDuty Python REST API Sessions 5.2.0 documentation diff --git a/docs/searchindex.js b/docs/searchindex.js index 3ffd686..67434e7 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["changelog", "contributing", "index", "module_reference", "user_guide"], "filenames": ["changelog.rst", "contributing.rst", "index.rst", "module_reference.rst", "user_guide.rst"], "titles": ["Changelog", "Contribution Guide", "PDPYRAS: PagerDuty Python REST API Sessions", "Module Reference", "User Guide"], "terms": {"2023": [0, 4], "09": 0, "12": 0, "version": [0, 2, 3, 4], "5": [0, 1, 3, 4], "1": [0, 1, 3, 4], "2": [0, 3, 4], "address": [0, 3, 4], "issu": [0, 1, 3, 4], "115": 0, "ad": [0, 1, 3, 4], "default": [0, 2], "valu": [0, 3, 4], "pdpyra": [0, 1, 3, 4], "pdsession": [0, 2, 3, 4], "retri": [0, 2, 3], "event": [0, 2, 3], "chang": [0, 2, 3, 4], "api": [0, 1], "client": [0, 2], "class": [0, 1, 2, 4], "upgrad": [0, 1], "ci": 0, "imag": [0, 3], "add": [0, 1, 3, 4], "support": [0, 3, 4], "python": [0, 1, 4], "3": [0, 3, 4], "11": 0, "07": [0, 4], "18": 0, "fix": [0, 1], "bug": [0, 1, 3], "us": [0, 1, 2, 3], "iter_al": [0, 3, 4], "an": [0, 1, 3, 4], "endpoint": [0, 3, 4], "cursor": [0, 3, 4], "base": [0, 3, 4], "pagin": [0, 2, 3], "should": [0, 1, 3, 4], "correctli": 0, "call": [0, 3, 4], "out": [0, 1, 4], "iter_cursor": [0, 3, 4], "wa": [0, 3, 4], "make": [0, 1, 3, 4], "remov": [0, 3], "keyword": [0, 3, 4], "argument": [0, 3, 4], "06": 0, "26": [0, 4], "0": [0, 3, 4], "new": [0, 2, 3, 4], "featur": [0, 1, 2, 3], "abil": 0, "specifi": [0, 3, 4], "timestamp": [0, 3], "when": [0, 1, 3, 4], "submit": [0, 3, 4], "suppli": [0, 3, 4], "changeeventsapisess": [0, 2, 3, 4], "explicitli": [0, 3], "includ": [0, 1, 3, 4], "upstream": 0, "except": [0, 3, 4], "caus": [0, 3, 4], "rais": [0, 3, 4], "due": 0, "non": [0, 2, 3], "transient": [0, 3, 4], "network": [0, 3, 4], "error": [0, 1, 2], "break": 0, "deprec": [0, 3, 4], "function": [0, 1, 2], "tokenize_url_path": 0, "resource_envelop": 0, "object_typ": 0, "resource_nam": 0, "raise_on_error": 0, "__init__": 0, "all": [0, 1, 3, 4], "session": [0, 3, 4], "longer": [0, 1, 3, 4], "accept": [0, 3, 4], "name": [0, 1, 3, 4], "apisess": [0, 2, 3, 4], "attribut": [0, 3, 4], "object": [0, 3, 4], "method": [0, 3, 4], "properti": [0, 2, 3], "profiler_kei": 0, "raise_if_http_error": 0, "4": [0, 3, 4], "user": [0, 1, 2, 3], "me": 0, "i": [0, 1, 3, 4], "also": [0, 1, 3, 4], "ambigu": 0, "match": [0, 3, 4], "canon": [0, 3], "path": [0, 1, 3, 4], "id": [0, 3, 4], "solut": 0, "asmith": 0, "pd": 0, "short": [0, 3, 4], "circuit": [0, 3], "exact": [0, 3], "url": [0, 2], "05": 0, "17": 0, "incorpor": [0, 4], "bugfix": 0, "from": [0, 1, 2, 3], "103": 0, "av1m": 0, "gener": [0, 2, 3], "behind": 0, "102": 0, "unsaf": 0, "mix": 0, "string": [0, 3, 4], "format": [0, 3], "style": 0, "In": [0, 3, 4], "http": [0, 2, 3], "exhaust": 0, "messag": [0, 1, 3, 4], "print": [0, 1, 3, 4], "onli": [0, 3, 4], "limit": [0, 3, 4], "got": 0, "reach": 0, "necessarili": 0, "per": [0, 3, 4], "statu": [0, 3, 4], "01": 0, "note": [0, 1, 3, 4], "ha": [0, 1, 3, 4], "been": [0, 3, 4], "yank": 0, "patch": [0, 1], "releas": [0, 2], "v5": [0, 3, 4], "setup": [0, 2], "py": [0, 1, 4], "assum": [0, 1, 3, 4], "entiti": [0, 2], "wrap": [0, 2], "like": [0, 4], "rget": [0, 3, 4], "now": 0, "print_debug": [0, 3, 4], "enabl": [0, 3, 4], "verbos": [0, 3], "log": [0, 2, 3], "sy": [0, 3, 4], "stderr": [0, 3, 4], "set_api_kei": 0, "end": [0, 2, 3, 4], "v3": 0, "which": [0, 1, 3, 4], "life": 0, "follow": [0, 1, 3, 4], "next": [0, 1, 4], "minor": [0, 1], "them": [0, 1, 3, 4], "trigger": [0, 3, 4], "warn": [0, 3], "constructor": [0, 4], "thi": [0, 3, 4], "previous": 0, "set": [0, 1, 2, 3], "logger": [0, 3, 4], "effect": [0, 3, 4], "could": [0, 3], "fals": [0, 3, 4], "stop": 0, "iter": [0, 3, 4], "after": [0, 1, 3, 4], "first": [0, 1, 3, 4], "page": [0, 2, 3, 4], "result": [0, 2, 3], "wrapper": [0, 3, 4], "The": [0, 1, 2, 3], "determin": [0, 3], "automat": [0, 3, 4], "decor": [0, 2], "allow": [0, 3, 4], "partial": [0, 4], "return": [0, 3, 4], "case": [0, 1, 2, 3], "2022": 0, "10": [0, 3, 4], "13": 0, "request": [0, 1, 2, 3], "timeout": [0, 2, 3], "60": [0, 3], "api_key_access": [0, 3], "implement": [0, 3, 4], "formerli": 0, "parent": [0, 3, 4], "inherit": [0, 3], "did": 0, "need": [0, 1, 3, 4], "packag": [0, 1], "distribut": [0, 3], "build": [0, 1, 4], "02": 0, "22": 0, "yield": [0, 3, 4], "whenev": [0, 4], "pdhttperror": [0, 2, 3, 4], "strictli": [0, 3], "applic": [0, 3, 4], "level": [0, 3, 4], "e": [0, 1, 3, 4], "respons": [0, 2, 3], "v": [0, 1], "pdclienterror": [0, 2, 3, 4], "unnecessari": 0, "depend": [0, 1, 4], "were": 0, "hold": [0, 3], "7": 0, "compat": [0, 4], "squar": [0, 3, 4], "bracket": [0, 3, 4], "queri": [0, 2, 3], "paramet": [0, 2, 3], "ar": [0, 1, 3, 4], "list": [0, 3, 4], "type": [0, 2, 3], "forget": 0, "do": [0, 4], "so": [0, 1, 3, 4], "requir": [0, 1, 3, 4], "filter": [0, 3, 4], "stagger_cooldown": [0, 3, 4], "appli": [0, 3, 4], "form": [0, 3], "retrial": 0, "updat": [0, 2, 3], "persist": [0, 3, 4], "ani": [0, 1, 3, 4], "exist": [0, 1, 3, 4], "resourc": [0, 3], "provid": [0, 3], "2021": 0, "28": 0, "configur": [0, 2, 3], "instanc": [0, 3, 4], "variabl": [0, 3, 4], "suggest": 0, "pull": [0, 1], "48": 0, "made": [0, 3, 4], "badnetmask": 0, "drop": 0, "improv": 0, "code": [0, 1, 3, 4], "sampl": 0, "jackton1": 0, "65": 0, "replac": [0, 3], "escap": 0, "sequenc": 0, "doubl": 0, "splat": 0, "oper": [0, 4], "docstr": 0, "ashwin153": 0, "68": 0, "work": [0, 3, 4], "around": [0, 3], "plai": 0, "61": 0, "04": [0, 4], "hunner": 0, "56": 0, "03": 0, "regress": 0, "eventsapisess": [0, 2, 3, 4], "post": [0, 3, 4], "defin": [0, 3, 4], "bodi": [0, 3, 4], "json": [0, 3, 4], "without": [0, 3, 4], "routing_kei": [0, 3, 4], "possibl": [0, 1], "befor": [0, 1, 3, 4], "x": [0, 4], "rout": 0, "kei": [0, 3, 4], "header": [0, 2, 3], "undocu": 0, "document": [0, 2, 3, 4], "v2": [0, 2, 3], "53": 0, "arg": [0, 3], "backward": 0, "second": [0, 3, 4], "can": [0, 1, 3, 4], "modul": [0, 2, 4], "ctrlaltdel": 0, "2020": 0, "15": 0, "37": 0, "other": [0, 3, 4], "enhanc": 0, "10000": [0, 3], "encount": [0, 1, 3, 4], "versu": 0, "becaus": [0, 3, 4], "exceed": 0, "elicit": 0, "400": [0, 3, 4], "initi": [0, 2, 3, 4], "offset": [0, 3, 4], "via": [0, 3, 4], "param": [0, 3, 4], "alwai": [0, 1, 3, 4], "start": [0, 3, 4], "capit": [0, 3], "constant": 0, "instead": [0, 3, 4], "none": [0, 3, 4], "32": 0, "08": 0, "idempot": [0, 3, 4], "creator": 0, "dictionari": [0, 3, 4], "have": [0, 1, 3, 4], "self": [0, 3, 4], "place": [0, 4], "oauth": [0, 3], "access": [0, 1, 3, 4], "token": [0, 1, 3, 4], "authent": [0, 2, 3], "23": 0, "indic": [0, 4], "scope": [0, 4], "given": [0, 3, 4], "credenti": [0, 1, 3, 4], "trunc_token": [0, 3], "typo": 0, "attributeerror": 0, "2019": 0, "31": 0, "size": 0, "basi": 0, "_all": 0, "pass": [0, 3, 4], "page_s": [0, 3], "If": [0, 1, 3, 4], "present": 0, "captur": 0, "easier": [0, 3], "identifi": [0, 3, 4], "commun": [0, 1], "pagerduti": [0, 3, 4], "extend": [0, 3], "metadata": [0, 3, 4], "cooldown": [0, 2, 3], "time": [0, 1, 3, 4], "between": [0, 3, 4], "rate": [0, 3, 4], "option": [0, 3], "random": [0, 3, 4], "posit": [0, 3, 4], "number": [0, 1, 3, 4], "departur": 0, "payload": [0, 3], "doe": [0, 1, 3, 4], "merg": [0, 2, 3], "rather": [0, 3], "complet": [0, 2, 3], "behavior": [0, 2, 3], "some": [0, 1, 3, 4], "intern": 0, "tool": [0, 1], "previou": [0, 3], "Not": 0, "intend": [0, 3], "design": [0, 3, 4], "At": [0, 4], "odd": 0, "introduct": 0, "custom": [0, 3, 4], "agent": [0, 3], "distinguish": 0, "purpos": [0, 3], "usag": [0, 2, 3], "analyt": 0, "import": [0, 1, 4], "logic": [0, 3, 4], "keyerror": [0, 4], "incorrect": 0, "more": [0, 3, 4], "than": [0, 3, 4], "amount": [0, 3], "faulti": 0, "comparison": 0, "14": 0, "A": [0, 1, 3, 4], "light": 0, "refactor": 0, "specif": [0, 4], "send": [0, 3, 4], "send_ev": [0, 3], "catch": [0, 3, 4], "incid": [0, 3, 4], "still": [0, 3, 4], "most": [0, 1, 3, 4], "same": [0, 1, 3, 4], "rest": [0, 3], "unpack": 0, "log_entri": 0, "whitelist": 0, "r": [0, 1, 3, 4], "rescind": 0, "how": [0, 3, 4], "help": [0, 1, 3], "thei": [0, 3, 4], "don": 0, "t": [0, 3, 4], "envelop": 0, "auto": [0, 3], "valid": [0, 1, 3, 4], "presenc": [0, 4], "order": [0, 3], "busi": 0, "impact": 0, "metric": 0, "2018": 0, "list_al": [0, 3, 4], "dict_al": [0, 3, 4], "turn": 0, "index": [0, 1, 3, 4], "dict": [0, 3, 4], "save": [0, 4], "bit": 0, "effort": 0, "perform": [0, 2, 3], "multi": [0, 2], "action": [0, 3, 4], "manag": [0, 4], "rput": [0, 3, 4], "receiv": [0, 3, 4], "dure": [0, 3], "report": [1, 3], "welcom": 1, "built": 1, "recommend": [1, 3, 4], "assert": 1, "appropri": [1, 3, 4], "test_pdpyra": 1, "ensur": 1, "coverag": 1, "": [1, 3, 4], "pleas": [1, 3], "reproduc": 1, "along": 1, "themselv": 1, "github": [1, 2], "commit": 1, "To": [1, 3, 4], "abl": 1, "rebuild": 1, "sure": 1, "you": [1, 3], "pip": [1, 4], "your": [1, 4], "shell": 1, "environ": 1, "well": [1, 4], "local": [1, 4], "txt": 1, "root": [1, 3, 4], "repositori": [1, 2], "suit": 1, "rst": 1, "file": 1, "sphinx": 1, "sourc": [1, 3, 4], "where": [1, 3, 4], "live": 1, "html": 1, "doc": [1, 3], "forc": 1, "touch": 1, "changelog": [1, 2], "account": [1, 3, 4], "both": [1, 3, 4], "pypi": [1, 2], "org": 1, "maintain": 1, "role": 1, "project": [1, 2], "see": [1, 3, 4], "abov": [1, 4], "It": [1, 3, 4], "strongli": 1, "upload": 1, "onc": [1, 3, 4], "even": 1, "delet": [1, 2, 3], "For": [1, 3, 4], "reason": 1, "good": 1, "idea": 1, "suffix": [1, 3], "dev001": 1, "__version__": 1, "while": [1, 2], "enter": 1, "prompt": 1, "testpublish": 1, "target": [1, 4], "egg": 1, "dist": 1, "librari": [1, 4], "temporari": [1, 3], "virtualenv": 1, "alreadi": [1, 3, 4], "script": 1, "immedi": [1, 3, 4], "exit": [1, 3], "investig": 1, "mitig": 1, "again": 1, "temporarili": 1, "count": [1, 3], "get": [1, 3, 4], "desir": [1, 4], "actual": [1, 3], "creat": [1, 2, 3], "least": 1, "item": [1, 3], "correspond": [1, 3, 4], "parenthes": 1, "handl": [1, 2], "contributor": 1, "slash": [1, 3, 4], "link": [1, 3], "preexist": [1, 3], "exampl": [1, 2, 3], "semant": 1, "rebuilt": 1, "view": 1, "open": [1, 4], "web": [1, 3, 4], "browser": 1, "review": 1, "approv": 1, "Then": 1, "checkout": 1, "main": [1, 4], "git": 1, "origin": [1, 4], "c": 1, "push": 1, "clone": 1, "branch": 1, "check": [1, 3], "latest": [1, 4], "avail": [1, 4], "tree": 1, "clean": 1, "uncommit": 1, "__token__": 1, "usernam": 1, "password": 1, "final": [1, 4], "fill": 1, "detail": [1, 3, 4], "select": 1, "choos": 1, "being": [1, 3, 4], "major": 1, "veri": [1, 4], "brief": [1, 3], "summari": [1, 3, 4], "compos": [1, 3, 4], "descript": [1, 3], "whose": [1, 3, 4], "refer": [2, 4], "guid": [2, 3], "instal": 2, "u": 2, "servic": 2, "region": 2, "basic": 2, "data": [2, 3], "schema": [2, 3], "awar": [2, 3], "classic": [2, 3], "pattern": [2, 3], "special": [2, 3], "proxi": 2, "server": [2, 3], "exponenti": 2, "pdservererror": [2, 3], "urlerror": [2, 3], "canonical_path": [2, 3], "cursor_based_pagination_path": [2, 3], "entity_wrapper_config": [2, 3, 4], "iteration_limit": [2, 3], "text_len_limit": [2, 3], "helper": 2, "contribut": 2, "run": [2, 4], "unit": 2, "test": 2, "publish": [2, 4], "tag": 2, "cover": 3, "individu": [3, 4], "api_kei": [3, 4], "str": 3, "debug": [3, 4], "opinion": 3, "few": 3, "addit": [3, 4], "reattempt": 3, "increas": [3, 4], "interv": 3, "attempt": [3, 4], "through": [3, 4], "hoc": 3, "verb": 3, "doesn": [3, 4], "prepend": 3, "permitted_method": 3, "bool": 3, "true": [3, 4], "command": [3, 4], "line": [3, 4], "output": [3, 4], "after_set_api_kei": 3, "setter": 3, "hook": 3, "child": 3, "step": [3, 4], "getter": 3, "_api_kei": 3, "auth_head": 3, "By": [3, 4], "handler": [3, 4], "emit": 3, "max_http_attempt": [3, 4], "status": [3, 4], "greater": 3, "zero": 3, "max_network_attempt": [3, 4], "connect": 3, "treat": 3, "failur": 3, "happen": [3, 4], "normalize_param": 3, "modifi": [3, 4], "current": 3, "append": [3, 4], "keep": [3, 4], "normalize_url": 3, "whether": [3, 4], "super": 3, "tupl": 3, "permit": 3, "put": [3, 4], "postprocess": 3, "supplement": 3, "prepare_head": 3, "user_head": 3, "upper": 3, "overrid": [3, 4], "flag": 3, "notset": [3, 4], "thu": [3, 4], "toggl": 3, "disabl": [3, 4], "wai": [3, 4], "product": [3, 4], "kwarg": 3, "insensit": 3, "mai": [3, 4], "one": [3, 4], "each": [3, 4], "reflect": 3, "must": [3, 4], "separ": 3, "int": 3, "repres": [3, 4], "infinit": 3, "n": [3, 4], "up": [3, 4], "total": [3, 4], "whichev": 3, "mani": [3, 4], "success": [3, 4], "wait": [3, 4], "factor": [3, 4], "sleep_timer_bas": [3, 4], "429": [3, 4], "sleep_tim": [3, 4], "followup": 3, "delai": 3, "equal": 3, "power": 3, "far": 3, "unless": [3, 4], "nonzero": [3, 4], "sleep": [3, 4], "adjust": 3, "plu": [3, 4], "uniformli": 3, "top": 3, "timer": 3, "overal": 3, "wherea": 3, "just": 3, "avoid": [3, 4], "thunder": 3, "herd": 3, "potenti": 3, "simultan": 3, "concurr": 3, "consequ": 3, "consist": 3, "sent": [3, 4], "tcp": 3, "read": [3, 4], "trunc_kei": 3, "truncat": 3, "secur": 3, "displai": 3, "identif": 3, "default_from": [3, 4], "auth_typ": [3, 4], "oft": 3, "aspect": 3, "email": [3, 4], "oauth2": [3, 4], "bearer": 3, "member": 3, "api_call_count": 3, "record": [3, 4], "memoiz": 3, "Will": 3, "permiss": 3, "ui": 3, "global": 3, "administr": [3, 4], "api_tim": 3, "default_page_s": 3, "100": [3, 4], "kw": 3, "With": 3, "further": 3, "uniqu": [3, 4], "distinct": 3, "omit": 3, "find": [3, 4], "exactli": [3, 4], "found": [3, 4], "structur": [3, 4], "entri": [3, 4], "arrai": [3, 4], "otherwis": [3, 4], "expect": [3, 4], "ignor": 3, "take": [3, 4], "much": 3, "constrain": 3, "those": [3, 4], "everi": 3, "download": [3, 4], "compar": 3, "against": 3, "until": [3, 4], "escalation_polici": [3, 4], "search": [3, 4], "item_hook": 3, "content": [3, 4], "pagint": 3, "k": [3, 4], "numer": [3, 4], "alter": 3, "preced": [3, 4], "differ": [3, 4], "dictat": 3, "what": [3, 4], "callabl": 3, "invok": 3, "progress": 3, "three": [3, 4], "seri": 3, "isn": 3, "knowabl": 3, "third": 3, "leav": 3, "confer": 3, "small": 3, "advantag": 3, "comput": 3, "jget": [3, 4], "decod": [3, 4], "jpost": 3, "jput": 3, "directli": [3, 4], "attr": 3, "pair": [3, 4], "underli": [3, 4], "ap": 3, "contain": [3, 4], "inform": 3, "about": [3, 4], "rdelet": 3, "retriev": 3, "represent": [3, 4], "rpost": [3, 4], "subdomain": 3, "total_call_count": 3, "total_call_tim": 3, "spent": 3, "com": [3, 4], "acknowledg": [3, 4], "dedup_kei": [3, 4], "alert": [3, 4], "dedupl": [3, 4], "state": [3, 4], "resolv": [3, 4], "develop": 3, "associ": 3, "would": [3, 4], "sever": 3, "critic": 3, "custom_detail": 3, "wrong": 3, "human": 3, "readabl": 3, "system": [3, 4], "affect": [3, 4], "conjunct": 3, "regard": 3, "send_change_ev": 3, "iso8601": 3, "date": 3, "impli": 3, "sole": 3, "experienc": 3, "4xx": 3, "descend": [3, 4], "backend": 3, "successfulli": 3, "cleanli": 3, "guarante": 3, "its": [3, 4], "denot": [3, 4], "thing": 3, "wherein": 3, "recevi": 3, "try": [3, 4], "pabc123": [3, 4], "status_cod": [3, 4], "els": [3, 4], "write": [3, 4], "fail": 3, "earli": 3, "ga": 3, "5xx": [3, 4], "unsupport": 3, "malform": 3, "input": 3, "These": 3, "There": 3, "explicit": 3, "antipattern": 3, "convent": [3, 4], "infer": 3, "infer_entity_wrapp": 3, "therefor": [3, 4], "properli": 3, "space": 3, "either": [3, 4], "marshal": 3, "unmarsh": 3, "unwrap": [3, 4], "under": [3, 4], "said": [3, 4], "transmit": 3, "apart": 3, "secondari": 3, "bear": [3, 4], "discard": [3, 4], "prevent": 3, "maximum": [3, 4], "exce": 3, "enforc": 3, "side": 3, "someth": 3, "longest": 3, "length": 3, "own": 3, "typic": [3, 4], "benefit": 3, "anyon": 3, "who": 3, "relat": 3, "base_url": 3, "classifi": 3, "accord": [3, 4], "particular": [3, 4], "within": 3, "belong": 3, "part": [3, 4], "shown": 3, "contact_method": 3, "contact": 3, "normal": [3, 4], "full": [3, 4], "endpoint_match": 3, "endpoint_pattern": 3, "uppercas": 3, "boolean": 3, "is_path_param": 3, "path_nod": 3, "node": [3, 4], "rel": [3, 4], "baseurl": 3, "exclud": 3, "trail": 3, "entity_wrapp": 3, "obtain": [3, 4], "element": 3, "signal": 3, "unmodifi": 3, "orthodox": 3, "broadli": 3, "univers": 3, "predict": 3, "subclass": [3, 4], "auto_json": 3, "requires_success": 3, "resource_url": 3, "itself": [3, 4], "elimin": 3, "re": 3, "construct": [3, 4], "wrapped_ent": 3, "encod": [3, 4], "reform": 3, "miscellan": 3, "deprecated_kwarg": 3, "deprecated_nam": 3, "http_error_messag": 3, "context": [3, 4], "describ": 3, "last_4": 3, "secret": [3, 4], "abbrevi": 3, "plural_nam": 3, "obj_typ": 3, "plural": [3, 4], "user_refer": [3, 4], "last": [3, 4], "successful_respons": 3, "truncate_text": 3, "text": 3, "try_decod": 3, "topic": 4, "depth": 4, "altern": 4, "directori": 4, "session_oauth": 4, "oauth_token": 4, "events_sess": 4, "change_events_sess": 4, "do_appl": 4, "integr": 4, "menu": 4, "tab": 4, "profil": 4, "deriv": 4, "necessari": 4, "eu": 4, "outsid": 4, "ok": 4, "collect": 4, "convert": 4, "sn": 4, "look": 4, "jane": 4, "example35": 4, "updated_us": 4, "user_data": 4, "user123": 4, "mcuserson": 4, "ordinarili": 4, "prior": 4, "paramt": 4, "assign": 4, "user_id": 4, "phij789": 4, "5b": 4, "5d": 4, "updated_incid": 4, "fire": 4, "dusti": 4, "old": 4, "net": 4, "abc123": 4, "finish": 4, "head": 4, "autom": 4, "sinc": 4, "similar": 4, "analog": 4, "j": 4, "though": 4, "howev": 4, "lead": 4, "One": 4, "strip": 4, "As": 4, "everyth": 4, "simpli": 4, "serial": 4, "first_dan": 4, "dan": 4, "v4": 4, "82": 4, "foo": 4, "foo_servic": 4, "team": 4, "50": 4, "plain": 4, "That": 4, "uuid": 4, "encapsul": 4, "insid": 4, "articl": 4, "analogu": 4, "speak": 4, "consid": 4, "escal": 4, "polici": 4, "ep": 4, "escalation_rul": 4, "daili": 4, "engin": 4, "rotat": 4, "rule": 4, "new_rul": 4, "escalation_delay_in_minut": 4, "30": 4, "pam4fg": 4, "pi7dh85": 4, "schedule_refer": 4, "respect": 4, "respond": 4, "anoth": 4, "singl": 4, "extract": 4, "singular": 4, "noun": 4, "On": 4, "equival": 4, "decid": 4, "store": 4, "point": 4, "control": 4, "business_servic": 4, "subscrib": 4, "subscript": 4, "unusu": 4, "vice": 4, "versa": 4, "schedul": 4, "incient": 4, "status_upd": 4, "created_overrid": 4, "pghi789": 4, "01t00": 4, "00": 4, "02t00": 4, "peysgva": 4, "time_zon": 4, "utc": 4, "03t00": 4, "peysgvf": 4, "201": 4, "fetch": 4, "dav": 4, "dave": 4, "david": 4, "bob": 4, "synchron": 4, "multipl": 4, "thread": 4, "higher": 4, "moreov": 4, "larg": 4, "volum": 4, "wise": 4, "erron": 4, "condit": 4, "sort": 4, "real": 4, "recalcul": 4, "skip": 4, "repeat": 4, "accordingli": 4, "process": 4, "manual": 4, "edit": 4, "elabor": 4, "let": 4, "sai": 4, "notebook": 4, "essenti": 4, "go": 4, "101st": 4, "201st": 4, "etc": 4, "tear": 4, "shift": 4, "becom": 4, "hundr": 4, "over": 4, "similarli": 4, "401": 4, "500": 4, "601": 4, "700": 4, "attach": 4, "opposit": 4, "bump": 4, "group": 4, "prioriti": 4, "yet": 4, "two": 4, "pdef456": 4, "incident_refer": 4, "effici": 4, "login": 4, "differenti": 4, "pertain": 4, "404": 4, "pjkl678": 4, "introduc": 4, "Its": 4, "unconfigur": 4, "defer": 4, "left": 4, "discret": 4, "later": 4, "streamhandl": 4, "host": 4, "traffic": 4, "42": 4, "187": 4, "port": 4, "4012": 4, "protocol": 4, "unsuccess": 4, "loop": 4, "period": 4, "\u03c1": 4, "indefinit": 4, "cannot": 4, "overridden": 4, "sane": 4, "approach": 4, "ever": 4, "too": 4, "natur": 4, "rogu": 4, "satur": 4, "unauthor": 4, "invalid": 4, "prefer": 4, "hang": 4, "continu": 4, "502": 4, "toler": 4, "supersed": 4, "lower": 4, "carri": 4, "four": 4, "8": 4, "16": 4, "paus": 4, "won": 4, "pnoexst": 4, "62": 4, "6": 4}, "objects": {"": [[3, 0, 0, "module-3", "pdpyras"]], "pdpyras": [[3, 1, 1, "", "APISession"], [3, 5, 1, "", "CANONICAL_PATHS"], [3, 5, 1, "", "CURSOR_BASED_PAGINATION_PATHS"], [3, 1, 1, "", "ChangeEventsAPISession"], [3, 5, 1, "", "ENTITY_WRAPPER_CONFIG"], [3, 1, 1, "", "EventsAPISession"], [3, 5, 1, "", "ITERATION_LIMIT"], [3, 1, 1, "", "PDClientError"], [3, 1, 1, "", "PDHTTPError"], [3, 1, 1, "", "PDServerError"], [3, 1, 1, "", "PDSession"], [3, 5, 1, "", "TEXT_LEN_LIMIT"], [3, 5, 1, "", "TIMEOUT"], [3, 1, 1, "", "URLError"], [3, 6, 1, "", "auto_json"], [3, 6, 1, "", "canonical_path"], [3, 6, 1, "", "deprecated_kwarg"], [3, 6, 1, "", "endpoint_matches"], [3, 6, 1, "", "entity_wrappers"], [3, 6, 1, "", "http_error_message"], [3, 6, 1, "", "infer_entity_wrapper"], [3, 6, 1, "", "is_path_param"], [3, 6, 1, "", "last_4"], [3, 6, 1, "", "normalize_url"], [3, 6, 1, "", "plural_name"], [3, 6, 1, "", "requires_success"], [3, 6, 1, "", "resource_url"], [3, 6, 1, "", "successful_response"], [3, 6, 1, "", "truncate_text"], [3, 6, 1, "", "try_decoding"], [3, 6, 1, "", "unwrap"], [3, 6, 1, "", "wrapped_entities"]], "pdpyras.APISession": [[3, 2, 1, "", "api_call_counts"], [3, 3, 1, "", "api_key_access"], [3, 2, 1, "", "api_time"], [3, 3, 1, "", "auth_type"], [3, 2, 1, "", "default_from"], [3, 2, 1, "", "default_page_size"], [3, 4, 1, "", "dict_all"], [3, 4, 1, "", "find"], [3, 4, 1, "", "iter_all"], [3, 4, 1, "", "iter_cursor"], [3, 4, 1, "", "jget"], [3, 4, 1, "", "jpost"], [3, 4, 1, "", "jput"], [3, 4, 1, "", "list_all"], [3, 4, 1, "", "persist"], [3, 4, 1, "", "postprocess"], [3, 4, 1, "", "rdelete"], [3, 4, 1, "", "rget"], [3, 4, 1, "", "rpost"], [3, 4, 1, "", "rput"], [3, 3, 1, "", "subdomain"], [3, 3, 1, "", "total_call_count"], [3, 3, 1, "", "total_call_time"], [3, 3, 1, "", "trunc_token"], [3, 2, 1, "", "url"]], "pdpyras.ChangeEventsAPISession": [[3, 4, 1, "", "prepare_headers"], [3, 4, 1, "", "send_change_event"], [3, 4, 1, "", "submit"]], "pdpyras.EventsAPISession": [[3, 4, 1, "", "acknowledge"], [3, 4, 1, "", "post"], [3, 4, 1, "", "prepare_headers"], [3, 4, 1, "", "resolve"], [3, 4, 1, "", "send_event"], [3, 4, 1, "", "trigger"]], "pdpyras.PDClientError": [[3, 2, 1, "", "response"]], "pdpyras.PDSession": [[3, 4, 1, "", "after_set_api_key"], [3, 3, 1, "", "api_key"], [3, 3, 1, "", "auth_header"], [3, 2, 1, "", "log"], [3, 2, 1, "", "max_http_attempts"], [3, 2, 1, "", "max_network_attempts"], [3, 4, 1, "", "normalize_params"], [3, 4, 1, "", "normalize_url"], [3, 2, 1, "", "parent"], [3, 2, 1, "", "permitted_methods"], [3, 4, 1, "", "postprocess"], [3, 4, 1, "", "prepare_headers"], [3, 3, 1, "", "print_debug"], [3, 4, 1, "", "request"], [3, 2, 1, "", "retry"], [3, 2, 1, "", "sleep_timer"], [3, 2, 1, "", "sleep_timer_base"], [3, 3, 1, "", "stagger_cooldown"], [3, 2, 1, "", "timeout"], [3, 3, 1, "", "trunc_key"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute", "3": "py:property", "4": "py:method", "5": "py:data", "6": "py:function"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "method", "Python method"], "5": ["py", "data", "Python data"], "6": ["py", "function", "Python function"]}, "titleterms": {"changelog": 0, "contribut": 1, "guid": [1, 4], "initi": 1, "setup": 1, "run": 1, "unit": 1, "test": 1, "updat": [1, 4], "document": 1, "releas": 1, "new": 1, "version": 1, "perform": [1, 4], "end": 1, "publish": 1, "instal": [1, 4], "merg": 1, "chang": 1, "tag": 1, "pdpyra": 2, "pagerduti": 2, "python": 2, "rest": [2, 4], "api": [2, 3, 4], "session": 2, "extern": 2, "resourc": [2, 4], "tabl": 2, "content": 2, "modul": 3, "refer": 3, "client": [3, 4], "class": 3, "error": [3, 4], "default": [3, 4], "function": [3, 4], "url": [3, 4], "handl": [3, 4], "entiti": [3, 4], "wrap": [3, 4], "decor": 3, "helper": 3, "user": 4, "authent": 4, "The": 4, "from": 4, "header": 4, "us": 4, "non": 4, "u": 4, "servic": 4, "region": 4, "basic": 4, "usag": 4, "exampl": 4, "v2": 4, "event": 4, "gener": 4, "featur": 4, "queri": 4, "paramet": 4, "request": 4, "respons": 4, "data": 4, "type": 4, "schema": 4, "awar": 4, "classic": 4, "pattern": 4, "special": 4, "case": 4, "pagin": 4, "complet": 4, "result": 4, "creat": 4, "delet": 4, "while": 4, "multi": 4, "log": 4, "proxi": 4, "server": 4, "http": 4, "retri": 4, "configur": 4, "exponenti": 4, "cooldown": 4, "behavior": 4, "set": 4, "properti": 4}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "sphinx": 57}, "alltitles": {"Changelog": [[0, "changelog"]], "Contribution Guide": [[1, "contribution-guide"]], "Initial Setup": [[1, "initial-setup"]], "Running Unit Tests": [[1, "running-unit-tests"]], "Updating Documentation": [[1, "updating-documentation"]], "Releasing a New Version": [[1, "releasing-a-new-version"]], "Perform end-to-end publish and installation testing": [[1, "perform-end-to-end-publish-and-installation-testing"]], "Merge changes and tag": [[1, "merge-changes-and-tag"]], "Publishing": [[1, "publishing"]], "PDPYRAS: PagerDuty Python REST API Sessions": [[2, "pdpyras-pagerduty-python-rest-api-sessions"]], "External Resources": [[2, "external-resources"]], "Table of Contents": [[2, "table-of-contents"]], "Module Reference": [[3, "module-reference"]], "API Client Classes": [[3, "api-client-classes"]], "Errors": [[3, "errors"]], "Client Defaults": [[3, "client-defaults"]], "Functions": [[3, "functions"]], "URL Handling": [[3, "url-handling"]], "Entity Wrapping": [[3, "entity-wrapping"], [4, "entity-wrapping"]], "Function Decorators": [[3, "function-decorators"]], "Helpers": [[3, "helpers"]], "User Guide": [[4, "user-guide"]], "Installation": [[4, "installation"]], "Authentication": [[4, "authentication"]], "The From header": [[4, "the-from-header"]], "Using Non-US Service Regions": [[4, "using-non-us-service-regions"]], "Basic Usage Examples": [[4, "basic-usage-examples"]], "REST API v2": [[4, "rest-api-v2"]], "Events API v2": [[4, "events-api-v2"]], "Generic Client Features": [[4, "generic-client-features"]], "URLs": [[4, "urls"]], "Query Parameters": [[4, "query-parameters"]], "Requests and Responses": [[4, "requests-and-responses"]], "Data types": [[4, "data-types"]], "Resource schemas": [[4, "resource-schemas"]], "Wrapped-entity-aware Functions": [[4, "wrapped-entity-aware-functions"]], "Classic Patterns": [[4, "classic-patterns"]], "Special Cases": [[4, "special-cases"]], "Pagination": [[4, "pagination"]], "Performance and Completeness of Results": [[4, "performance-and-completeness-of-results"]], "Updating, creating or deleting while paginating": [[4, "updating-creating-or-deleting-while-paginating"]], "Multi-updating": [[4, "multi-updating"]], "Error Handling": [[4, "error-handling"]], "Logging": [[4, "logging"]], "Using a Proxy Server": [[4, "using-a-proxy-server"]], "HTTP Retry Configuration": [[4, "http-retry-configuration"]], "Exponential Cooldown": [[4, "exponential-cooldown"]], "Default Behavior": [[4, "default-behavior"]], "Setting the retry property": [[4, "setting-the-retry-property"]]}, "indexentries": {"apisession (class in pdpyras)": [[3, "pdpyras.APISession"]], "canonical_paths (in module pdpyras)": [[3, "pdpyras.CANONICAL_PATHS"]], "cursor_based_pagination_paths (in module pdpyras)": [[3, "pdpyras.CURSOR_BASED_PAGINATION_PATHS"]], "changeeventsapisession (class in pdpyras)": [[3, "pdpyras.ChangeEventsAPISession"]], "entity_wrapper_config (in module pdpyras)": [[3, "pdpyras.ENTITY_WRAPPER_CONFIG"]], "eventsapisession (class in pdpyras)": [[3, "pdpyras.EventsAPISession"]], "iteration_limit (in module pdpyras)": [[3, "pdpyras.ITERATION_LIMIT"]], "pdclienterror (class in pdpyras)": [[3, "pdpyras.PDClientError"]], "pdhttperror (class in pdpyras)": [[3, "pdpyras.PDHTTPError"]], "pdservererror (class in pdpyras)": [[3, "pdpyras.PDServerError"]], "pdsession (class in pdpyras)": [[3, "pdpyras.PDSession"]], "text_len_limit (in module pdpyras)": [[3, "pdpyras.TEXT_LEN_LIMIT"]], "timeout (in module pdpyras)": [[3, "pdpyras.TIMEOUT"]], "urlerror (class in pdpyras)": [[3, "pdpyras.URLError"]], "acknowledge() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.acknowledge"]], "after_set_api_key() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.after_set_api_key"]], "api_call_counts (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.api_call_counts"]], "api_key (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.api_key"]], "api_key_access (pdpyras.apisession property)": [[3, "pdpyras.APISession.api_key_access"]], "api_time (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.api_time"]], "auth_header (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.auth_header"]], "auth_type (pdpyras.apisession property)": [[3, "pdpyras.APISession.auth_type"]], "auto_json() (in module pdpyras)": [[3, "pdpyras.auto_json"]], "canonical_path() (in module pdpyras)": [[3, "pdpyras.canonical_path"]], "default_from (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.default_from"]], "default_page_size (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.default_page_size"]], "deprecated_kwarg() (in module pdpyras)": [[3, "pdpyras.deprecated_kwarg"]], "dict_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.dict_all"]], "endpoint_matches() (in module pdpyras)": [[3, "pdpyras.endpoint_matches"]], "entity_wrappers() (in module pdpyras)": [[3, "pdpyras.entity_wrappers"]], "find() (pdpyras.apisession method)": [[3, "pdpyras.APISession.find"]], "http_error_message() (in module pdpyras)": [[3, "pdpyras.http_error_message"]], "infer_entity_wrapper() (in module pdpyras)": [[3, "pdpyras.infer_entity_wrapper"]], "is_path_param() (in module pdpyras)": [[3, "pdpyras.is_path_param"]], "iter_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.iter_all"]], "iter_cursor() (pdpyras.apisession method)": [[3, "pdpyras.APISession.iter_cursor"]], "jget() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jget"]], "jpost() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jpost"]], "jput() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jput"]], "last_4() (in module pdpyras)": [[3, "pdpyras.last_4"]], "list_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.list_all"]], "log (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.log"]], "max_http_attempts (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.max_http_attempts"]], "max_network_attempts (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.max_network_attempts"]], "module": [[3, "module-0"], [3, "module-1"], [3, "module-2"], [3, "module-3"], [3, "module-pdpyras"]], "normalize_params() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.normalize_params"]], "normalize_url() (in module pdpyras)": [[3, "pdpyras.normalize_url"]], "normalize_url() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.normalize_url"]], "parent (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.parent"]], "pdpyras": [[3, "module-0"], [3, "module-1"], [3, "module-2"], [3, "module-3"], [3, "module-pdpyras"]], "permitted_methods (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.permitted_methods"]], "persist() (pdpyras.apisession method)": [[3, "pdpyras.APISession.persist"]], "plural_name() (in module pdpyras)": [[3, "pdpyras.plural_name"]], "post() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.post"]], "postprocess() (pdpyras.apisession method)": [[3, "pdpyras.APISession.postprocess"]], "postprocess() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.postprocess"]], "prepare_headers() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.prepare_headers"]], "prepare_headers() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.prepare_headers"]], "prepare_headers() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.prepare_headers"]], "print_debug (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.print_debug"]], "rdelete() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rdelete"]], "request() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.request"]], "requires_success() (in module pdpyras)": [[3, "pdpyras.requires_success"]], "resolve() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.resolve"]], "resource_url() (in module pdpyras)": [[3, "pdpyras.resource_url"]], "response (pdpyras.pdclienterror attribute)": [[3, "pdpyras.PDClientError.response"]], "retry (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.retry"]], "rget() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rget"]], "rpost() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rpost"]], "rput() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rput"]], "send_change_event() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.send_change_event"]], "send_event() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.send_event"]], "sleep_timer (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.sleep_timer"]], "sleep_timer_base (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.sleep_timer_base"]], "stagger_cooldown (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.stagger_cooldown"]], "subdomain (pdpyras.apisession property)": [[3, "pdpyras.APISession.subdomain"]], "submit() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.submit"]], "successful_response() (in module pdpyras)": [[3, "pdpyras.successful_response"]], "timeout (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.timeout"]], "total_call_count (pdpyras.apisession property)": [[3, "pdpyras.APISession.total_call_count"]], "total_call_time (pdpyras.apisession property)": [[3, "pdpyras.APISession.total_call_time"]], "trigger() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.trigger"]], "trunc_key (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.trunc_key"]], "trunc_token (pdpyras.apisession property)": [[3, "pdpyras.APISession.trunc_token"]], "truncate_text() (in module pdpyras)": [[3, "pdpyras.truncate_text"]], "try_decoding() (in module pdpyras)": [[3, "pdpyras.try_decoding"]], "unwrap() (in module pdpyras)": [[3, "pdpyras.unwrap"]], "url (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.url"]], "wrapped_entities() (in module pdpyras)": [[3, "pdpyras.wrapped_entities"]]}}) \ No newline at end of file +Search.setIndex({"docnames": ["changelog", "contributing", "index", "module_reference", "user_guide"], "filenames": ["changelog.rst", "contributing.rst", "index.rst", "module_reference.rst", "user_guide.rst"], "titles": ["Changelog", "Contribution Guide", "PDPYRAS: PagerDuty Python REST API Sessions", "Module Reference", "User Guide"], "terms": {"2023": [0, 4], "12": 0, "28": 0, "version": [0, 2, 3, 4], "5": [0, 1, 3, 4], "2": [0, 3, 4], "0": [0, 3, 4], "expand": 0, "us": [0, 1, 2, 3], "type": [0, 2, 3], "hint": 0, "place": [0, 4], "rtype": 0, "sphinx": [0, 1], "direct": 0, "remov": [0, 3], "unus": 0, "depend": [0, 1, 4], "deprec": [0, 3, 4], "fix": [0, 1, 3], "bug": [0, 1, 3], "path": [0, 1, 3, 4], "tag": [0, 2], "id": [0, 3, 4], "entity_typ": 0, "break": 0, "entiti": [0, 2], "wrap": [0, 2], "logic": [0, 3, 4], "issu": [0, 1, 3, 4], "130": 0, "11": 0, "15": 0, "1": [0, 1, 3, 4], "3": [0, 3, 4], "escap": 0, "sequenc": 0, "which": [0, 1, 3, 4], "were": 0, "caus": [0, 3, 4], "downstream": 0, "linter": 0, "unit": [0, 2], "test": [0, 2], "error": [0, 1, 2], "from": [0, 1, 2, 3], "docstr": 0, "refer": [0, 2, 4], "properti": [0, 2, 3], "modul": [0, 2, 4], "warn": [0, 3], "09": 0, "address": [0, 3, 4], "115": 0, "ad": [0, 1, 3, 4], "default": [0, 2], "valu": [0, 3, 4], "pdpyra": [0, 1, 3, 4], "pdsession": [0, 2, 3, 4], "retri": [0, 2, 3], "event": [0, 2, 3], "chang": [0, 2, 3, 4], "api": [0, 1], "client": [0, 2], "class": [0, 1, 2, 4], "upgrad": [0, 1], "ci": 0, "imag": [0, 3], "add": [0, 1, 3, 4], "support": [0, 3, 4], "python": [0, 1, 4], "07": [0, 4], "18": 0, "iter_al": [0, 3, 4], "an": [0, 1, 3, 4], "endpoint": [0, 3, 4], "cursor": [0, 3, 4], "base": [0, 3, 4], "pagin": [0, 2, 3], "should": [0, 1, 3, 4], "correctli": 0, "call": [0, 3, 4], "out": [0, 1, 4], "iter_cursor": [0, 3, 4], "wa": [0, 3, 4], "make": [0, 1, 3, 4], "keyword": [0, 3, 4], "argument": [0, 3, 4], "06": 0, "26": [0, 4], "new": [0, 2, 3, 4], "featur": [0, 1, 2, 3], "abil": 0, "specifi": [0, 3, 4], "timestamp": [0, 3], "when": [0, 1, 3, 4], "submit": [0, 3, 4], "suppli": [0, 3, 4], "changeeventsapisess": [0, 2, 3, 4], "explicitli": [0, 3], "includ": [0, 1, 3, 4], "upstream": 0, "except": [0, 3, 4], "rais": [0, 3, 4], "due": 0, "non": [0, 2, 3], "transient": [0, 3, 4], "network": [0, 3, 4], "function": [0, 1, 2], "tokenize_url_path": 0, "resource_envelop": 0, "object_typ": 0, "resource_nam": 0, "raise_on_error": 0, "__init__": 0, "all": [0, 1, 3, 4], "session": [0, 3, 4], "longer": [0, 1, 3, 4], "accept": [0, 3, 4], "name": [0, 1, 3, 4], "apisess": [0, 2, 3, 4], "attribut": [0, 3, 4], "object": [0, 3, 4], "method": [0, 3, 4], "profiler_kei": 0, "raise_if_http_error": 0, "4": [0, 3, 4], "user": [0, 1, 2, 3], "me": 0, "i": [0, 1, 3, 4], "also": [0, 1, 3, 4], "ambigu": 0, "match": [0, 3, 4], "canon": [0, 3], "solut": 0, "asmith": 0, "pd": 0, "short": [0, 3, 4], "circuit": [0, 3], "exact": [0, 3], "url": [0, 2], "05": 0, "17": 0, "incorpor": [0, 4], "bugfix": 0, "103": 0, "av1m": 0, "gener": [0, 2, 3], "behind": 0, "102": 0, "unsaf": 0, "mix": 0, "string": [0, 3, 4], "format": [0, 3], "style": 0, "In": [0, 3, 4], "http": [0, 2, 3], "exhaust": 0, "messag": [0, 1, 3, 4], "print": [0, 1, 3, 4], "onli": [0, 3, 4], "limit": [0, 3, 4], "got": 0, "reach": 0, "necessarili": 0, "per": [0, 3, 4], "statu": [0, 3, 4], "01": 0, "note": [0, 1, 3, 4], "ha": [0, 1, 3, 4], "been": [0, 3, 4], "yank": 0, "patch": [0, 1], "releas": [0, 2], "v5": [0, 3, 4], "setup": [0, 2], "py": [0, 1, 4], "assum": [0, 1, 3, 4], "like": [0, 4], "rget": [0, 3, 4], "now": 0, "print_debug": [0, 3, 4], "enabl": [0, 3, 4], "verbos": [0, 3], "log": [0, 2, 3], "sy": [0, 3, 4], "stderr": [0, 3, 4], "set_api_kei": 0, "end": [0, 2, 3, 4], "v3": 0, "life": 0, "follow": [0, 1, 3, 4], "next": [0, 1, 4], "minor": [0, 1], "them": [0, 1, 3, 4], "trigger": [0, 3, 4], "constructor": [0, 4], "thi": [0, 3, 4], "previous": 0, "set": [0, 1, 2, 3], "logger": [0, 3, 4], "effect": [0, 3, 4], "could": [0, 3], "fals": [0, 3, 4], "stop": 0, "iter": [0, 3, 4], "after": [0, 1, 3, 4], "first": [0, 1, 3, 4], "page": [0, 2, 3, 4], "result": [0, 2, 3], "wrapper": [0, 3, 4], "The": [0, 1, 2, 3], "determin": [0, 3], "automat": [0, 3, 4], "decor": [0, 2], "allow": [0, 3, 4], "partial": [0, 4], "return": [0, 3, 4], "case": [0, 1, 2, 3], "2022": 0, "10": [0, 3, 4], "13": 0, "request": [0, 1, 2, 3], "timeout": [0, 2, 3], "60": [0, 3], "api_key_access": [0, 3], "implement": [0, 3, 4], "formerli": 0, "parent": [0, 3, 4], "inherit": [0, 3], "did": 0, "need": [0, 1, 3, 4], "packag": [0, 1], "distribut": [0, 3], "build": [0, 1, 4], "02": 0, "22": 0, "yield": [0, 3, 4], "whenev": [0, 4], "pdhttperror": [0, 2, 3, 4], "strictli": [0, 3], "applic": [0, 3, 4], "level": [0, 3, 4], "e": [0, 1, 3, 4], "respons": [0, 2, 3], "v": [0, 1], "pdclienterror": [0, 2, 3, 4], "unnecessari": 0, "hold": [0, 3], "7": 0, "compat": [0, 4], "squar": [0, 3, 4], "bracket": [0, 3, 4], "queri": [0, 2, 3], "paramet": [0, 2, 3], "ar": [0, 1, 3, 4], "list": [0, 3, 4], "forget": 0, "do": [0, 4], "so": [0, 1, 3, 4], "requir": [0, 1, 3, 4], "filter": [0, 3, 4], "stagger_cooldown": [0, 3, 4], "appli": [0, 3, 4], "form": [0, 3], "retrial": 0, "updat": [0, 2, 3], "persist": [0, 3, 4], "ani": [0, 1, 3, 4], "exist": [0, 1, 3, 4], "resourc": [0, 3], "provid": [0, 3], "2021": 0, "configur": [0, 2, 3], "instanc": [0, 3, 4], "variabl": [0, 3, 4], "suggest": 0, "pull": [0, 1], "48": 0, "made": [0, 3, 4], "badnetmask": 0, "drop": 0, "improv": 0, "code": [0, 1, 3, 4], "sampl": 0, "jackton1": 0, "65": 0, "replac": [0, 3], "doubl": 0, "splat": 0, "oper": [0, 4], "ashwin153": 0, "68": 0, "work": [0, 3, 4], "around": [0, 3], "plai": 0, "61": 0, "04": [0, 4], "hunner": 0, "56": 0, "03": 0, "regress": 0, "eventsapisess": [0, 2, 3, 4], "post": [0, 3, 4], "defin": [0, 3, 4], "bodi": [0, 3, 4], "json": [0, 3, 4], "without": [0, 3, 4], "routing_kei": [0, 3, 4], "possibl": [0, 1], "befor": [0, 1, 3, 4], "x": [0, 4], "rout": 0, "kei": [0, 3, 4], "header": [0, 2, 3], "undocu": 0, "document": [0, 2, 3, 4], "v2": [0, 2, 3], "53": 0, "arg": [0, 3], "backward": 0, "second": [0, 3, 4], "can": [0, 1, 3, 4], "ctrlaltdel": 0, "2020": 0, "37": 0, "other": [0, 3, 4], "enhanc": 0, "10000": [0, 3], "encount": [0, 1, 3, 4], "versu": 0, "becaus": [0, 3, 4], "exceed": 0, "elicit": 0, "400": [0, 3, 4], "initi": [0, 2, 3, 4], "offset": [0, 3, 4], "via": [0, 3, 4], "param": [0, 3, 4], "alwai": [0, 1, 3, 4], "start": [0, 3, 4], "capit": [0, 3], "constant": 0, "instead": [0, 3, 4], "none": [0, 3, 4], "32": 0, "08": 0, "idempot": [0, 3, 4], "creator": 0, "dictionari": [0, 3, 4], "have": [0, 1, 3, 4], "self": [0, 3, 4], "oauth": [0, 3], "access": [0, 1, 3, 4], "token": [0, 1, 3, 4], "authent": [0, 2, 3], "23": 0, "indic": [0, 4], "scope": [0, 4], "given": [0, 3, 4], "credenti": [0, 1, 3, 4], "trunc_token": [0, 3], "typo": 0, "attributeerror": 0, "2019": 0, "31": 0, "size": 0, "basi": 0, "_all": 0, "pass": [0, 3, 4], "page_s": [0, 3], "If": [0, 1, 3, 4], "present": 0, "captur": 0, "easier": [0, 3], "identifi": [0, 3, 4], "commun": [0, 1], "pagerduti": [0, 3, 4], "extend": [0, 3], "metadata": [0, 3, 4], "cooldown": [0, 2, 3], "time": [0, 1, 3, 4], "between": [0, 3, 4], "rate": [0, 3, 4], "option": [0, 3], "random": [0, 3, 4], "posit": [0, 3, 4], "number": [0, 1, 3, 4], "departur": 0, "payload": [0, 3], "doe": [0, 1, 3, 4], "merg": [0, 2, 3], "rather": [0, 3], "complet": [0, 2, 3], "behavior": [0, 2, 3], "some": [0, 1, 3, 4], "intern": 0, "tool": [0, 1], "previou": [0, 3], "Not": 0, "intend": [0, 3], "design": [0, 3, 4], "At": [0, 4], "odd": 0, "introduct": 0, "custom": [0, 3, 4], "agent": [0, 3], "distinguish": 0, "purpos": [0, 3], "usag": [0, 2, 3], "analyt": 0, "import": [0, 1, 4], "keyerror": [0, 4], "incorrect": 0, "more": [0, 3, 4], "than": [0, 3, 4], "amount": [0, 3], "faulti": 0, "comparison": 0, "14": 0, "A": [0, 1, 3, 4], "light": 0, "refactor": 0, "specif": [0, 4], "send": [0, 3, 4], "send_ev": [0, 3], "catch": [0, 3, 4], "incid": [0, 3, 4], "still": [0, 3, 4], "most": [0, 1, 3, 4], "same": [0, 1, 3, 4], "rest": [0, 3], "unpack": 0, "log_entri": 0, "whitelist": 0, "r": [0, 1, 3, 4], "rescind": 0, "how": [0, 3, 4], "help": [0, 1, 3], "thei": [0, 3, 4], "don": 0, "t": [0, 3, 4], "envelop": 0, "auto": [0, 3], "valid": [0, 1, 3, 4], "presenc": [0, 4], "order": [0, 3], "busi": 0, "impact": 0, "metric": 0, "2018": 0, "list_al": [0, 3, 4], "dict_al": [0, 3, 4], "turn": 0, "index": [0, 1, 3, 4], "dict": [0, 3, 4], "save": [0, 4], "bit": 0, "effort": 0, "perform": [0, 2, 3], "multi": [0, 2], "action": [0, 3, 4], "manag": [0, 4], "rput": [0, 3, 4], "receiv": [0, 3, 4], "dure": [0, 3], "report": [1, 3], "welcom": 1, "built": 1, "recommend": [1, 3, 4], "assert": 1, "appropri": [1, 3, 4], "test_pdpyra": 1, "ensur": 1, "coverag": 1, "": [1, 3, 4], "pleas": [1, 3], "reproduc": 1, "along": 1, "themselv": 1, "github": [1, 2], "commit": 1, "To": [1, 3, 4], "abl": 1, "rebuild": 1, "sure": 1, "you": [1, 3], "pip": [1, 4], "your": [1, 4], "shell": 1, "environ": 1, "well": [1, 4], "local": [1, 4], "txt": 1, "root": [1, 3, 4], "repositori": [1, 2], "suit": 1, "rst": 1, "file": 1, "sourc": [1, 3, 4], "where": [1, 3, 4], "live": 1, "html": 1, "doc": [1, 3], "forc": 1, "touch": 1, "changelog": [1, 2], "account": [1, 3, 4], "both": [1, 3, 4], "pypi": [1, 2], "org": 1, "maintain": 1, "role": 1, "project": [1, 2], "see": [1, 3, 4], "abov": [1, 4], "It": [1, 3, 4], "strongli": 1, "upload": 1, "onc": [1, 3, 4], "even": 1, "delet": [1, 2, 3], "For": [1, 3, 4], "reason": 1, "good": 1, "idea": 1, "suffix": [1, 3], "dev001": 1, "__version__": 1, "while": [1, 2], "enter": 1, "prompt": 1, "testpublish": 1, "target": [1, 4], "egg": 1, "dist": 1, "librari": [1, 4], "temporari": [1, 3], "virtualenv": 1, "alreadi": [1, 3, 4], "script": 1, "immedi": [1, 3, 4], "exit": [1, 3], "investig": 1, "mitig": 1, "again": 1, "temporarili": 1, "count": [1, 3], "get": [1, 3, 4], "desir": [1, 4], "actual": [1, 3], "creat": [1, 2, 3], "least": 1, "item": [1, 3], "correspond": [1, 3, 4], "parenthes": 1, "handl": [1, 2], "contributor": 1, "slash": [1, 3, 4], "link": [1, 3], "preexist": [1, 3], "exampl": [1, 2, 3], "semant": 1, "rebuilt": 1, "view": 1, "open": [1, 4], "web": [1, 3, 4], "browser": 1, "review": 1, "approv": 1, "Then": 1, "checkout": 1, "main": [1, 4], "git": 1, "origin": [1, 4], "c": 1, "push": 1, "clone": 1, "branch": 1, "check": [1, 3], "latest": [1, 4], "avail": [1, 4], "tree": 1, "clean": 1, "uncommit": 1, "__token__": 1, "usernam": 1, "password": 1, "final": [1, 3, 4], "fill": 1, "detail": [1, 3, 4], "select": 1, "choos": 1, "being": [1, 3, 4], "major": 1, "veri": [1, 4], "brief": [1, 3], "summari": [1, 3, 4], "compos": [1, 3, 4], "descript": [1, 3], "whose": [1, 3, 4], "guid": [2, 3], "instal": 2, "u": 2, "servic": 2, "region": 2, "basic": 2, "data": [2, 3], "schema": [2, 3], "awar": [2, 3], "classic": [2, 3], "pattern": [2, 3], "special": [2, 3], "proxi": 2, "server": [2, 3], "exponenti": 2, "pdservererror": [2, 3], "urlerror": [2, 3], "canonical_path": [2, 3], "cursor_based_pagination_path": [2, 3], "entity_wrapper_config": [2, 3, 4], "iteration_limit": [2, 3], "text_len_limit": [2, 3], "helper": 2, "contribut": 2, "run": [2, 4], "publish": [2, 4], "cover": 3, "individu": [3, 4], "api_kei": [3, 4], "str": 3, "debug": [3, 4], "opinion": 3, "few": 3, "addit": [3, 4], "reattempt": 3, "increas": [3, 4], "interv": 3, "attempt": [3, 4], "through": [3, 4], "hoc": 3, "verb": 3, "doesn": [3, 4], "prepend": 3, "permitted_method": 3, "bool": 3, "true": [3, 4], "command": [3, 4], "line": [3, 4], "output": [3, 4], "after_set_api_kei": 3, "setter": 3, "hook": 3, "child": 3, "step": [3, 4], "getter": 3, "_api_kei": 3, "auth_head": 3, "By": [3, 4], "handler": [3, 4], "emit": 3, "max_http_attempt": [3, 4], "status": [3, 4], "greater": 3, "zero": 3, "max_network_attempt": [3, 4], "connect": 3, "treat": 3, "failur": 3, "happen": [3, 4], "normalize_param": 3, "modifi": [3, 4], "eas": 3, "current": 3, "append": [3, 4], "keep": [3, 4], "modif": 3, "normalize_url": 3, "whether": [3, 4], "super": 3, "tupl": 3, "permit": 3, "put": [3, 4], "postprocess": 3, "supplement": 3, "prepare_head": 3, "user_head": 3, "upper": 3, "overrid": [3, 4], "flag": 3, "notset": [3, 4], "thu": [3, 4], "toggl": 3, "disabl": [3, 4], "wai": [3, 4], "product": [3, 4], "kwarg": 3, "insensit": 3, "mai": [3, 4], "one": [3, 4], "each": [3, 4], "reflect": 3, "must": [3, 4], "separ": 3, "int": 3, "repres": [3, 4], "infinit": 3, "n": [3, 4], "up": [3, 4], "total": [3, 4], "whichev": 3, "mani": [3, 4], "success": [3, 4], "wait": [3, 4], "factor": [3, 4], "sleep_timer_bas": [3, 4], "429": [3, 4], "sleep_tim": [3, 4], "followup": 3, "delai": 3, "equal": 3, "power": 3, "far": 3, "unless": [3, 4], "nonzero": [3, 4], "sleep": [3, 4], "float": 3, "adjust": 3, "plu": [3, 4], "uniformli": 3, "top": 3, "timer": 3, "overal": 3, "wherea": 3, "just": 3, "avoid": [3, 4], "thunder": 3, "herd": 3, "potenti": 3, "simultan": 3, "concurr": 3, "consequ": 3, "consist": 3, "sent": [3, 4], "tcp": 3, "read": [3, 4], "trunc_kei": 3, "truncat": 3, "secur": 3, "displai": 3, "identif": 3, "default_from": [3, 4], "auth_typ": [3, 4], "oft": 3, "aspect": 3, "email": [3, 4], "oauth2": [3, 4], "bearer": 3, "member": 3, "api_call_count": 3, "record": [3, 4], "memoiz": 3, "Will": 3, "permiss": 3, "ui": 3, "global": 3, "administr": [3, 4], "api_tim": 3, "default_page_s": 3, "100": [3, 4], "kw": 3, "represent": [3, 4], "collect": [3, 4], "With": 3, "further": 3, "uniqu": [3, 4], "distinct": 3, "omit": 3, "find": [3, 4], "exactli": [3, 4], "otherwis": [3, 4], "expect": [3, 4], "ignor": 3, "take": [3, 4], "much": 3, "constrain": 3, "those": [3, 4], "everi": 3, "download": [3, 4], "compar": 3, "against": 3, "until": [3, 4], "found": [3, 4], "escalation_polici": [3, 4], "search": [3, 4], "item_hook": 3, "content": [3, 4], "pagint": 3, "k": [3, 4], "numer": [3, 4], "entri": [3, 4], "arrai": [3, 4], "alter": 3, "preced": [3, 4], "differ": [3, 4], "dictat": 3, "what": [3, 4], "callabl": 3, "invok": 3, "progress": 3, "three": [3, 4], "seri": 3, "isn": 3, "knowabl": 3, "third": 3, "leav": 3, "confer": 3, "small": 3, "advantag": 3, "comput": 3, "jget": [3, 4], "decod": [3, 4], "jpost": 3, "jput": 3, "directli": [3, 4], "attr": 3, "pair": [3, 4], "underli": [3, 4], "ap": 3, "contain": [3, 4], "inform": 3, "about": [3, 4], "rdelet": 3, "retriev": 3, "rpost": [3, 4], "subdomain": 3, "total_call_count": 3, "total_call_tim": 3, "spent": 3, "com": [3, 4], "acknowledg": [3, 4], "dedup_kei": [3, 4], "alert": [3, 4], "dedupl": [3, 4], "state": [3, 4], "resolv": [3, 4], "develop": 3, "associ": 3, "would": [3, 4], "sever": 3, "critic": 3, "custom_detail": 3, "wrong": 3, "human": 3, "readabl": 3, "system": [3, 4], "affect": [3, 4], "conjunct": 3, "regard": 3, "send_change_ev": 3, "iso8601": 3, "date": 3, "impli": 3, "sole": 3, "experienc": 3, "4xx": 3, "descend": [3, 4], "backend": 3, "successfulli": 3, "cleanli": 3, "guarante": 3, "its": [3, 4], "denot": [3, 4], "thing": 3, "wherein": 3, "recevi": 3, "try": [3, 4], "pabc123": [3, 4], "status_cod": [3, 4], "els": [3, 4], "write": [3, 4], "fail": 3, "earli": 3, "ga": 3, "5xx": [3, 4], "unsupport": 3, "malform": 3, "input": 3, "These": 3, "There": 3, "explicit": 3, "antipattern": 3, "convent": [3, 4], "infer": 3, "infer_entity_wrapp": 3, "therefor": [3, 4], "properli": 3, "space": 3, "either": [3, 4], "marshal": 3, "unmarsh": 3, "unwrap": [3, 4], "under": [3, 4], "said": [3, 4], "transmit": 3, "apart": 3, "secondari": 3, "bear": [3, 4], "discard": [3, 4], "prevent": 3, "maximum": [3, 4], "exce": 3, "enforc": 3, "side": 3, "someth": 3, "longest": 3, "length": 3, "own": 3, "typic": [3, 4], "benefit": 3, "anyon": 3, "who": 3, "relat": 3, "base_url": 3, "classifi": 3, "accord": [3, 4], "particular": [3, 4], "within": 3, "belong": 3, "part": [3, 4], "shown": 3, "contact_method": 3, "contact": 3, "normal": [3, 4], "full": [3, 4], "endpoint_match": 3, "endpoint_pattern": 3, "uppercas": 3, "is_path_param": 3, "path_nod": 3, "node": [3, 4], "arbitrari": 3, "rel": [3, 4], "baseurl": 3, "exclud": 3, "trail": 3, "entity_wrapp": 3, "obtain": [3, 4], "element": 3, "signal": 3, "unmodifi": 3, "orthodox": 3, "broadli": 3, "univers": 3, "predict": 3, "union": 3, "map": 3, "subclass": [3, 4], "auto_json": 3, "requires_success": 3, "resource_url": 3, "itself": [3, 4], "elimin": 3, "re": 3, "construct": [3, 4], "wrapped_ent": 3, "encod": [3, 4], "reform": 3, "miscellan": 3, "deprecated_kwarg": 3, "deprecated_nam": 3, "http_error_messag": 3, "context": [3, 4], "describ": 3, "last_4": 3, "secret": [3, 4], "sensit": 3, "last": [3, 4], "charact": 3, "text": 3, "plural_nam": 3, "obj_typ": 3, "plural": [3, 4], "user_refer": [3, 4], "successful_respons": 3, "truncate_text": 3, "try_decod": 3, "topic": 4, "depth": 4, "altern": 4, "directori": 4, "session_oauth": 4, "oauth_token": 4, "events_sess": 4, "change_events_sess": 4, "do_appl": 4, "integr": 4, "menu": 4, "tab": 4, "profil": 4, "deriv": 4, "necessari": 4, "eu": 4, "outsid": 4, "ok": 4, "convert": 4, "sn": 4, "look": 4, "jane": 4, "example35": 4, "updated_us": 4, "user_data": 4, "user123": 4, "mcuserson": 4, "ordinarili": 4, "prior": 4, "paramt": 4, "assign": 4, "user_id": 4, "phij789": 4, "5b": 4, "5d": 4, "updated_incid": 4, "fire": 4, "dusti": 4, "old": 4, "net": 4, "abc123": 4, "finish": 4, "head": 4, "autom": 4, "sinc": 4, "similar": 4, "analog": 4, "j": 4, "though": 4, "howev": 4, "lead": 4, "One": 4, "strip": 4, "As": 4, "everyth": 4, "simpli": 4, "serial": 4, "first_dan": 4, "dan": 4, "v4": 4, "82": 4, "foo": 4, "foo_servic": 4, "team": 4, "50": 4, "plain": 4, "That": 4, "uuid": 4, "encapsul": 4, "insid": 4, "articl": 4, "analogu": 4, "structur": 4, "speak": 4, "consid": 4, "escal": 4, "polici": 4, "ep": 4, "escalation_rul": 4, "daili": 4, "engin": 4, "rotat": 4, "rule": 4, "new_rul": 4, "escalation_delay_in_minut": 4, "30": 4, "pam4fg": 4, "pi7dh85": 4, "schedule_refer": 4, "respect": 4, "respond": 4, "anoth": 4, "singl": 4, "extract": 4, "singular": 4, "noun": 4, "On": 4, "equival": 4, "decid": 4, "store": 4, "point": 4, "control": 4, "business_servic": 4, "subscrib": 4, "subscript": 4, "unusu": 4, "vice": 4, "versa": 4, "schedul": 4, "incient": 4, "status_upd": 4, "created_overrid": 4, "pghi789": 4, "01t00": 4, "00": 4, "02t00": 4, "peysgva": 4, "time_zon": 4, "utc": 4, "03t00": 4, "peysgvf": 4, "201": 4, "fetch": 4, "dav": 4, "dave": 4, "david": 4, "bob": 4, "synchron": 4, "multipl": 4, "thread": 4, "higher": 4, "moreov": 4, "larg": 4, "volum": 4, "wise": 4, "erron": 4, "condit": 4, "sort": 4, "real": 4, "recalcul": 4, "skip": 4, "repeat": 4, "accordingli": 4, "process": 4, "manual": 4, "edit": 4, "elabor": 4, "let": 4, "sai": 4, "notebook": 4, "essenti": 4, "go": 4, "101st": 4, "201st": 4, "etc": 4, "tear": 4, "shift": 4, "becom": 4, "hundr": 4, "over": 4, "similarli": 4, "401": 4, "500": 4, "601": 4, "700": 4, "attach": 4, "opposit": 4, "bump": 4, "group": 4, "prioriti": 4, "yet": 4, "two": 4, "pdef456": 4, "incident_refer": 4, "effici": 4, "login": 4, "differenti": 4, "pertain": 4, "404": 4, "pjkl678": 4, "introduc": 4, "Its": 4, "unconfigur": 4, "defer": 4, "left": 4, "discret": 4, "later": 4, "streamhandl": 4, "host": 4, "traffic": 4, "42": 4, "187": 4, "port": 4, "4012": 4, "protocol": 4, "unsuccess": 4, "loop": 4, "period": 4, "\u03c1": 4, "indefinit": 4, "cannot": 4, "overridden": 4, "sane": 4, "approach": 4, "ever": 4, "too": 4, "natur": 4, "rogu": 4, "satur": 4, "unauthor": 4, "invalid": 4, "prefer": 4, "hang": 4, "continu": 4, "502": 4, "toler": 4, "supersed": 4, "lower": 4, "carri": 4, "four": 4, "8": 4, "16": 4, "paus": 4, "won": 4, "pnoexst": 4, "62": 4, "6": 4}, "objects": {"": [[3, 0, 0, "module-3", "pdpyras"]], "pdpyras": [[3, 1, 1, "", "APISession"], [3, 5, 1, "", "CANONICAL_PATHS"], [3, 5, 1, "", "CURSOR_BASED_PAGINATION_PATHS"], [3, 1, 1, "", "ChangeEventsAPISession"], [3, 5, 1, "", "ENTITY_WRAPPER_CONFIG"], [3, 1, 1, "", "EventsAPISession"], [3, 5, 1, "", "ITERATION_LIMIT"], [3, 1, 1, "", "PDClientError"], [3, 1, 1, "", "PDHTTPError"], [3, 1, 1, "", "PDServerError"], [3, 1, 1, "", "PDSession"], [3, 5, 1, "", "TEXT_LEN_LIMIT"], [3, 5, 1, "", "TIMEOUT"], [3, 1, 1, "", "URLError"], [3, 6, 1, "", "auto_json"], [3, 6, 1, "", "canonical_path"], [3, 6, 1, "", "deprecated_kwarg"], [3, 6, 1, "", "endpoint_matches"], [3, 6, 1, "", "entity_wrappers"], [3, 6, 1, "", "http_error_message"], [3, 6, 1, "", "infer_entity_wrapper"], [3, 6, 1, "", "is_path_param"], [3, 6, 1, "", "last_4"], [3, 6, 1, "", "normalize_url"], [3, 6, 1, "", "plural_name"], [3, 6, 1, "", "requires_success"], [3, 6, 1, "", "resource_url"], [3, 6, 1, "", "successful_response"], [3, 6, 1, "", "truncate_text"], [3, 6, 1, "", "try_decoding"], [3, 6, 1, "", "unwrap"], [3, 6, 1, "", "wrapped_entities"]], "pdpyras.APISession": [[3, 2, 1, "", "api_call_counts"], [3, 3, 1, "", "api_key_access"], [3, 2, 1, "", "api_time"], [3, 3, 1, "", "auth_type"], [3, 2, 1, "", "default_from"], [3, 2, 1, "", "default_page_size"], [3, 4, 1, "", "dict_all"], [3, 4, 1, "", "find"], [3, 4, 1, "", "iter_all"], [3, 4, 1, "", "iter_cursor"], [3, 4, 1, "", "jget"], [3, 4, 1, "", "jpost"], [3, 4, 1, "", "jput"], [3, 4, 1, "", "list_all"], [3, 4, 1, "", "persist"], [3, 4, 1, "", "postprocess"], [3, 4, 1, "", "rdelete"], [3, 4, 1, "", "rget"], [3, 4, 1, "", "rpost"], [3, 4, 1, "", "rput"], [3, 3, 1, "", "subdomain"], [3, 3, 1, "", "total_call_count"], [3, 3, 1, "", "total_call_time"], [3, 3, 1, "", "trunc_token"], [3, 2, 1, "", "url"]], "pdpyras.ChangeEventsAPISession": [[3, 4, 1, "", "prepare_headers"], [3, 4, 1, "", "send_change_event"], [3, 4, 1, "", "submit"]], "pdpyras.EventsAPISession": [[3, 4, 1, "", "acknowledge"], [3, 4, 1, "", "post"], [3, 4, 1, "", "prepare_headers"], [3, 4, 1, "", "resolve"], [3, 4, 1, "", "send_event"], [3, 4, 1, "", "trigger"]], "pdpyras.PDClientError": [[3, 2, 1, "", "response"]], "pdpyras.PDSession": [[3, 4, 1, "", "after_set_api_key"], [3, 3, 1, "", "api_key"], [3, 3, 1, "", "auth_header"], [3, 2, 1, "", "log"], [3, 2, 1, "", "max_http_attempts"], [3, 2, 1, "", "max_network_attempts"], [3, 4, 1, "", "normalize_params"], [3, 4, 1, "", "normalize_url"], [3, 2, 1, "", "parent"], [3, 2, 1, "", "permitted_methods"], [3, 4, 1, "", "postprocess"], [3, 4, 1, "", "prepare_headers"], [3, 3, 1, "", "print_debug"], [3, 4, 1, "", "request"], [3, 2, 1, "", "retry"], [3, 2, 1, "", "sleep_timer"], [3, 2, 1, "", "sleep_timer_base"], [3, 3, 1, "", "stagger_cooldown"], [3, 2, 1, "", "timeout"], [3, 3, 1, "", "trunc_key"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute", "3": "py:property", "4": "py:method", "5": "py:data", "6": "py:function"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "method", "Python method"], "5": ["py", "data", "Python data"], "6": ["py", "function", "Python function"]}, "titleterms": {"changelog": 0, "contribut": 1, "guid": [1, 4], "initi": 1, "setup": 1, "run": 1, "unit": 1, "test": 1, "updat": [1, 4], "document": 1, "releas": 1, "new": 1, "version": 1, "perform": [1, 4], "end": 1, "publish": 1, "instal": [1, 4], "merg": 1, "chang": 1, "tag": 1, "pdpyra": 2, "pagerduti": 2, "python": 2, "rest": [2, 4], "api": [2, 3, 4], "session": 2, "extern": 2, "resourc": [2, 4], "tabl": 2, "content": 2, "modul": 3, "refer": 3, "client": [3, 4], "class": 3, "error": [3, 4], "default": [3, 4], "function": [3, 4], "url": [3, 4], "handl": [3, 4], "entiti": [3, 4], "wrap": [3, 4], "decor": 3, "helper": 3, "user": 4, "authent": 4, "The": 4, "from": 4, "header": 4, "us": 4, "non": 4, "u": 4, "servic": 4, "region": 4, "basic": 4, "usag": 4, "exampl": 4, "v2": 4, "event": 4, "gener": 4, "featur": 4, "queri": 4, "paramet": 4, "request": 4, "respons": 4, "data": 4, "type": 4, "schema": 4, "awar": 4, "classic": 4, "pattern": 4, "special": 4, "case": 4, "pagin": 4, "complet": 4, "result": 4, "creat": 4, "delet": 4, "while": 4, "multi": 4, "log": 4, "proxi": 4, "server": 4, "http": 4, "retri": 4, "configur": 4, "exponenti": 4, "cooldown": 4, "behavior": 4, "set": 4, "properti": 4}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "sphinx": 57}, "alltitles": {"Contribution Guide": [[1, "contribution-guide"]], "Initial Setup": [[1, "initial-setup"]], "Running Unit Tests": [[1, "running-unit-tests"]], "Updating Documentation": [[1, "updating-documentation"]], "Releasing a New Version": [[1, "releasing-a-new-version"]], "Perform end-to-end publish and installation testing": [[1, "perform-end-to-end-publish-and-installation-testing"]], "Merge changes and tag": [[1, "merge-changes-and-tag"]], "Publishing": [[1, "publishing"]], "PDPYRAS: PagerDuty Python REST API Sessions": [[2, "pdpyras-pagerduty-python-rest-api-sessions"]], "External Resources": [[2, "external-resources"]], "Table of Contents": [[2, "table-of-contents"]], "User Guide": [[4, "user-guide"]], "Installation": [[4, "installation"]], "Authentication": [[4, "authentication"]], "The From header": [[4, "the-from-header"]], "Using Non-US Service Regions": [[4, "using-non-us-service-regions"]], "Basic Usage Examples": [[4, "basic-usage-examples"]], "REST API v2": [[4, "rest-api-v2"]], "Events API v2": [[4, "events-api-v2"]], "Generic Client Features": [[4, "generic-client-features"]], "URLs": [[4, "urls"]], "Query Parameters": [[4, "query-parameters"]], "Requests and Responses": [[4, "requests-and-responses"]], "Data types": [[4, "data-types"]], "Resource schemas": [[4, "resource-schemas"]], "Entity Wrapping": [[4, "entity-wrapping"], [3, "entity-wrapping"]], "Wrapped-entity-aware Functions": [[4, "wrapped-entity-aware-functions"]], "Classic Patterns": [[4, "classic-patterns"]], "Special Cases": [[4, "special-cases"]], "Pagination": [[4, "pagination"]], "Performance and Completeness of Results": [[4, "performance-and-completeness-of-results"]], "Updating, creating or deleting while paginating": [[4, "updating-creating-or-deleting-while-paginating"]], "Multi-updating": [[4, "multi-updating"]], "Error Handling": [[4, "error-handling"]], "Logging": [[4, "logging"]], "Using a Proxy Server": [[4, "using-a-proxy-server"]], "HTTP Retry Configuration": [[4, "http-retry-configuration"]], "Exponential Cooldown": [[4, "exponential-cooldown"]], "Default Behavior": [[4, "default-behavior"]], "Setting the retry property": [[4, "setting-the-retry-property"]], "Module Reference": [[3, "module-reference"]], "API Client Classes": [[3, "api-client-classes"]], "Errors": [[3, "errors"]], "Client Defaults": [[3, "client-defaults"]], "Functions": [[3, "functions"]], "URL Handling": [[3, "url-handling"]], "Function Decorators": [[3, "function-decorators"]], "Helpers": [[3, "helpers"]], "Changelog": [[0, "changelog"]]}, "indexentries": {"apisession (class in pdpyras)": [[3, "pdpyras.APISession"]], "canonical_paths (in module pdpyras)": [[3, "pdpyras.CANONICAL_PATHS"]], "cursor_based_pagination_paths (in module pdpyras)": [[3, "pdpyras.CURSOR_BASED_PAGINATION_PATHS"]], "changeeventsapisession (class in pdpyras)": [[3, "pdpyras.ChangeEventsAPISession"]], "entity_wrapper_config (in module pdpyras)": [[3, "pdpyras.ENTITY_WRAPPER_CONFIG"]], "eventsapisession (class in pdpyras)": [[3, "pdpyras.EventsAPISession"]], "iteration_limit (in module pdpyras)": [[3, "pdpyras.ITERATION_LIMIT"]], "pdclienterror (class in pdpyras)": [[3, "pdpyras.PDClientError"]], "pdhttperror (class in pdpyras)": [[3, "pdpyras.PDHTTPError"]], "pdservererror (class in pdpyras)": [[3, "pdpyras.PDServerError"]], "pdsession (class in pdpyras)": [[3, "pdpyras.PDSession"]], "text_len_limit (in module pdpyras)": [[3, "pdpyras.TEXT_LEN_LIMIT"]], "timeout (in module pdpyras)": [[3, "pdpyras.TIMEOUT"]], "urlerror (class in pdpyras)": [[3, "pdpyras.URLError"]], "acknowledge() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.acknowledge"]], "after_set_api_key() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.after_set_api_key"]], "api_call_counts (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.api_call_counts"]], "api_key (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.api_key"]], "api_key_access (pdpyras.apisession property)": [[3, "pdpyras.APISession.api_key_access"]], "api_time (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.api_time"]], "auth_header (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.auth_header"]], "auth_type (pdpyras.apisession property)": [[3, "pdpyras.APISession.auth_type"]], "auto_json() (in module pdpyras)": [[3, "pdpyras.auto_json"]], "canonical_path() (in module pdpyras)": [[3, "pdpyras.canonical_path"]], "default_from (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.default_from"]], "default_page_size (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.default_page_size"]], "deprecated_kwarg() (in module pdpyras)": [[3, "pdpyras.deprecated_kwarg"]], "dict_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.dict_all"]], "endpoint_matches() (in module pdpyras)": [[3, "pdpyras.endpoint_matches"]], "entity_wrappers() (in module pdpyras)": [[3, "pdpyras.entity_wrappers"]], "find() (pdpyras.apisession method)": [[3, "pdpyras.APISession.find"]], "http_error_message() (in module pdpyras)": [[3, "pdpyras.http_error_message"]], "infer_entity_wrapper() (in module pdpyras)": [[3, "pdpyras.infer_entity_wrapper"]], "is_path_param() (in module pdpyras)": [[3, "pdpyras.is_path_param"]], "iter_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.iter_all"]], "iter_cursor() (pdpyras.apisession method)": [[3, "pdpyras.APISession.iter_cursor"]], "jget() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jget"]], "jpost() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jpost"]], "jput() (pdpyras.apisession method)": [[3, "pdpyras.APISession.jput"]], "last_4() (in module pdpyras)": [[3, "pdpyras.last_4"]], "list_all() (pdpyras.apisession method)": [[3, "pdpyras.APISession.list_all"]], "log (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.log"]], "max_http_attempts (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.max_http_attempts"]], "max_network_attempts (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.max_network_attempts"]], "module": [[3, "module-0"], [3, "module-1"], [3, "module-2"], [3, "module-3"], [3, "module-pdpyras"]], "normalize_params() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.normalize_params"]], "normalize_url() (in module pdpyras)": [[3, "pdpyras.normalize_url"]], "normalize_url() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.normalize_url"]], "parent (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.parent"]], "pdpyras": [[3, "module-0"], [3, "module-1"], [3, "module-2"], [3, "module-3"], [3, "module-pdpyras"]], "permitted_methods (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.permitted_methods"]], "persist() (pdpyras.apisession method)": [[3, "pdpyras.APISession.persist"]], "plural_name() (in module pdpyras)": [[3, "pdpyras.plural_name"]], "post() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.post"]], "postprocess() (pdpyras.apisession method)": [[3, "pdpyras.APISession.postprocess"]], "postprocess() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.postprocess"]], "prepare_headers() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.prepare_headers"]], "prepare_headers() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.prepare_headers"]], "prepare_headers() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.prepare_headers"]], "print_debug (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.print_debug"]], "rdelete() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rdelete"]], "request() (pdpyras.pdsession method)": [[3, "pdpyras.PDSession.request"]], "requires_success() (in module pdpyras)": [[3, "pdpyras.requires_success"]], "resolve() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.resolve"]], "resource_url() (in module pdpyras)": [[3, "pdpyras.resource_url"]], "response (pdpyras.pdclienterror attribute)": [[3, "pdpyras.PDClientError.response"]], "retry (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.retry"]], "rget() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rget"]], "rpost() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rpost"]], "rput() (pdpyras.apisession method)": [[3, "pdpyras.APISession.rput"]], "send_change_event() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.send_change_event"]], "send_event() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.send_event"]], "sleep_timer (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.sleep_timer"]], "sleep_timer_base (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.sleep_timer_base"]], "stagger_cooldown (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.stagger_cooldown"]], "subdomain (pdpyras.apisession property)": [[3, "pdpyras.APISession.subdomain"]], "submit() (pdpyras.changeeventsapisession method)": [[3, "pdpyras.ChangeEventsAPISession.submit"]], "successful_response() (in module pdpyras)": [[3, "pdpyras.successful_response"]], "timeout (pdpyras.pdsession attribute)": [[3, "pdpyras.PDSession.timeout"]], "total_call_count (pdpyras.apisession property)": [[3, "pdpyras.APISession.total_call_count"]], "total_call_time (pdpyras.apisession property)": [[3, "pdpyras.APISession.total_call_time"]], "trigger() (pdpyras.eventsapisession method)": [[3, "pdpyras.EventsAPISession.trigger"]], "trunc_key (pdpyras.pdsession property)": [[3, "pdpyras.PDSession.trunc_key"]], "trunc_token (pdpyras.apisession property)": [[3, "pdpyras.APISession.trunc_token"]], "truncate_text() (in module pdpyras)": [[3, "pdpyras.truncate_text"]], "try_decoding() (in module pdpyras)": [[3, "pdpyras.try_decoding"]], "unwrap() (in module pdpyras)": [[3, "pdpyras.unwrap"]], "url (pdpyras.apisession attribute)": [[3, "pdpyras.APISession.url"]], "wrapped_entities() (in module pdpyras)": [[3, "pdpyras.wrapped_entities"]]}}) \ No newline at end of file diff --git a/docs/user_guide.html b/docs/user_guide.html index da6b45e..f1eaa9c 100644 --- a/docs/user_guide.html +++ b/docs/user_guide.html @@ -6,7 +6,7 @@ - User Guide — PagerDuty Python REST API Sessions 5.1.3 documentation + User Guide — PagerDuty Python REST API Sessions 5.2.0 documentation diff --git a/pdpyras.py b/pdpyras.py index 25121e0..cf9a467 100644 --- a/pdpyras.py +++ b/pdpyras.py @@ -9,14 +9,18 @@ from copy import deepcopy from datetime import datetime from random import random +from typing import Iterator, Union from warnings import warn -# Libraries from PyPI -import requests +# Upstream components on which this client is based: +from requests import Response, Session +from requests import __version__ as REQUESTS_VERSION + +# HTTP client exceptions: from urllib3.exceptions import HTTPError, PoolError from requests.exceptions import RequestException -__version__ = '5.1.3' +__version__ = '5.2.0' ####################### ### CLIENT DEFAULTS ### @@ -195,7 +199,9 @@ '/status_dashboards/url_slugs/{url_slug}/service_impacts', '/tags', '/tags/{id}', - '/tags/{id}/{entity_type}', + '/tags/{id}/users', + '/tags/{id}/teams', + '/tags/{id}/escalation_policies', '/teams', '/teams/{id}', '/teams/{id}/audit/records', @@ -383,9 +389,9 @@ ### URL HANDLING ### #################### -def canonical_path(base_url: str, url: str): +def canonical_path(base_url: str, url: str) -> str: """ - Returns the canonical REST API path corresponding to a URL. + The canonical path from the API documentation corresponding to a URL This is used to identify and classify URLs according to which particular API within REST API v2 it belongs to. @@ -398,12 +404,13 @@ def canonical_path(base_url: str, url: str): :param base_url: The base URL of the API :param url: A non-normalized URL (a path or full URL) - :rtype: str + :returns: + The canonical REST API v2 path corresponding to a URL. """ full_url = normalize_url(base_url, url) - # Starting with / after hostname up until the parameters: + # Starting with / after hostname before the query string: url_path = full_url.replace(base_url.rstrip('/'), '').split('?')[0] - # Root node (blank) counts so we include it + # Root node (blank) counts so we include it: n_nodes = url_path.count('/') # First winnow the list down to paths with the same number of nodes: patterns = list(filter( @@ -435,9 +442,9 @@ def canonical_path(base_url: str, url: str): else: return patterns[0] -def endpoint_matches(endpoint_pattern: str, method: str, path: str): +def endpoint_matches(endpoint_pattern: str, method: str, path: str) -> bool: """ - Returns true if a method and path match an endpoint pattern. + Whether an endpoint (method and canonical path) matches a given pattern This is the filtering logic used for finding the appropriate entry in :attr:`ENTITY_WRAPPER_CONFIG` to use for a given method and API path. @@ -450,23 +457,25 @@ def endpoint_matches(endpoint_pattern: str, method: str, path: str): The HTTP method. :param path: The canonical API path (i.e. as returned by :func:`canonical_path`) - :rtype: boolean + :returns: + True or False based on whether the pattern matches the endpoint """ return ( endpoint_pattern.startswith(method.upper()) \ or endpoint_pattern.startswith('*') ) and endpoint_pattern.endswith(f" {path}") -def is_path_param(path_node: str): +def is_path_param(path_node: str) -> bool: """ - Returns true if a given node in a canonical path represents a parameter. + Whether a part of a canonical path represents a variable parameter :param path_node: The node (value between slashes) in the path - :rtype: bool + :returns: + True if the node is an arbitrary variable, False if it is a fixed value """ return path_node.startswith('{') and path_node.endswith('}') -def normalize_url(base_url: str, url: str): +def normalize_url(base_url: str, url: str) -> str: """ Normalize a URL to a complete API URL. @@ -477,7 +486,6 @@ def normalize_url(base_url: str, url: str): The base API URL, excluding any trailing slash, i.e. "https://api.pagerduty.com" :returns: The full API endpoint URL - :rtype: str """ if url.startswith(base_url): return url @@ -492,19 +500,18 @@ def normalize_url(base_url: str, url: str): ### ENTITY WRAPPING ### ####################### -def entity_wrappers(method: str, path: str): +def entity_wrappers(method: str, path: str) -> tuple: """ Obtains entity wrapping information for a given endpoint (path and method) - Returns a 2-tuple. The first element is the wrapper name that should be used - for the request body, and the second is the wrapper name to be used for the - response body. For either elements, if ``None`` is returned, that signals to - disable wrapping and pass the user-supplied request body or API response - body object unmodified. - :param method: The HTTP method :param path: A canonical API path i.e. as returned by ``canonical_path`` - :rtype: tuple + :returns: + A 2-tuple. The first element is the wrapper name that should be used for + the request body, and the second is the wrapper name to be used for the + response body. For either elements, if ``None`` is returned, that + signals to disable wrapping and pass the user-supplied request body or + API response body object unmodified. """ m = method.upper() endpoint = "%s %s"%(m, path) @@ -544,7 +551,7 @@ def entity_wrappers(method: str, path: str): raise Exception(f"{endpoint} matches more than one pattern:" + \ f"{matches_str}; this is most likely a bug in pdpyras.") -def infer_entity_wrapper(method: str, path: str): +def infer_entity_wrapper(method: str, path: str) -> str: """ Infer the entity wrapper name from the endpoint using orthodox patterns. @@ -556,7 +563,6 @@ def infer_entity_wrapper(method: str, path: str): :param method: The HTTP method :param path: A canonical API path i.e. as returned by ``canonical_path`` - :rtype: str """ m = method.upper() path_nodes = path.split('/') @@ -573,13 +579,16 @@ def infer_entity_wrapper(method: str, path: str): # Plural if listing via GET to the index endpoint, or doing a multi-put: return path_nodes[-1] -def unwrap(response: requests.Response, wrapper): +def unwrap(response: Response, wrapper) -> Union[dict, list]: """ - Unwraps and returns a wrapped entity. + Unwraps a wrapped entity. :param response: The response object :param wrapper: The entity wrapper :type wrapper: str or None + :returns: + The value associated with the wrapper key in the JSON-decoded body of + the response, which is expected to be a dictionary (map). """ body = try_decoding(response) endpoint = "%s %s"%(response.request.method.upper(), response.request.url) @@ -722,7 +731,7 @@ def deprecated_kwarg(deprecated_name: str, details=None): details_msg = f" {details}" warn(f"Keyword argument \"{deprecated_name}\" is deprecated.{details_msg}") -def http_error_message(r: requests.Response, context=None): +def http_error_message(r: Response, context=None) -> str: """ Formats a message describing a HTTP error. @@ -730,6 +739,8 @@ def http_error_message(r: requests.Response, context=None): The response object. :param context: A description of when the error was received, or None to not include it + :returns: + The message to include in the HTTP error """ received_http_response = bool(r.status_code) endpoint = "%s %s"%(r.request.method.upper(), r.request.url) @@ -751,19 +762,25 @@ def http_error_message(r: requests.Response, context=None): return f"{endpoint}: Success (status {r.status_code}) but an " \ f"expectation still failed{context_msg}" -def last_4(secret: str): - """Returns an abbreviation of the input""" +def last_4(secret: str) -> str: + """ + Truncate a sensitive value to its last 4 characters + + :param secret: text to truncate + :returns: + The truncated text + """ return '*'+str(secret)[-4:] -def plural_name(obj_type: str): +def plural_name(obj_type: str) -> str: """ Pluralizes a name, i.e. the API name from the ``type`` property :param obj_type: The object type, i.e. ``user`` or ``user_reference`` - :returns: The name of the resource, i.e. the last part of the URL for the + :returns: + The name of the resource, i.e. the last part of the URL for the resource's index URL - :rtype: str """ if obj_type.endswith('_reference'): # Strip down to basic type if it's a reference @@ -774,7 +791,7 @@ def plural_name(obj_type: str): else: return obj_type+'s' -def singular_name(r_name: str): +def singular_name(r_name: str) -> str: """ Singularizes a name, i.e. for the entity wrapper in a POST request @@ -783,7 +800,8 @@ def singular_name(r_name: str): forms the part of the canonical path identifying what kind of resource lives in the collection there, for an API that follows classic wrapped entity naming patterns. - :rtype: str + :returns: + The singularized name """ if r_name.endswith('ies'): # Because English @@ -791,8 +809,7 @@ def singular_name(r_name: str): else: return r_name.rstrip('s') -def successful_response(r: requests.Response, context=None) \ - -> requests.Response: +def successful_response(r: Response, context=None) -> Response: """Validates the response as successful. Returns the response if it was successful; otherwise, raises an exception. @@ -801,7 +818,8 @@ def successful_response(r: requests.Response, context=None) \ Response object corresponding to the response received. :param context: A description of when the HTTP request is happening, for error reporting - :returns: The response object, if it was successful + :returns: + The response object, if it was successful """ if r.ok and bool(r.status_code): return r @@ -812,7 +830,7 @@ def successful_response(r: requests.Response, context=None) \ else: raise PDClientError(http_error_message(r, context=context)) -def truncate_text(text: str): +def truncate_text(text: str) -> str: """Truncates a string longer than :attr:`TEXT_LEN_LIMIT` :param text: The string to truncate if longer than the limit. @@ -822,7 +840,7 @@ def truncate_text(text: str): else: return text -def try_decoding(r: requests.Response): +def try_decoding(r: Response) -> Union[dict, list, str]: """ JSON-decode a response body @@ -844,7 +862,7 @@ def try_decoding(r: requests.Response): ### CLASSES ### ############### -class PDSession(requests.Session): +class PDSession(Session): """ Base class for making HTTP requests to PagerDuty APIs @@ -970,7 +988,7 @@ def after_set_api_key(self): pass @property - def api_key(self): + def api_key(self) -> str: """ API Key property getter. @@ -987,18 +1005,18 @@ def api_key(self, api_key): self.after_set_api_key() @property - def auth_header(self): + def auth_header(self) -> dict: """ Generates the header with the API credential used for authentication. """ raise NotImplementedError - def cooldown_factor(self): + def cooldown_factor(self) -> float: return self.sleep_timer_base*(1+self.stagger_cooldown*random()) - def normalize_params(self, params): + def normalize_params(self, params) -> dict: """ - Modify the user-supplied parameters. + Modify the user-supplied parameters to ease implementation Current behavior: @@ -1006,6 +1024,9 @@ def normalize_params(self, params): not already end in "[]", then the square brackets are appended to keep in line with the requirement that all set filters' parameter names end in "[]". + + :returns: + The query parameters after modification """ updated_params = {} for param, value in params.items(): @@ -1015,7 +1036,7 @@ def normalize_params(self, params): updated_params[param] = value return updated_params - def normalize_url(self, url): + def normalize_url(self, url) -> str: """Compose the URL whether it is a path or an already-complete URL""" return normalize_url(self.url, url) @@ -1028,7 +1049,7 @@ def postprocess(self, response): """ pass - def prepare_headers(self, method, user_headers={}): + def prepare_headers(self, method, user_headers={}) -> dict: """ Append special additional per-request headers. @@ -1036,6 +1057,8 @@ def prepare_headers(self, method, user_headers={}): The HTTP method, in upper case. :param user_headers: Headers that can be specified to override default values. + :returns: + The final list of headers to use in the request """ headers = deepcopy(self.headers) if user_headers: @@ -1043,7 +1066,7 @@ def prepare_headers(self, method, user_headers={}): return headers @property - def print_debug(self): + def print_debug(self) -> bool: """ Printing debug flag @@ -1060,7 +1083,7 @@ def print_debug(self): return self._debug @print_debug.setter - def print_debug(self, debug): + def print_debug(self, debug: bool): self._debug = debug if debug and not hasattr(self, '_debugHandler'): self.log.setLevel(logging.DEBUG) @@ -1072,7 +1095,7 @@ def print_debug(self, debug): delattr(self, '_debugHandler') # else: no-op; only happens if debug is set to the same value twice - def request(self, method, url, **kwargs): + def request(self, method, url, **kwargs) -> Response: """ Make a generic PagerDuty API request. @@ -1086,8 +1109,8 @@ def request(self, method, url, **kwargs): Custom keyword arguments to pass to ``requests.Session.request``. :type method: str :type url: str - :returns: the HTTP response object - :rtype: `requests.Response`_ + :returns: + The `requests.Response`_ object corresponding to the HTTP response """ sleep_timer = self.sleep_timer network_attempts = 0 @@ -1173,7 +1196,7 @@ def request(self, method, url, **kwargs): return response @property - def stagger_cooldown(self): + def stagger_cooldown(self) -> float: """ Randomizing factor for wait times between retries during rate limiting. @@ -1214,15 +1237,15 @@ def stagger_cooldown(self, val): self._stagger_cooldown = val @property - def trunc_key(self): + def trunc_key(self) -> str: """Truncated key for secure display/identification purposes.""" return last_4(self.api_key) @property - def user_agent(self): + def user_agent(self) -> str: return 'pdpyras/%s python-requests/%s Python/%d.%d'%( __version__, - requests.__version__, + REQUESTS_VERSION, sys.version_info.major, sys.version_info.minor ) @@ -1252,22 +1275,27 @@ def __init__(self, api_key: str, debug=False): self.retry[503] = 6 # service unavailable, 7 requests total @property - def auth_header(self): + def auth_header(self) -> dict: return {} - def acknowledge(self, dedup_key): + def acknowledge(self, dedup_key) -> str: """ Acknowledge an alert via Events API. :param dedup_key: The deduplication key of the alert to set to the acknowledged state. + :returns: + The deduplication key """ return self.send_event('acknowledge', dedup_key=dedup_key) - def prepare_headers(self, method, user_headers={}): - """Add user agent and content type headers for Events API requests. + def prepare_headers(self, method, user_headers={}) -> dict: + """ + Add user agent and content type headers for Events API requests. :param user_headers: User-supplied headers that will override defaults + :returns: + The final list of headers to use in the request """ headers = {} headers.update(self.headers) @@ -1278,7 +1306,7 @@ def prepare_headers(self, method, user_headers={}): headers.update(user_headers) return headers - def resolve(self, dedup_key): + def resolve(self, dedup_key) -> str: """ Resolve an alert via Events API. @@ -1287,7 +1315,7 @@ def resolve(self, dedup_key): """ return self.send_event('resolve', dedup_key=dedup_key) - def send_event(self, action, dedup_key=None, **properties): + def send_event(self, action, dedup_key=None, **properties) -> str: """ Send an event to the v2 Events API. @@ -1305,7 +1333,7 @@ def send_event(self, action, dedup_key=None, **properties): :type action: str :type dedup_key: str :returns: - The deduplication key of the incident, if any. + The deduplication key of the incident """ actions = ('trigger', 'acknowledge', 'resolve') @@ -1332,7 +1360,7 @@ def send_event(self, action, dedup_key=None, **properties): raise PDServerError(err_msg, response) return response_body['dedup_key'] - def post(self, *args, **kw): + def post(self, *args, **kw) -> Response: """ Override of ``requests.Session.post`` @@ -1343,7 +1371,7 @@ def post(self, *args, **kw): return super(EventsAPISession, self).post(*args, **kw) def trigger(self, summary, source, dedup_key=None, severity='critical', - payload=None, custom_details=None, images=None, links=None): + payload=None, custom_details=None, images=None, links=None) -> str: """ Trigger an incident @@ -1378,7 +1406,8 @@ def trigger(self, summary, source, dedup_key=None, severity='critical', :type severity: str :type source: str :type summary: str - :rtype: str + :returns: + The deduplication key of the incident, if any. """ for local in ('payload', 'custom_details'): local_var = locals()[local] @@ -1402,7 +1431,7 @@ def trigger(self, summary, source, dedup_key=None, severity='critical', class ChangeEventsAPISession(PDSession): """ - Session class for submitting change events to the PagerDuty v2 Change Events API. + Session class for submitting events to the PagerDuty v2 Change Events API. Implements methods for submitting change events to PagerDuty's change events API. See the `Change Events API documentation @@ -1424,15 +1453,21 @@ def __init__(self, api_key: str, debug=False): self.retry[503] = 6 # service unavailable, 7 requests total @property - def auth_header(self): + def auth_header(self) -> dict: return {} @property - def event_timestamp(self): + def event_timestamp(self) -> str: return datetime.utcnow().isoformat()+'Z' - def prepare_headers(self, method, user_headers={}): - """Add user agent and content type headers for Change Events API requests.""" + def prepare_headers(self, method, user_headers={}) -> dict: + """ + Add user agent and content type headers for Change Events API requests. + + :param user_headers: User-supplied headers that will override defaults + :returns: + The final list of headers to use in the request + """ headers = deepcopy(self.headers) headers.update({ 'Content-Type': 'application/json', @@ -1462,7 +1497,7 @@ def send_change_event(self, **properties): return response_body.get("id", None) def submit(self, summary, source=None, custom_details=None, links=None, - timestamp=None): + timestamp=None) -> str: """ Submit an incident change @@ -1481,7 +1516,8 @@ def submit(self, summary, source=None, custom_details=None, links=None, :type custom_details: dict :type links: list :type timestamp: str - :rtype: str + :returns: + The response ID """ local_var = locals()['custom_details'] if not (local_var is None or isinstance(local_var, dict)): @@ -1552,7 +1588,7 @@ class APISession(PDSession): url = 'https://api.pagerduty.com' """Base URL of the REST API""" - def __init__(self, api_key, default_from=None, + def __init__(self, api_key: str, default_from=None, auth_type='token', debug=False): self.api_call_counts = {} self.api_time = {} @@ -1567,7 +1603,7 @@ def after_set_api_key(self): self._subdomain = None @property - def api_key_access(self): + def api_key_access(self) -> str: """ Memoized API key access type getter. @@ -1594,7 +1630,7 @@ def api_key_access(self): return self._api_key_access @property - def auth_type(self): + def auth_type(self) -> str: """ Defines the method of API authentication. @@ -1610,15 +1646,15 @@ def auth_type(self, value: str): self._auth_type = value @property - def auth_header(self): + def auth_header(self) -> dict: if self.auth_type in ('bearer', 'oauth2'): return {"Authorization": "Bearer "+self.api_key} else: return {"Authorization": "Token token="+self.api_key} - def dict_all(self, path, **kw): + def dict_all(self, path: str, **kw) -> dict: """ - Returns a dictionary of all objects from a given index endpoint. + Dictionary representation of resource collection results With the exception of ``by``, all keyword arguments passed to this method are also passed to :attr:`iter_all`; see the documentation on @@ -1637,14 +1673,11 @@ def dict_all(self, path, **kw): iterator = self.iter_all(path, **kw) return {obj[by]:obj for obj in iterator} - def find(self, resource, query, attribute='name', params=None): + def find(self, resource, query, attribute='name', params=None) \ + -> Union[dict, None]: """ Finds an object of a given resource type exactly matching a query. - Returns a dict if a result is found. The structure will be that of an - entry in the index endpoint schema's array of results. Otherwise, it - will return ``None`` if no result is found or an error is encountered. - Works by querying a given resource index endpoint using the ``query`` parameter. To use this function on any given resource, the resource's index must support the ``query`` parameter; otherwise, the function may @@ -1669,7 +1702,9 @@ def find(self, resource, query, attribute='name', params=None): :type query: str :type attribute: str :type params: dict or None - :rtype: dict + :returns: + The dictionary representation of the result, if found; ``None`` will + be returned if there is no exact match result. """ query_params = {} if params is not None: @@ -1683,7 +1718,7 @@ def find(self, resource, query, attribute='name', params=None): return next(iter(filter(equiv, obj_iter)), None) def iter_all(self, url, params=None, page_size=None, item_hook=None, - total=False): + total=False) -> Iterator[dict]: """ Iterator for the contents of an index endpoint or query. @@ -1731,24 +1766,26 @@ def iter_all(self, url, params=None, page_size=None, item_hook=None, # Get entity wrapping and validate that the URL being requested is # likely to support pagination: path = canonical_path(self.url, url) - # Short-circuit to cursor-based iteration: + endpoint = f"GET {path}" + + # Short-circuit to cursor-based pagination if appropriate: if path in CURSOR_BASED_PAGINATION_PATHS: return self.iter_cursor(url, params=params) - endpoint = f"GET {path}" + nodes = path.split('/') if is_path_param(nodes[-1]): - # This is based on an as-yet universal pattern, but like classic - # entity wrapping conventions, it isn't explicitly in the API - # contract and so it may be subject to change. Therefore, I can only - # hope our API developers do not deviate from it. If ever a path - # parameter refers to a resource type versus a unique ID, we will - # have to distinguish between types of path parameters somehow. - raise URLError(f"Path {path} (URL={url}) is for accessing an " \ - "individual resource, versus a resource collection, and as " \ - "such does not feature pagination.") + # NOTE: If this happens for a newer API, the path might need to be + # added to the EXPAND_PATHS dictionary in + # scripts/get_path_list/get_path_list.py, after which + # CANONICAL_PATHS will then need to be updated accordingly based on + # the new output of the script. + raise URLError(f"Path {path} (URL={url}) is formatted like an " \ + "individual resource versus a resource collection. It is " \ + "therefore assumed to not support pagination.") _, wrapper = entity_wrappers('GET', path) + if wrapper is None: - raise URLError(f"Pagination is not supported for GET {path}.") + raise URLError(f"Pagination is not supported for {endpoint}.") # Parameters to send: data = {} @@ -1827,7 +1864,7 @@ def iter_all(self, url, params=None, page_size=None, item_hook=None, item_hook(result, n, total_count) yield result - def iter_cursor(self, url, params=None, item_hook=None): + def iter_cursor(self, url, params=None, item_hook=None) -> Iterator[dict]: """ Iterator for results from an endpoint using cursor-based pagination. @@ -1874,7 +1911,7 @@ def iter_cursor(self, url, params=None, item_hook=None): @resource_url @auto_json - def jget(self, url, **kw): + def jget(self, url, **kw) -> Union[dict, list]: """ Performs a GET request, returning the JSON-decoded body as a dictionary """ @@ -1882,7 +1919,7 @@ def jget(self, url, **kw): @resource_url @auto_json - def jpost(self, url, **kw): + def jpost(self, url, **kw) -> Union[dict, list]: """ Performs a POST request, returning the JSON-decoded body as a dictionary """ @@ -1890,13 +1927,13 @@ def jpost(self, url, **kw): @resource_url @auto_json - def jput(self, url, **kw): + def jput(self, url, **kw) -> Union[dict, list]: """ Performs a PUT request, returning the JSON-decoded body as a dictionary """ return self.put(url, **kw) - def list_all(self, url, **kw): + def list_all(self, url, **kw) -> list: """ Returns a list of all objects from a given index endpoint. @@ -1953,7 +1990,7 @@ def persist(self, resource, attr, values, update=False): else: return self.rpost(resource, json=values) - def postprocess(self, response: requests.Response, suffix=None): + def postprocess(self, response: Response, suffix=None): """ Records performance information / request metadata about the API call. @@ -1994,7 +2031,7 @@ def postprocess(self, response: requests.Response, suffix=None): "and reference x_request_id=%s / date=%s", status, request_id, request_date) - def prepare_headers(self, method, user_headers={}): + def prepare_headers(self, method, user_headers={}) -> dict: headers = deepcopy(self.headers) headers['User-Agent'] = self.user_agent if self.default_from is not None: @@ -2007,7 +2044,7 @@ def prepare_headers(self, method, user_headers={}): @resource_url @requires_success - def rdelete(self, resource, **kw) -> requests.Response: + def rdelete(self, resource, **kw) -> Response: """ Delete a resource. @@ -2023,7 +2060,7 @@ def rdelete(self, resource, **kw) -> requests.Response: @resource_url @wrapped_entities - def rget(self, resource, **kw): + def rget(self, resource, **kw) -> Union[dict, list]: """ Wrapped-entity-aware GET function. @@ -2037,14 +2074,13 @@ def rget(self, resource, **kw): :param **kw: Custom keyword arguments to pass to ``requests.Session.get`` :returns: - Dictionary representation of the object. + Dictionary representation of the requested object :type resource: str or dict - :rtype: dict """ return self.get(resource, **kw) @wrapped_entities - def rpost(self, path, **kw): + def rpost(self, path, **kw) -> Union[dict, list]: """ Wrapped-entity-aware POST function. @@ -2058,13 +2094,12 @@ def rpost(self, path, **kw): :returns: Dictionary representation of the created object :type path: str - :rtype: dict """ return self.post(path, **kw) @resource_url @wrapped_entities - def rput(self, resource, **kw): + def rput(self, resource, **kw) -> Union[dict, list]: """ Wrapped-entity-aware PUT function. @@ -2078,12 +2113,11 @@ def rput(self, resource, **kw): Custom keyword arguments to pass to ``requests.Session.put`` :returns: Dictionary representation of the updated object - :rtype: dict """ return self.put(resource, **kw) @property - def subdomain(self): + def subdomain(self) -> str: """ Subdomain of the PagerDuty account of the API access token. @@ -2100,17 +2134,17 @@ def subdomain(self): return self._subdomain @property - def total_call_count(self): + def total_call_count(self) -> int: """The total number of API calls made by this instance.""" return sum(self.api_call_counts.values()) @property - def total_call_time(self): + def total_call_time(self) -> float: """The total time spent making API calls.""" return sum(self.api_time.values()) @property - def trunc_token(self): + def trunc_token(self) -> str: """Truncated token for secure display/identification purposes.""" return last_4(self.api_key) @@ -2175,7 +2209,7 @@ class PDHTTPError(PDClientError): print("HTTP error: "+str(e.response.status_code)) """ - def __init__(self, message, response: requests.Response): + def __init__(self, message, response: Response): super(PDHTTPError, self).__init__(message, response=response) class PDServerError(PDHTTPError): diff --git a/scripts/get_path_list/get_path_list.py b/scripts/get_path_list/get_path_list.py index 4938c46..338c125 100755 --- a/scripts/get_path_list/get_path_list.py +++ b/scripts/get_path_list/get_path_list.py @@ -1,5 +1,10 @@ #!/usr/bin/env python +# Usage: get_path_list.py PATH +# +# PATH must be a path to "reference/v2/Index.yaml" within a clone of the API +# source code repository. + # This script is not part of the pdpyras library. Rather, it can be used for the # by PagerDuty engineers to assist the development and maintenance of pdpyras. # It automatically generates the declaration of module variables @@ -7,8 +12,23 @@ # documentation source code (which is kept in a private repository in the # PagerDuty GitHub org). # -# To use, run this script with its sole argument a path to -# "reference/v2/Index.yaml" inside a clone of the repo: +# It is meant to minimize the amount of work that has to be done to allow +# pdpyras to support new APIs by generating the client's specific knowledge +# of APIs directly from the documentation programatically. + +# NOTE: +# +# If any new API introduces an endpoint that is designed to work as a resource +# collection and support pagination, but whose path ends in a variable parameter +# that refers to a value in a fixed list of well-recognized entity types (as +# opposed to a separate documentation page per distinct entity type), THE +# CANONICAL PATH WILL NEED TO BE ADDED TO THE FOLLOWING DICTIONARY, OR ENTITY +# WRAPPING WILL END UP BROKEN FOR THAT ENDPOINT: +EXPAND_PATHS = { + '/tags/{id}/{entity_type}': [ + '/tags/{id}/'+et for et in ('users', 'teams', 'escalation_policies') + ] +} import sys from yaml import load, dump @@ -31,7 +51,9 @@ def main(): print('CANONICAL_PATHS = [') for path in public_endpoints: - print(f" '{path}',") + print_paths = EXPAND_PATHS.get(path, [path]) + for path in print_paths: + print(f" '{path}',") print("]") print('"""'+"\nExplicit list of supported canonical REST API v2 paths") print("\n:meta hide-value:\n"+'"""'+"\n") diff --git a/setup.py b/setup.py index 851a982..db92657 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -__version__ = '5.1.3' +__version__ = '5.2.0' if __name__ == '__main__': setup( diff --git a/test_pdpyras.py b/test_pdpyras.py index c30769b..7b0621f 100755 --- a/test_pdpyras.py +++ b/test_pdpyras.py @@ -132,6 +132,8 @@ class EntityWrappingTest(unittest.TestCase): def test_entity_wrappers(self): io_expected = [ + # Special endpoint (broken support v5.0.0 - 5.1.x) managed by script + (('get', '/tags/{id}/users'), ('users', 'users')), # Conventional endpoint: singular read (('get', '/services/{id}'), ('service', 'service')), # Conventional endpoint: singular update