From 2ddc2cc4740a5b8e70b726119ec838387204acc2 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 20 Sep 2022 16:10:39 -0700 Subject: [PATCH 01/20] Test infra --- src/blueink/tests/__init__.py | 0 src/blueink/utils/__init__.py | 0 src/blueink/utils/testcase.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/blueink/tests/__init__.py create mode 100644 src/blueink/utils/__init__.py create mode 100644 src/blueink/utils/testcase.py diff --git a/src/blueink/tests/__init__.py b/src/blueink/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/blueink/utils/__init__.py b/src/blueink/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/blueink/utils/testcase.py b/src/blueink/utils/testcase.py new file mode 100644 index 0000000..a0c47fc --- /dev/null +++ b/src/blueink/utils/testcase.py @@ -0,0 +1,28 @@ +class TestCase: + + def assert_true(self, val): + if val is None: + assert False, f"{val} is None, not True" + + assert val, f"{val} is False, not True" + + def assert_false(self, val): + if val is None: + assert False, f"{val} is None, not False" + + assert not val, f"{val} is True, not False" + + def assert_equal(self, a, b): + assert a == b, f"{a} != {b}" + + def assert_not_equal(self, a, b): + assert a != b, f"{a} == {b}" + + def assert_in(self, item, container): + assert item in container + + def assert_not_in(self, item, container): + assert item not in container, f"{item} is not in array/set" + + def assert_len(self, container, length): + assert len(container) == length, f"{len(container)} != {length}" From e884d76adfebbd45aef4d5773c276937049cc44a Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 20 Sep 2022 16:10:49 -0700 Subject: [PATCH 02/20] basic tests for BundleHelper --- src/blueink/tests/test_bundle_helper.py | 146 ++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/blueink/tests/test_bundle_helper.py diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py new file mode 100644 index 0000000..4c42488 --- /dev/null +++ b/src/blueink/tests/test_bundle_helper.py @@ -0,0 +1,146 @@ +import copy + +from src.blueink import BundleHelper +from src.blueink.utils.testcase import TestCase + + +class TestBundleHelper(TestCase): + + BUNDLE_INIT_DATA = { + "label": "TEST_BUNDLE", + "email_subject": "EMAIL_SUBJECT", + "email_message": "EMAIL_MESSAGE", + "in_order": True, + "is_test": False, + "custom_key": "CUSTOM_KEY", + "team": None + } + + SIGNER_01_DATA = { + "name": "Eli Vance", + "email": "eli@blackmesa.gov", + "phone": "505 555 5555", + "deliver_via": "email", + "person_id": "person-01", + "auth_sms": False, + "auth_selfie": False, + "auth_id": False, + } + + SIGNER_02_DATA = { + "name": "Gordon Freeman", + "email": "gordon@blackmesa.gov", + "phone": "505 555 5556", + "deliver_via": "email", + "person_id": "person-02", + "auth_sms": False, + "auth_selfie": False, + "auth_id": False, + } + + FIELD_01_DATA = { + "x": 15, + "y": 20, + "w": 10, + "h": 12, + "p": 1, + "kind": "inp", + "editors": [], + "label": "MY_INPUT_01" + } + + FIELD_02_DATA = { + "x": 23, + "y": 43, + "w": 5, + "h": 2, + "p": 1, + "kind": "inp", + "editors": [], + "label": "MY_INPUT_02" + } + + DOCUMENT_01_URL = "https://www.example.com/example1.pdf" + DOCUMENT_02_URL = "https://www.example.com/example2.pdf" + + + + def __init__(self): + pass + + def test_base_bundle(self): + """Test creating a Bundle with no documents, no signers -- just the base Bundle""" + input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) + bh = BundleHelper(**input_data) + compiled_bundle = bh.as_data() + + for key, value in input_data.items(): + self.assert_equal(compiled_bundle[key], value) + + def test_adding_document_via_url(self): + input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) + url01 = self.DOCUMENT_01_URL + url02 = self.DOCUMENT_02_URL + + bh = BundleHelper(**input_data) + bh.add_document_by_url(url01) + bh.add_document_by_url(url02) + + compiled_bundle = bh.as_data() + + self.assert_in("documents", compiled_bundle) + self.assert_len(compiled_bundle["documents"], 2) + + self.assert_in("file_url", compiled_bundle["documents"][0]) + self.assert_in("file_url", compiled_bundle["documents"][1]) + + self.assert_equal(compiled_bundle["documents"][0]["file_url"], url01) + self.assert_equal(compiled_bundle["documents"][1]["file_url"], url02) + + def test_adding_fields(self): + input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) + url01 = self.DOCUMENT_01_URL + signer01_data = copy.deepcopy(self.SIGNER_01_DATA) + signer02_data = copy.deepcopy(self.SIGNER_02_DATA) + field01_data = copy.deepcopy(self.FIELD_01_DATA) + field02_data = copy.deepcopy(self.FIELD_02_DATA) + + + bh = BundleHelper(**input_data) + doc01_key = bh.add_document_by_url(url01) + signer01_key = bh.add_signer(**signer01_data) + signer02_key = bh.add_signer(**signer02_data) + + field01_data["document_key"] = doc01_key + field01_data["editors"].append(signer01_key) + field01_data["editors"].append(signer02_key) + bh.add_field(**field01_data) + + field02_data["document_key"] = doc01_key + field02_data["editors"].append(signer01_key) + bh.add_field(**field02_data) + + compiled_bundle = bh.as_data() + + # Bundle and Field correctly populated, probably can use reflection + # to be more thorough. + self.assert_in("documents", compiled_bundle) + self.assert_len(compiled_bundle["documents"], 1) + + self.assert_in("fields", compiled_bundle["documents"][0]) + self.assert_len(compiled_bundle["documents"][0]["fields"], 2) + + field01 = compiled_bundle["documents"][0]["fields"][0] + self.assert_equal(field01_data["label"], field01["label"]) + self.assert_len(field01["editors"], 2) + + field02 = compiled_bundle["documents"][0]["fields"][1] + self.assert_equal(field02_data["label"], field02["label"]) + self.assert_len(field02["editors"], 2) + + # Correct packets + self.assert_in("packets", compiled_bundle) + self.assert_len(compiled_bundle["packets"], 2) + + self.assert_equal(compiled_bundle["packets"][0]["key"], signer01_key) + self.assert_equal(compiled_bundle["packets"][1]["key"], signer02_key) From c6ce386d47868ef7f6cb377e80fb577ba65e3f1e Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 20 Sep 2022 16:20:16 -0700 Subject: [PATCH 03/20] corrected test input data --- src/blueink/tests/test_bundle_helper.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py index 4c42488..5728e2c 100644 --- a/src/blueink/tests/test_bundle_helper.py +++ b/src/blueink/tests/test_bundle_helper.py @@ -13,7 +13,6 @@ class TestBundleHelper(TestCase): "in_order": True, "is_test": False, "custom_key": "CUSTOM_KEY", - "team": None } SIGNER_01_DATA = { @@ -63,11 +62,6 @@ class TestBundleHelper(TestCase): DOCUMENT_01_URL = "https://www.example.com/example1.pdf" DOCUMENT_02_URL = "https://www.example.com/example2.pdf" - - - def __init__(self): - pass - def test_base_bundle(self): """Test creating a Bundle with no documents, no signers -- just the base Bundle""" input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) @@ -136,7 +130,7 @@ def test_adding_fields(self): field02 = compiled_bundle["documents"][0]["fields"][1] self.assert_equal(field02_data["label"], field02["label"]) - self.assert_len(field02["editors"], 2) + self.assert_len(field02["editors"], 1) # Correct packets self.assert_in("packets", compiled_bundle) From 5d81dee138893d30d16fbfdcb00c5d2e0d30446f Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 20 Sep 2022 16:46:19 -0700 Subject: [PATCH 04/20] More thorough field test --- src/blueink/tests/test_bundle_helper.py | 26 +++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py index 5728e2c..8af59dd 100644 --- a/src/blueink/tests/test_bundle_helper.py +++ b/src/blueink/tests/test_bundle_helper.py @@ -116,8 +116,6 @@ def test_adding_fields(self): compiled_bundle = bh.as_data() - # Bundle and Field correctly populated, probably can use reflection - # to be more thorough. self.assert_in("documents", compiled_bundle) self.assert_len(compiled_bundle["documents"], 1) @@ -125,12 +123,26 @@ def test_adding_fields(self): self.assert_len(compiled_bundle["documents"][0]["fields"], 2) field01 = compiled_bundle["documents"][0]["fields"][0] - self.assert_equal(field01_data["label"], field01["label"]) self.assert_len(field01["editors"], 2) + self.assert_in("key", field01) + self.assert_equal(field01["x"], field01_data["x"]) + self.assert_equal(field01["y"], field01_data["y"]) + self.assert_equal(field01["w"], field01_data["w"]) + self.assert_equal(field01["h"], field01_data["h"]) + self.assert_equal(field01["page"], field01_data["p"]) + self.assert_equal(field01["kind"], field01_data["kind"]) + self.assert_equal(field01["label"], field01_data["label"]) field02 = compiled_bundle["documents"][0]["fields"][1] - self.assert_equal(field02_data["label"], field02["label"]) self.assert_len(field02["editors"], 1) + self.assert_in("key", field02) + self.assert_equal(field02["x"], field02_data["x"]) + self.assert_equal(field02["y"], field02_data["y"]) + self.assert_equal(field02["w"], field02_data["w"]) + self.assert_equal(field02["h"], field02_data["h"]) + self.assert_equal(field02["page"], field02_data["p"]) + self.assert_equal(field02["kind"], field02_data["kind"]) + self.assert_equal(field02["label"], field02_data["label"]) # Correct packets self.assert_in("packets", compiled_bundle) @@ -138,3 +150,9 @@ def test_adding_fields(self): self.assert_equal(compiled_bundle["packets"][0]["key"], signer01_key) self.assert_equal(compiled_bundle["packets"][1]["key"], signer02_key) + + # Verify signer data transferred as expected + for k, v in signer01_data.items(): + self.assert_equal(compiled_bundle["packets"][0][k], v) + for k, v in signer02_data.items(): + self.assert_equal(compiled_bundle["packets"][1][k], v) From 40834b8f22362ad7e4e5f2d8d32e5114169b6839 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Thu, 22 Sep 2022 08:43:22 -0700 Subject: [PATCH 05/20] Better type hinting --- src/blueink/client.py | 135 ++++++++++++++++++++++------------ src/blueink/person_helper.py | 12 +-- src/blueink/request_helper.py | 2 +- 3 files changed, 94 insertions(+), 55 deletions(-) diff --git a/src/blueink/client.py b/src/blueink/client.py index ad979a8..23a01a9 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -6,13 +6,18 @@ from . import endpoints from .bundle_helper import BundleHelper -from .constants import BUNDLE_STATUS, DEFAULT_BASE_URL, ENV_BLUEINK_API_URL, ENV_BLUEINK_PRIVATE_API_KEY +from .constants import ( + BUNDLE_STATUS, + DEFAULT_BASE_URL, + ENV_BLUEINK_API_URL, + ENV_BLUEINK_PRIVATE_API_KEY +) from .paginator import PaginatedIterator from .person_helper import PersonHelper from .request_helper import NormalizedResponse, RequestHelper -def _build_params(page=None, per_page=None, **query_params): +def _build_params(page: int = None, per_page: int = None, **query_params): params = dict(**query_params) if page is not None: # page could be zero, although Blueink pagination is 1-indexed params["page"] = page @@ -24,16 +29,16 @@ def _build_params(page=None, per_page=None, **query_params): class Client: - def __init__(self, private_api_key=None, base_url=None): + def __init__(self, private_api_key: str = None, base_url: str = None): """Initialize a Client instance to access the Blueink eSignature API Args: private_api_key: the private API key used to access the Blueink API. - If no value is provided, then the environment is checked for a variable named - "BLUEINK_PRIVATE_API_KEY". - base_url: override the API base URL. If not supplied, we check the environment variable - BLUEINK_API_URL. If that is empty, the default value of "https://api.blueink.com/api/v2" - is used. + If no value is provided, then the environment is checked for a variable + named "BLUEINK_PRIVATE_API_KEY". + base_url: override the API base URL. If not supplied, we check the + environment variable BLUEINK_API_URL. If that is empty, the default + value of "https://api.blueink.com/api/v2" is used. Returns: A Client instance @@ -47,8 +52,9 @@ def __init__(self, private_api_key=None, base_url=None): if not private_api_key: raise ValueError( - "A Blueink Private API Key must be provided on Client initialization or " - f"specified via the environment variable {ENV_BLUEINK_PRIVATE_API_KEY}" + "A Blueink Private API Key must be provided on Client initialization" + " or specified via the environment variable" + " {ENV_BLUEINK_PRIVATE_API_KEY}" ) if not base_url: @@ -65,7 +71,7 @@ def __init__(self, private_api_key=None, base_url=None): self.templates = self._Templates(base_url, self._request_helper) class _SubClient: - def __init__(self, base_url, requests_helper): + def __init__(self, base_url: str, requests_helper: RequestHelper): self._base_url = base_url self._requests = requests_helper @@ -74,14 +80,16 @@ def build_url(self, endpoint: str, **kwargs): Args: endpoint: one of the API endpoints, e.g. endpoints.BUNDLES.create - **kwargs: the arg name should be one of the keys in endpoints.interpolations, and the arg - value will be substituted for the named placeholder in the endpoint str + **kwargs: the arg name should be one of the keys in endpoints. + interpolations, and the arg value will be substituted for the named + placeholder in the endpoint str Returns: The URL as a str Raises: - ValueError if one of the kwargs is not a valid endpoint interpolation key + ValueError if one of the kwargs is not a valid endpoint + interpolation key """ # All of our current endpoints take 1 parameter, max if len(kwargs) > 1: @@ -91,12 +99,13 @@ def build_url(self, endpoint: str, **kwargs): url = endpoints.URLBuilder(self._base_url, endpoint).build(**kwargs) except KeyError: arg_name = list(kwargs.keys())[0] - raise ValueError(f'Invalid substitution argument "{arg_name}" provided for endpoint "{endpoint}"') + raise ValueError(f'Invalid substitution argument "{arg_name}"' + f' provided for endpoint "{endpoint}"') return url class _Bundles(_SubClient): - def _prepare_files(self, file_list): + def _prepare_files(self, file_list: list[io.BufferedReader]): if isinstance(file_list, dict): file_list = [file_list] @@ -106,19 +115,24 @@ def _prepare_files(self, file_list): try: fh = file_dict["file"] except KeyError: - raise ValueError("Each file dict must have a 'file' key that is a file-like object") + raise ValueError("Each file dict must have a 'file' key that" + " is a file-like object") if not isinstance(fh, io.BufferedReader): raise ValueError( - f"Bad type for file {idx}. Expected an io.BufferedReader (e.g. an open file handle)" + f"Bad type for file {idx}. Expected an io.BufferedReader" + f" (e.g. an open file handle)" ) field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), fh, file_dict.get("content_type")))) + files_data.append((field_name, (file_dict.get("filename"), + fh, + file_dict.get("content_type")))) return files_data - def create(self, data: dict, files=[]) -> NormalizedResponse: + def create(self, data: dict, + files: list[io.BufferedReader] = []) -> NormalizedResponse: """ Post a Bundle to the BlueInk application. :param data: python dict, typically from BundleHelper.as_data() @@ -139,22 +153,26 @@ def create(self, data: dict, files=[]) -> NormalizedResponse: bundle_request_data = {"bundle_request": json.dumps(data)} - response = self._requests.post(url, data=bundle_request_data, files=files_data) + response = self._requests.post(url, + data=bundle_request_data, + files=files_data) return response - def create_from_bundle_helper(self, bundle_helper: BundleHelper) -> NormalizedResponse: + def create_from_bundle_helper(self, + bdl_helper: BundleHelper) -> NormalizedResponse: """ - Post a Bundle to the BlueInk application. Convenience method as bundle_helper has files/filenames if - creating a Bundle that way - :param bundle_helper: + Post a Bundle to the BlueInk application. Convenience method as + bundle_helper has files/filenames if creating a Bundle that way + :param bdl_helper: :return: """ - data = bundle_helper.as_data() - files = bundle_helper.files + data = bdl_helper.as_data() + files = bdl_helper.files return self.create(data=data, files=files) - def paged_list(self, page=1, per_page=50, related_data=False, **query_params) -> PaginatedIterator: + def paged_list(self, page: int = 1, per_page: int = 50, + related_data: bool = False, **query_params) -> PaginatedIterator: """ returns an iterable object such that you can do @@ -174,7 +192,8 @@ def paged_list(self, page=1, per_page=50, related_data=False, **query_params) -> **query_params) return iterator - def list(self, page=None, per_page=None, related_data=False, **query_params) -> NormalizedResponse: + def list(self, page: int = None, per_page: int = None, + related_data: bool = False, **query_params) -> NormalizedResponse: """ Returns a list of bundles :param page: (optional) @@ -184,7 +203,10 @@ def list(self, page=None, per_page=None, related_data=False, **query_params) -> :return: """ url = self.build_url(endpoints.BUNDLES.LIST) - response = self._requests.get(url, params=_build_params(page, per_page, **query_params)) + response = self._requests.get(url, + params=_build_params(page, + per_page, + **query_params)) if related_data: for bundle in response.data: @@ -207,7 +229,8 @@ def _attach_additional_data(self, bundle): data_response = self.list_data(bundle_id) bundle.data = data_response.data - def retrieve(self, bundle_id, related_data=False) -> NormalizedResponse: + def retrieve(self, bundle_id: str, + related_data: bool = False) -> NormalizedResponse: """ Requests a single bundle :param bundle_id: bundle slug @@ -223,7 +246,7 @@ def retrieve(self, bundle_id, related_data=False) -> NormalizedResponse: return response - def cancel(self, bundle_id) -> NormalizedResponse: + def cancel(self, bundle_id: str) -> NormalizedResponse: """ Cancels a bundle given bundle slug :param bundle_id: @@ -232,7 +255,7 @@ def cancel(self, bundle_id) -> NormalizedResponse: url = self.build_url(endpoints.BUNDLES.CANCEL, bundle_id=bundle_id) return self._request.put(url) - def list_events(self, bundle_id) -> NormalizedResponse: + def list_events(self, bundle_id: str) -> NormalizedResponse: """ Returns a list of events for the supplied bundle corresponding to the id :param bundle_id: @@ -241,7 +264,7 @@ def list_events(self, bundle_id) -> NormalizedResponse: url = self.build_url(endpoints.BUNDLES.LIST_EVENTS, bundle_id=bundle_id) return self._requests.get(url) - def list_files(self, bundle_id) -> NormalizedResponse: + def list_files(self, bundle_id: str) -> NormalizedResponse: """ Returns a list of files for the supplied bundle corresponding to the id :param bundle_id: @@ -250,9 +273,10 @@ def list_files(self, bundle_id) -> NormalizedResponse: url = self.build_url(endpoints.BUNDLES.LIST_FILES, bundle_id=bundle_id) return self._requests.get(url) - def list_data(self, bundle_id) -> NormalizedResponse: + def list_data(self, bundle_id: str) -> NormalizedResponse: """ - Returns a list of data fields for the supplied bundle corresponding to the id + Returns a list of data fields for the supplied bundle corresponding to + the id :param bundle_id: :return: """ @@ -275,7 +299,8 @@ def create(self, data: dict, **kwargs) -> NormalizedResponse: url = self.build_url(endpoints.PERSONS.CREATE) return self._requests.post(url, json=data) - def create_from_person_helper(self, person_helper: PersonHelper, **kwargs) -> NormalizedResponse: + def create_from_person_helper(self, person_helper: PersonHelper, + **kwargs) -> NormalizedResponse: """ Creates a person. :param person_helper: PersonHelper setup of a person @@ -283,7 +308,8 @@ def create_from_person_helper(self, person_helper: PersonHelper, **kwargs) -> No """ return self.create(person_helper.as_dict(**kwargs)) - def paged_list(self, page=1, per_page=50, **query_params) -> PaginatedIterator: + def paged_list(self, page: int = 1, per_page: int = 50, + **query_params) -> PaginatedIterator: """ returns an iterable object such that you can do @@ -302,16 +328,21 @@ def paged_list(self, page=1, per_page=50, **query_params) -> PaginatedIterator: **query_params) return iterator - def list(self, page=None, per_page=None, **query_params) -> NormalizedResponse: + def list(self, page: int = None, per_page: int = None, + **query_params) -> NormalizedResponse: """ - Returns a list of persons. Optionally supply the page number and results per page. + Returns a list of persons. Optionally supply the page number and results + per page. :param page: :param per_page: :param query_params: Additional query params to be put onto the request :return: """ url = self.build_url(endpoints.PERSONS.LIST) - return self._requests.get(url, params=_build_params(page, per_page, **query_params)) + return self._requests.get(url, + params=_build_params(page, + per_page, + **query_params)) def retrieve(self, person_id: str) -> NormalizedResponse: """ @@ -322,7 +353,8 @@ def retrieve(self, person_id: str) -> NormalizedResponse: url = self.build_url(endpoints.PERSONS.RETRIEVE, person_id=person_id) return self._requests.get(url) - def update(self, person_id: str, data: dict, partial=False) -> NormalizedResponse: + def update(self, person_id: str, data: dict, + partial: bool = False) -> NormalizedResponse: """ :param person_id: :param data: a full dictionary representation of person @@ -354,7 +386,8 @@ def update(self, packet_id: str, data: dict) -> NormalizedResponse: A NormalizedResponse, with the updated packet as `data` Raises: - exceptions.RequestException (or a more specific exception class) if an error occured + exceptions.RequestException (or a more specific exception class) + if an error occured """ url = self.build_url(endpoints.PACKETS.UPDATE, packet_id=packet_id) return self._requests.patch(url, json=data) @@ -362,7 +395,8 @@ def update(self, packet_id: str, data: dict) -> NormalizedResponse: def embed_url(self, packet_id: str) -> NormalizedResponse: """Create an embedded signing URL - deliver_via on the Packet must be set to "embed" for this request to succeed. + deliver_via on the Packet must be set to "embed" for this request + to succeed. Args: packet_id: the ID of the Packet. @@ -393,7 +427,8 @@ class _Templates(_SubClient): def __init__(self, base_url, private_api_key): super().__init__(base_url, private_api_key) - def paged_list(self, page=1, per_page=50, **query_params) -> PaginatedIterator: + def paged_list(self, page: int = 1, per_page: int = 50, + **query_params) -> PaginatedIterator: """ returns an iterable object such that you can do @@ -411,16 +446,20 @@ def paged_list(self, page=1, per_page=50, **query_params) -> PaginatedIterator: **query_params) return iterator - def list(self, page=None, per_page=None, **query_params) -> NormalizedResponse: + def list(self, page: int = None, per_page: int = None, + **query_params) -> NormalizedResponse: """ - Retrieves a list of templates, optionally for a page and # of results per page + Retrieves a list of templates, optionally for a page and # of results + per page :param page: :param per_page: :param query_params: Additional query params to be put onto the request :return: """ url = self.build_url(endpoints.TEMPLATES.LIST) - return self._requests.get(url, params=_build_params(page, per_page, **query_params)) + return self._requests.get(url, params=_build_params(page, + per_page, + **query_params)) def retrieve(self, template_id: str) -> NormalizedResponse: """ diff --git a/src/blueink/person_helper.py b/src/blueink/person_helper.py index 3e8ec58..683c4bf 100644 --- a/src/blueink/person_helper.py +++ b/src/blueink/person_helper.py @@ -14,7 +14,7 @@ def __init__( self._phones = phones self._emails = emails - def add_phone(self, phone: str) -> list: + def add_phone(self, phone: str) -> list[str]: """ Add a phone number to the current list of phone numbers @@ -27,7 +27,7 @@ def add_phone(self, phone: str) -> list: self._phones.append(phone) return self._phones - def set_phones(self, phones: list) -> list: + def set_phones(self, phones: list) -> list[str]: """ Replace the current list of phone numbers with this list @@ -40,7 +40,7 @@ def set_phones(self, phones: list) -> list: self._phones = phones return self._phones - def get_phones(self) -> list: + def get_phones(self) -> list[str]: """ Returns all of the phone numbers currently stored @@ -49,7 +49,7 @@ def get_phones(self) -> list: """ return self._phones - def add_email(self, email: str) -> list: + def add_email(self, email: str) -> list[str]: """ Add an email to the current list of emails @@ -61,7 +61,7 @@ def add_email(self, email: str) -> list: self._emails.append(email) return self._emails - def set_emails(self, emails: list) -> list: + def set_emails(self, emails: list) -> list[str]: """ Replace the current list of emails with this list @@ -74,7 +74,7 @@ def set_emails(self, emails: list) -> list: self._emails = emails return self._emails - def get_emails(self) -> list: + def get_emails(self) -> list[str]: """ Returns all of the emails currently stored diff --git a/src/blueink/request_helper.py b/src/blueink/request_helper.py index 44e4066..ea01d1c 100644 --- a/src/blueink/request_helper.py +++ b/src/blueink/request_helper.py @@ -43,7 +43,7 @@ def __init__(self, response: requests.Response): self.data = response.content self.request = response.request - self.status = response.status_code + self.status: int = response.status_code self.original_response = response # Pagination From a82fb3772b795d6a84f33d6cd848cf7c9555f6af Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Thu, 22 Sep 2022 09:14:13 -0700 Subject: [PATCH 06/20] fixed list type hints, removed mimetype --- src/blueink/bundle_helper.py | 8 ++++---- src/blueink/client.py | 4 ++-- src/blueink/person_helper.py | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index 1af189f..e94d69b 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -53,7 +53,7 @@ def add_document_by_url(self, url: str, **additional_data) -> str: self._documents[document.key] = document return document.key - def add_document_by_file(self, file: io.BufferedReader, file_name: str, mime_type: str, **additional_data) -> str: + def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additional_data) -> str: """ Add a document via url, with unique key. :param mime_type: @@ -66,7 +66,7 @@ def add_document_by_file(self, file: io.BufferedReader, file_name: str, mime_typ file_index = len(self.files) if type(file) == io.BufferedReader and file.readable(): - self.files.append({'file': file, "filename": file_name, "content_type": mime_type}) + self.files.append({'file': file, "filename": file_name}) else: raise ValueError(f"File unreadable.") @@ -86,7 +86,7 @@ def add_document_by_path(self, file_path: str, mime_type: str = None, **addition file = open(file_path, 'rb') return self.add_document_by_file(file, file.name, mime_type, **additional_data) - def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, mime_type: str, + def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, **additional_data) -> str: ''' Add a document via url, with unique key. @@ -99,7 +99,7 @@ def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, mime_ bytes = io.BytesIO(byte_array) file = io.BufferedReader(bytes, len(byte_array)) - return self.add_document_by_file(file, file_name, mime_type, **additional_data) + return self.add_document_by_file(file, file_name, **additional_data) def add_document_template(self, template_id: str, **additional_data) -> str: """ diff --git a/src/blueink/client.py b/src/blueink/client.py index 23a01a9..3ad839e 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -105,7 +105,7 @@ def build_url(self, endpoint: str, **kwargs): return url class _Bundles(_SubClient): - def _prepare_files(self, file_list: list[io.BufferedReader]): + def _prepare_files(self, file_list: [io.BufferedReader]): if isinstance(file_list, dict): file_list = [file_list] @@ -132,7 +132,7 @@ def _prepare_files(self, file_list: list[io.BufferedReader]): return files_data def create(self, data: dict, - files: list[io.BufferedReader] = []) -> NormalizedResponse: + files: [io.BufferedReader] = []) -> NormalizedResponse: """ Post a Bundle to the BlueInk application. :param data: python dict, typically from BundleHelper.as_data() diff --git a/src/blueink/person_helper.py b/src/blueink/person_helper.py index 683c4bf..25b47e0 100644 --- a/src/blueink/person_helper.py +++ b/src/blueink/person_helper.py @@ -14,7 +14,7 @@ def __init__( self._phones = phones self._emails = emails - def add_phone(self, phone: str) -> list[str]: + def add_phone(self, phone: str) -> [str]: """ Add a phone number to the current list of phone numbers @@ -27,7 +27,7 @@ def add_phone(self, phone: str) -> list[str]: self._phones.append(phone) return self._phones - def set_phones(self, phones: list) -> list[str]: + def set_phones(self, phones: list) -> [str]: """ Replace the current list of phone numbers with this list @@ -40,7 +40,7 @@ def set_phones(self, phones: list) -> list[str]: self._phones = phones return self._phones - def get_phones(self) -> list[str]: + def get_phones(self) -> [str]: """ Returns all of the phone numbers currently stored @@ -49,7 +49,7 @@ def get_phones(self) -> list[str]: """ return self._phones - def add_email(self, email: str) -> list[str]: + def add_email(self, email: str) -> [str]: """ Add an email to the current list of emails @@ -61,7 +61,7 @@ def add_email(self, email: str) -> list[str]: self._emails.append(email) return self._emails - def set_emails(self, emails: list) -> list[str]: + def set_emails(self, emails: list) -> [str]: """ Replace the current list of emails with this list @@ -74,7 +74,7 @@ def set_emails(self, emails: list) -> list[str]: self._emails = emails return self._emails - def get_emails(self) -> list[str]: + def get_emails(self) -> [str]: """ Returns all of the emails currently stored From 326786c5fd551e933fb92e8ac14d4ffdaaf797b7 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Thu, 22 Sep 2022 15:55:50 -0700 Subject: [PATCH 07/20] Made public facing methods/functions use Google styled DocStrings --- examples/create_bundle_from_file.py | 2 +- src/blueink/bundle_helper.py | 141 +++++++++------ src/blueink/client.py | 266 +++++++++++++++++----------- src/blueink/person_helper.py | 27 ++- 4 files changed, 269 insertions(+), 167 deletions(-) diff --git a/examples/create_bundle_from_file.py b/examples/create_bundle_from_file.py index 1e02977..b699c22 100644 --- a/examples/create_bundle_from_file.py +++ b/examples/create_bundle_from_file.py @@ -48,7 +48,7 @@ kind=FIELD_KIND.INPUT, label="label3", editors=[signer1, signer2]) - +client.bundles.create(data={}, files=12) try: response = client.bundles.create_from_bundle_helper(bh) except exceptions.HTTPError as e: diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index e94d69b..27135cf 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -1,4 +1,5 @@ import io +from typing import List from .model.bundles import ( Bundle, @@ -23,6 +24,19 @@ def __init__( custom_key: str = None, team: str = None, ): + """Helper class to aid building a Bundle. + + After documents/signers/fields added, use as_data() or as_json() to compile the Bundle either as a python dict or json string. + + Args: + label: + email_subject: + email_message: + in_order: + is_test: + custom_key: + team: + """ self._label = label self._in_order = in_order self._email_subj = email_subject @@ -56,7 +70,6 @@ def add_document_by_url(self, url: str, **additional_data) -> str: def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additional_data) -> str: """ Add a document via url, with unique key. - :param mime_type: :param file_name: :param file: :param additional_data: Optional and will append any additional kwargs to the json of the document @@ -74,17 +87,16 @@ def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additi self._documents[document.key] = document return document.key - def add_document_by_path(self, file_path: str, mime_type: str = None, **additional_data) -> str: + def add_document_by_path(self, file_path: str, **additional_data) -> str: """ Add a document via url, returns generated unique key. - :param mime_type: :param file_path: :param additional_data: Optional and will append any additional kwargs to the json of the document :return: Document instance """ file = open(file_path, 'rb') - return self.add_document_by_file(file, file.name, mime_type, **additional_data) + return self.add_document_by_file(file, file.name, **additional_data) def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, **additional_data) -> str: @@ -116,26 +128,28 @@ def add_document_template(self, template_id: str, **additional_data) -> str: return template.key def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, kind: str, - editors: [str] = None, label: str = None, v_pattern: str = None, v_min: int = None, + editors: List[str] = None, label: str = None, v_pattern: str = None, v_min: int = None, v_max: int = None, key=None, **additional_data): - """ - Create and add a field - :param document: - :param x: - :param y: - :param w: - :param h: - :param p: - :param kind: - - :param label: Optional - :param v_pattern: Optional - :param v_min: Optional - :param v_max: Optional - :param editors: Optional - :param key: Optional - :param additional_data: Optional and will append any additional kwargs to the json of the field - :return: Field object + """Create and add a field to a particular document. + + Args + document: + x: + y: + w: + h: + p: + kind: + label: Optional + v_pattern: Optional + v_min: Optional + v_max: Optional + editors: Optional + key: Optional + additional_data: Optional and will append any additional kwargs to the json of the field + + Returns: + Field key [str] """ if document_key not in self._documents: raise RuntimeError(f"No document found with key {document_key}!") @@ -154,22 +168,23 @@ def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, k def add_signer(self, name: str, email: str = None, phone: str = None, deliver_via: str = None, person_id=None, auth_sms: bool = False, auth_selfie: bool = False, auth_id: bool = False, order: int = None, key=None, **additional_data): - """ - Create and add a signer. - This should have at least an email xor phone number. - - :param key: - :param person_id: Optional - :param name: Optional - :param email: Optional - :param phone: Optional - :param auth_sms: Optional - :param auth_selfie: Optional - :param auth_id: Optional - :param deliver_via: Optional - :param order: Optional - :param additional_data: Optional and will append any additional kwargs to the json of the signer - :return: Packet instance + """Create and add a signer. With at least an email xor phone number. + + Args: + key: + person_id: Optional + name: Optional + email: Optional + phone: Optional + auth_sms: Optional + auth_selfie: Optional + auth_id: Optional + deliver_via: Optional + order: Optional + additional_data: Optional and will append any additional kwargs to the json of the signer + + Returns: + Packet key """ if phone is None and email is None: raise ValidationError('Packet must have either an email or phone number') @@ -189,13 +204,13 @@ def add_signer(self, name: str, email: str = None, phone: str = None, deliver_vi return packet.key def assign_role(self, document_key: str, signer_key: str, role: str, **additional_data): - """ - Assigns a signer to a particular role in a template - :param document_key: - :param signer_key: - :param role: - :param additional_data: Optional and will append any additional kwargs to the json of the ref assignment - :return: + """Assign a signer to a particular role in a template + + Args: + document_key: + signer_key: + role: + additional_data: Optional and will append any additional kwargs to the json of the ref assignment """ if document_key not in self._documents: raise RuntimeError(f"No document found with key {document_key}!") @@ -208,13 +223,13 @@ def assign_role(self, document_key: str, signer_key: str, role: str, **additiona self._documents[document_key].add_assignment(assignment) def set_value(self, document_key: str, key: str, value: str, **additional_data): - """ - Sets a field's value in a document. - :param document_key: - :param key: - :param value: - :param additional_data: Optional and will append any additional kwargs to the json of the field value - :return: + """Set a field's value in a document. + + Args: + document_key: + key: + value: + additional_data: Optional and will append any additional kwargs to the json of the field value """ if document_key not in self._documents: raise RuntimeError(f"No document found with key {document_key}!") @@ -248,17 +263,25 @@ def _compile_bundle(self, **additional_data) -> Bundle: return bundle_out def as_data(self, **additional_data): - """ - Returns a Bundle as a python dictionary - :return: + """Return a Bundle as a python dictionary + + Args: + additional_data: extra data to append to a bundle, as a dict + + Returns: + Bundle as dictionary """ bundle = self._compile_bundle(**additional_data) return bundle.dict(exclude_unset=True, exclude_none=True) def as_json(self, **additional_data): - """ - Returns a Bundle as a python dictionary - :return: + """Return a Bundle as a json + + Args: + additional_data: extra data to append to a bundle, as a dict + + Returns: + Bundle as json """ bundle = self._compile_bundle(**additional_data) return bundle.json(exclude_unset=True, exclude_none=True) diff --git a/src/blueink/client.py b/src/blueink/client.py index 3ad839e..ca14adb 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -1,6 +1,7 @@ import io import json from os import environ +from typing import List from munch import Munch @@ -132,12 +133,15 @@ def _prepare_files(self, file_list: [io.BufferedReader]): return files_data def create(self, data: dict, - files: [io.BufferedReader] = []) -> NormalizedResponse: - """ - Post a Bundle to the BlueInk application. - :param data: python dict, typically from BundleHelper.as_data() - :param files: list of file-like streams (optional) - :return: + files: List[io.BufferedReader] = []) -> NormalizedResponse: + """ Post a Bundle to the BlueInk application. + + Args: + data: raw data for Bundle, expressed as a python dict + files: list of file-like objects + + Returns: + NormalizedResponse object """ if not data: raise ValueError("data is required") @@ -161,11 +165,17 @@ def create(self, data: dict, def create_from_bundle_helper(self, bdl_helper: BundleHelper) -> NormalizedResponse: - """ - Post a Bundle to the BlueInk application. Convenience method as - bundle_helper has files/filenames if creating a Bundle that way - :param bdl_helper: - :return: + """ Post a Bundle to the BlueInk application. + + Provided as a convenience to simplify posting of a Bundle. This is the + recommended way to create a Bundle. + + Args: + bdl_helper: BundleHelper that has been configured as desired. + + Returns: + NormalizedResponse object + """ data = bdl_helper.as_data() files = bdl_helper.files @@ -173,17 +183,21 @@ def create_from_bundle_helper(self, def paged_list(self, page: int = 1, per_page: int = 50, related_data: bool = False, **query_params) -> PaginatedIterator: - """ - returns an iterable object such that you can do + """Returns an iterable object such that you may lazily fetch a number of + Bundles + + Typical Usage: + for page in client.bundles.paged_list(): + page.body -> munch of json - for page in client.bundles.paged_list(): - page.body -> munch of json + Args: + page: what page to start iterator at + per_page: max number of bundles per page + related_data: toggles whether or not to provide metadata along with + bundles (events, files, data) - :param page: start page (default 1) - :param per_page: max # of results per page (default 50) - :param related_data: (default false), returns events, files, data if true - :param query_params: Additional query params to be put onto the request - :return: + Returns: + PaginatedIterator object, compliant with python iterables """ iterator = PaginatedIterator(paged_api_function=self.list, page=page, @@ -194,13 +208,16 @@ def paged_list(self, page: int = 1, per_page: int = 50, def list(self, page: int = None, per_page: int = None, related_data: bool = False, **query_params) -> NormalizedResponse: - """ - Returns a list of bundles - :param page: (optional) - :param per_page: (optional) - :param related_data: (default false), returns events, files, data if true - :param query_params: Additional query params to be put onto the request - :return: + """ Returns a list of bundles + + Args: + page: which page to fetch + per_page: how many bundles to fetch + related_data: (default false), returns events, files, data if true + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.LIST) response = self._requests.get(url, @@ -231,11 +248,14 @@ def _attach_additional_data(self, bundle): def retrieve(self, bundle_id: str, related_data: bool = False) -> NormalizedResponse: - """ - Requests a single bundle - :param bundle_id: bundle slug - :param related_data: (default false), returns events, files, data if true - :return: + """Request a single bundle + + Args: + bundle_id: bundle slug + related_data: (default false), returns events, files, data if true + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.RETRIEVE, bundle_id=bundle_id) response = self._requests.get(url) @@ -247,48 +267,63 @@ def retrieve(self, bundle_id: str, return response def cancel(self, bundle_id: str) -> NormalizedResponse: - """ - Cancels a bundle given bundle slug - :param bundle_id: - :return: + """Cancel a bundle given bundle slug + + Args: + bundle_id: denotes which bundle to cancel + + Returns: + NormalizedResponse object + """ url = self.build_url(endpoints.BUNDLES.CANCEL, bundle_id=bundle_id) return self._request.put(url) def list_events(self, bundle_id: str) -> NormalizedResponse: - """ - Returns a list of events for the supplied bundle corresponding to the id - :param bundle_id: - :return: + """Return a list of events for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return events for + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.LIST_EVENTS, bundle_id=bundle_id) return self._requests.get(url) def list_files(self, bundle_id: str) -> NormalizedResponse: - """ - Returns a list of files for the supplied bundle corresponding to the id - :param bundle_id: - :return: + """Return a list of files for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return files for + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.LIST_FILES, bundle_id=bundle_id) return self._requests.get(url) def list_data(self, bundle_id: str) -> NormalizedResponse: - """ - Returns a list of data fields for the supplied bundle corresponding to - the id - :param bundle_id: - :return: + """Return a data for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return data for + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.LIST_DATA, bundle_id=bundle_id) return self._requests.get(url) class _Persons(_SubClient): def create(self, data: dict, **kwargs) -> NormalizedResponse: - """ - Creates a person. - :param data: A dictionary definition of a person - :return: + """Create a person (eg. signer) record. + + Args: + data: A dictionary definition of a person + + Returns: + NormalizedResponse object """ if "name" not in data or not data["name"]: raise ValueError("A name is required to create a Person") @@ -301,25 +336,32 @@ def create(self, data: dict, **kwargs) -> NormalizedResponse: def create_from_person_helper(self, person_helper: PersonHelper, **kwargs) -> NormalizedResponse: - """ - Creates a person. - :param person_helper: PersonHelper setup of a person - :return: + """Create a person using PersonHelper convenience object + + Args: + person_helper: PersonHelper setup of a person + + Return: + NormalizedResponse object """ return self.create(person_helper.as_dict(**kwargs)) def paged_list(self, page: int = 1, per_page: int = 50, **query_params) -> PaginatedIterator: - """ - returns an iterable object such that you can do + """Return an iterable object such that you may lazily fetch a number of + Persons (signers) + + Typical Usage: + for page in client.persons.paged_list(): + page.body -> munch of json - for page in client.persons.paged_list(): - page.body -> munch of json + Args: + page: start page (default 1) + per_page: max # of results per page (default 50) + query_params: Additional query params to be put onto the request - :param page: start page (default 1) - :param per_page: max # of results per page (default 50) - :param query_params: Additional query params to be put onto the request - :return: + Returns: + PaginatedIterator object """ iterator = PaginatedIterator(paged_api_function=self.list, @@ -330,13 +372,15 @@ def paged_list(self, page: int = 1, per_page: int = 50, def list(self, page: int = None, per_page: int = None, **query_params) -> NormalizedResponse: - """ - Returns a list of persons. Optionally supply the page number and results - per page. - :param page: - :param per_page: - :param query_params: Additional query params to be put onto the request - :return: + """Return a list of persons (signers). + + Args: + page: + per_page: + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.PERSONS.LIST) return self._requests.get(url, @@ -345,20 +389,28 @@ def list(self, page: int = None, per_page: int = None, **query_params)) def retrieve(self, person_id: str) -> NormalizedResponse: - """ - Retrieves details on a singular person - :param person_id: - :return: + """Retrieve details on a singular person + + Args: + person_id: identifying which signer to retrieve + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.PERSONS.RETRIEVE, person_id=person_id) return self._requests.get(url) def update(self, person_id: str, data: dict, partial: bool = False) -> NormalizedResponse: - """ - :param person_id: - :param data: a full dictionary representation of person - :return: + """Update a Person (signer)'s record + + Args: + person_id: + data: a dictionary representation of person's data + partial: Whether to do a partial update + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.PERSONS.UPDATE, person_id=person_id) if partial: @@ -368,6 +420,14 @@ def update(self, person_id: str, data: dict, return response def delete(self, person_id: str) -> NormalizedResponse: + """Delete a person (signer) + + Args: + person_id: + + Returns: + NormalizedResponse object + """ url = self.build_url(endpoints.PERSONS.DELETE, person_id=person_id) return self._requests.delete(url) @@ -429,16 +489,19 @@ def __init__(self, base_url, private_api_key): def paged_list(self, page: int = 1, per_page: int = 50, **query_params) -> PaginatedIterator: - """ - returns an iterable object such that you can do + """return an iterable object containing a list of templates + + Typical Usage: + for page in client.templates.paged_list(): + page.body -> munch of json - for page in client.templates.paged_list(): - page.body -> munch of json + Args: + page: start page (default 1) + per_page: max # of results per page (default 50) + query_params: Additional query params to be put onto the request - :param page: start page (default 1) - :param per_page: max # of results per page (default 50) - :param query_params: Additional query params to be put onto the request - :return: + Returns: + PaginatedIterator object """ iterator = PaginatedIterator(paged_api_function=self.list, page=page, @@ -448,13 +511,15 @@ def paged_list(self, page: int = 1, per_page: int = 50, def list(self, page: int = None, per_page: int = None, **query_params) -> NormalizedResponse: - """ - Retrieves a list of templates, optionally for a page and # of results - per page - :param page: - :param per_page: - :param query_params: Additional query params to be put onto the request - :return: + """Return a list of Templates. + + Args: + page: + per_page: + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.TEMPLATES.LIST) return self._requests.get(url, params=_build_params(page, @@ -462,10 +527,13 @@ def list(self, page: int = None, per_page: int = None, **query_params)) def retrieve(self, template_id: str) -> NormalizedResponse: - """ - Retrieves a singular template with this id - :param template_id: - :return: + """Return a singular Template by id. + + Args: + template_id: + + Returns: + NormalizedResponse object """ url = self.build_url(endpoints.TEMPLATES.RETRIEVE, template_id=template_id) return self._requests.get(url) diff --git a/src/blueink/person_helper.py b/src/blueink/person_helper.py index 25b47e0..c316015 100644 --- a/src/blueink/person_helper.py +++ b/src/blueink/person_helper.py @@ -1,3 +1,5 @@ +from typing import List + from .model.persons import ContactChannelSchema, PersonSchema @@ -6,15 +8,24 @@ def __init__( self, name: str = None, metadata: dict = {}, - phones: list = [], - emails: list = [], + phones: List[str] = [], + emails: List[str] = [], ): + """Helper class to aid building a Person. + + Once Person is ready, use as_dict() to compile python dictionary for the Person. + Args: + name: + metadata: + phones: + emails: + """ self._name = name self._metadata = metadata self._phones = phones self._emails = emails - def add_phone(self, phone: str) -> [str]: + def add_phone(self, phone: str) -> List[str]: """ Add a phone number to the current list of phone numbers @@ -27,7 +38,7 @@ def add_phone(self, phone: str) -> [str]: self._phones.append(phone) return self._phones - def set_phones(self, phones: list) -> [str]: + def set_phones(self, phones: List[str]) -> List[str]: """ Replace the current list of phone numbers with this list @@ -40,7 +51,7 @@ def set_phones(self, phones: list) -> [str]: self._phones = phones return self._phones - def get_phones(self) -> [str]: + def get_phones(self) -> List[str]: """ Returns all of the phone numbers currently stored @@ -49,7 +60,7 @@ def get_phones(self) -> [str]: """ return self._phones - def add_email(self, email: str) -> [str]: + def add_email(self, email: str) -> List[str]: """ Add an email to the current list of emails @@ -61,7 +72,7 @@ def add_email(self, email: str) -> [str]: self._emails.append(email) return self._emails - def set_emails(self, emails: list) -> [str]: + def set_emails(self, emails: List[str]) -> List[str]: """ Replace the current list of emails with this list @@ -74,7 +85,7 @@ def set_emails(self, emails: list) -> [str]: self._emails = emails return self._emails - def get_emails(self) -> [str]: + def get_emails(self) -> List[str]: """ Returns all of the emails currently stored From 3262f00a41901a380aff4bd4dfe0594856f99b13 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 27 Sep 2022 15:59:28 -0700 Subject: [PATCH 08/20] Remove examples, as they are now in own project --- examples/__init__.py | 0 examples/create_bundle_from_bytearray.py | 67 -------- examples/create_bundle_from_file.py | 71 --------- examples/create_bundle_from_template.py | 62 -------- examples/create_bundle_from_url.py | 58 ------- examples/create_bundle_from_url_in_order.py | 61 -------- examples/create_person.py | 164 -------------------- examples/fw4.pdf | Bin 187453 -> 0 bytes examples/list_bundles_etc.py | 68 -------- 9 files changed, 551 deletions(-) delete mode 100644 examples/__init__.py delete mode 100644 examples/create_bundle_from_bytearray.py delete mode 100644 examples/create_bundle_from_file.py delete mode 100644 examples/create_bundle_from_template.py delete mode 100644 examples/create_bundle_from_url.py delete mode 100644 examples/create_bundle_from_url_in_order.py delete mode 100644 examples/create_person.py delete mode 100644 examples/fw4.pdf delete mode 100644 examples/list_bundles_etc.py diff --git a/examples/__init__.py b/examples/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/examples/create_bundle_from_bytearray.py b/examples/create_bundle_from_bytearray.py deleted file mode 100644 index 9aba1b1..0000000 --- a/examples/create_bundle_from_bytearray.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import sys -from pprint import pprint - -from src.blueink import BundleHelper, Client, constants, exceptions - -fw4_path = os.path.dirname(os.path.realpath(__file__)) + "/fw4.pdf" - -pdf_bytearray = bytearray() -with open(fw4_path, 'rb') as pdf_file: - byte = pdf_file.read(1) - while byte: - pdf_bytearray += byte - byte = pdf_file.read(1) - -print("\n*********************") -print("Bundle Creation via file upload") -bh = BundleHelper(label="label2022b", - email_subject="Subject", - email_message="MessageText", - is_test=True) - -bh.add_cc("Homer.Simpson@example.com") -doc_key = bh.add_document_by_bytearray(pdf_bytearray, "fw4.pdf", "application/pdf") -signer1 = bh.add_signer(name="Homer Simpson", - email="Homer.Simpson@example.com", - phone="505-555-5555", - deliver_via=constants.DELIVER_VIA.EMAIL) -signer2 = bh.add_signer(name="Marge Simpson", - email="Marge.Simpson@example.com", - phone="505-555-5556", - deliver_via=constants.DELIVER_VIA.EMAIL) - -field1 = bh.add_field(doc_key, - x=1, y=15, w=60, h=20, p=3, - kind=constants.FIELD_KIND.INPUT, - label="label1", - editors=[signer1, signer2]) - -field2 = bh.add_field(doc_key, - x=1, y=15, w=68, h=30, p=4, - kind=constants.FIELD_KIND.ESIGNATURE, - label="label2", - editors=[signer1]) - -client = Client() - -try: - response = client.bundles.create_from_bundle_helper(bh) -except exceptions.HTTPError as e: - print(f"Request failed: {e}") - print("== Error Details: ==") - try: - pprint(e.response.json()) - except exceptions.JSONDecodeError: - chars = 10000 - print(e.response.text[:chars]) - if len(e.response.text) > chars: - print(f"\n== [TRUNCATED {len(e.response.text) - chars} characters] ==") - sys.exit(1) -except exceptions.RequestException as e: - print(f"Request failed: {e}") - sys.exit(1) - - -print("== Bundle Created ==") -pprint(response.data) diff --git a/examples/create_bundle_from_file.py b/examples/create_bundle_from_file.py deleted file mode 100644 index b699c22..0000000 --- a/examples/create_bundle_from_file.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -import sys -from pprint import pprint - -from src.blueink import BundleHelper, Client, exceptions -from src.blueink.constants import DELIVER_VIA, FIELD_KIND - -client = Client() - -fw4_path = os.path.dirname(os.path.realpath(__file__)) + "/fw4.pdf" - -print("\n*********************") -print("Creating Bundle with Uploaded Files") -bh = BundleHelper(label="label2022", - email_subject="Subject", - email_message="MessageText", - is_test=True) - -bh.add_cc("Homer.Simpson@example.com") -doc1 = bh.add_document_by_path(fw4_path, "application/pdf") - -signer1 = bh.add_signer(name="Homer Simpson", - email="Homer.Simpson@example.com", - phone="505-555-5555", - deliver_via=DELIVER_VIA.EMAIL) - -signer2 = bh.add_signer(name="Marge Simpson", - email="Marge.Simpson@example.com", - phone="505-555-5556", - deliver_via=DELIVER_VIA.EMAIL) - -field1 = bh.add_field(doc1, - x=1, y=15, w=60, h=20, p=3, - kind=FIELD_KIND.INPUT, - label="label1", - editors=[signer1, signer2]) - -field2 = bh.add_field(doc1, - x=1, y=15, w=68, h=30, p=4, - kind=FIELD_KIND.ESIGNATURE, - label="label2", - editors=[signer1]) - -# mime_type is optional -doc2 = bh.add_document_by_path(fw4_path) -field3 = bh.add_field(doc2, - x=1, y=15, w=60, h=20, p=3, - kind=FIELD_KIND.INPUT, - label="label3", - editors=[signer1, signer2]) -client.bundles.create(data={}, files=12) -try: - response = client.bundles.create_from_bundle_helper(bh) -except exceptions.HTTPError as e: - print(f"Request failed: {e}") - print("== Error Details: ==") - try: - pprint(e.response.json()) - except exceptions.JSONDecodeError: - chars = 10000 - print(e.response.text[:chars]) - if len(e.response.text) > chars: - print(f"\n== [TRUNCATED {len(e.response.text) - chars} characters] ==") - sys.exit(1) -except exceptions.RequestException as e: - print(f"Request failed: {e}") - sys.exit(1) - - -print("== Bundle Created ==") -pprint(response.data) diff --git a/examples/create_bundle_from_template.py b/examples/create_bundle_from_template.py deleted file mode 100644 index 1bbb0da..0000000 --- a/examples/create_bundle_from_template.py +++ /dev/null @@ -1,62 +0,0 @@ -import sys -from pprint import pprint - -from src.blueink import Client, constants, exceptions, BundleHelper - -client = Client() - -# Fetch templates -response = client.templates.list() -templates = response.data - -print("\n*********************") -print("Bundle Creation with a Template") - -print("== Available Templates ==") -for t in templates: - print( - f'{t.id} -- "{t.name or "[No name]"}" -- ' - f"{len(t.roles)} signers, {len(t.fields)} fields" - ) - -template_id = input("\nPlease enter template ID: ") -# This will fail with an exception if the template ID does not exist -response = client.templates.retrieve(template_id) -template = response.data - -bh = BundleHelper(label="Example from Template", - email_subject="Here is your example Bundle", - email_message="Please sign. This bundle was created from a template", - is_test=True) - -doc_key = bh.add_document_template(template_id) - -signer_key = bh.add_signer(name="Homer Simpson", - email="Homer.Simpson@example.com", - phone="505-555-5555", - deliver_via=constants.DELIVER_VIA.EMAIL) - -bh.assign_role(doc_key, signer_key, template['roles'][0]) - -# FIXME - collect some initial data for fields - -try: - response = client.bundles.create_from_bundle_helper(bh) -except exceptions.HTTPError as e: - print(f"Request failed: {e}") - print("== Error Details: ==") - try: - pprint(e.response.json()) - except exceptions.JSONDecodeError: - chars = 10000 - print(e.response.text[:chars]) - if len(e.response.text) > chars: - print(f"\n== [TRUNCATED {len(e.response.text) - chars} characters] ==") - sys.exit(1) -except exceptions.RequestException as e: - print(f"Request failed: {e}") - sys.exit(1) - - -print("== Bundle Created ==") -pprint(response.data) diff --git a/examples/create_bundle_from_url.py b/examples/create_bundle_from_url.py deleted file mode 100644 index 964b01a..0000000 --- a/examples/create_bundle_from_url.py +++ /dev/null @@ -1,58 +0,0 @@ -import sys -from pprint import pprint - -from src.blueink import Client, constants, exceptions, BundleHelper - -print("\n*********************") -print("Bundle Creation via URL") -bh = BundleHelper(label="label2022", - email_subject="Subject", - email_message="MessageText", - is_test=True) -bh.add_cc("Homer.Simpson@example.com") - -doc_key = bh.add_document_by_url("https://www.irs.gov/pub/irs-pdf/fw9.pdf") - -signer1 = bh.add_signer(name="Homer Simpson", - email="Homer.Simpson@example.com", - phone="505-555-5555", - deliver_via=constants.DELIVER_VIA.EMAIL) - -signer2 = bh.add_signer(name="Marge Simpson", - email="Marge.Simpson@example.com", - phone="505-555-5556", - deliver_via=constants.DELIVER_VIA.EMAIL) - -field1 = bh.add_field(doc_key, - x=1, y=15, w=60, h=20, p=3, - kind=constants.FIELD_KIND.INPUT, - label="label1", - editors=[signer1, signer2]) -field2 = bh.add_field(doc_key, - x=1, y=15, w=68, h=30, p=4, - kind=constants.FIELD_KIND.ESIGNATURE, - label="label2", - editors=[signer1]) - -client = Client() - -try: - response = client.bundles.create_from_bundle_helper(bh) -except exceptions.HTTPError as e: - print(f"Request failed: {e}") - print("== Error Details: ==") - try: - pprint(e.response.json()) - except exceptions.JSONDecodeError: - chars = 10000 - print(e.response.text[:chars]) - if len(e.response.text) > chars: - print(f"\n== [TRUNCATED {len(e.response.text) - chars} characters] ==") - sys.exit(1) -except exceptions.RequestException as e: - print(f"Request failed: {e}") - sys.exit(1) - - -print("== Bundle Created ==") -pprint(response.data) diff --git a/examples/create_bundle_from_url_in_order.py b/examples/create_bundle_from_url_in_order.py deleted file mode 100644 index e6f6253..0000000 --- a/examples/create_bundle_from_url_in_order.py +++ /dev/null @@ -1,61 +0,0 @@ -import sys -from pprint import pprint - -from src.blueink import BundleHelper, Client, constants, exceptions - -print("\n*********************") -print("Bundle Creation via URL") -bh = BundleHelper(label="label2022", - email_subject="Subject", - email_message="MessageText", - is_test=True, - in_order=True) - -bh.add_cc("Homer.Simpson@example.com") - -doc1 = bh.add_document_by_url("https://www.irs.gov/pub/irs-pdf/fw9.pdf") - -signer1 = bh.add_signer(name="Homer Simpson", - email="Homer.Simpson@example.com", - phone="505-555-5555", - deliver_via=constants.DELIVER_VIA.EMAIL) - -signer2 = bh.add_signer(name="Marge Simpson", - email="Marge.Simpson@example.com", - phone="505-555-5556", - deliver_via=constants.DELIVER_VIA.EMAIL) - -field1 = bh.add_field(doc1, - x=1, y=15, w=60, h=20, p=3, - kind=constants.FIELD_KIND.INPUT, - label="label1", - editors=[signer1, signer2]) - -field2 = bh.add_field(doc1, - x=1, y=15, w=68, h=30, p=4, - kind=constants.FIELD_KIND.ESIGNATURE, - label="label2", - editors=[signer1]) - -client = Client() - -try: - response = client.bundles.create_from_bundle_helper(bh) -except exceptions.HTTPError as e: - print(f"Request failed: {e}") - print("== Error Details: ==") - try: - pprint(e.response.json()) - except exceptions.JSONDecodeError: - chars = 10000 - print(e.response.text[:chars]) - if len(e.response.text) > chars: - print(f"\n== [TRUNCATED {len(e.response.text) - chars} characters] ==") - sys.exit(1) -except exceptions.RequestException as e: - print(f"Request failed: {e}") - sys.exit(1) - - -print("== Bundle Created ==") -pprint(response.data) diff --git a/examples/create_person.py b/examples/create_person.py deleted file mode 100644 index 4892cfa..0000000 --- a/examples/create_person.py +++ /dev/null @@ -1,164 +0,0 @@ -from copy import deepcopy -from requests.exceptions import HTTPError -from pprint import pprint - -from src.blueink.client import Client -from src.blueink.person_helper import PersonHelper - -client = Client() - -ph = PersonHelper() - -# Try and create a person without setting anything up -# this is expected to error -try: - result = client.persons.create_from_person_helper(ph) -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - -# Make up some metadata to add to the person -metadata = {} -metadata["number"] = 1 -metadata["string"] = "stringy" -metadata["dict"] = {} -metadata["dict"]["number"] = 2 -metadata["list"] = [] -metadata["list"].append(3) - -# Set the metadata of the person -ph.set_metadata(metadata) - -# Set the persons name -ph.set_name("New Name") - -# Add email contacts for the person -ph.add_email("test@email.com") -ph.add_email("test2@email.com") -ph.add_email("test3@email.com") - -# Get all of the emails for the person -all_current_emails = ph.get_emails() - -# Remove an email from the list -all_current_emails.remove("test@email.com") - -# Overwrite the existing email list with this new list -# Effectively removing test@email.com list -ph.set_emails(all_current_emails) - -# Add phone number contact for the person -ph.add_phone("5055551212") -ph.add_phone("5055551213") -ph.add_phone("5055551214") - -# Get all of the phone numbers for the person -all_current_phones = ph.get_phones() - -# Remove a phone number from the list -all_current_phones.pop() - -# Overwrite the existing email list with this new list -# Effectively removing last phone number -ph.set_phones(all_current_phones) - -# Create the person and check the result -try: - result = client.persons.create_from_person_helper(ph) - pprint(f"Result Create: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - -# Change the persons name and call update -result.data.name = "Second Name" - -""" - The channels in the response include both email and phone - If we want to update with this data we need to remove the ones - that are blank -""" -new_channels = [] -for channel in result.data.channels: - new_channel = deepcopy(channel) - for key, value in channel.items(): - # Remove the key/value pairs that are not valid - if not value: - new_channel.pop(key) - new_channels.append(new_channel) - -# Set the channels to the recreated channels without the invalid keys -result.data.channels = new_channels - -try: - result = client.persons.update(result.data.id, result.data) - pprint(f"Result Update: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - - -# Retrieve the person -try: - result = client.persons.retrieve(result.data.id) - pprint(f"Result Retrieve: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - - -# Perform a partial update to change the name again -third_name = {"name": "Third Name"} -try: - result = client.persons.update(result.data.id, third_name, partial=True) - pprint(f"Result Partial Update: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - -# Delete the person from your account and check the result -try: - result = client.persons.delete(result.data.id) - pprint(f"Result Delete: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) - -""" -Create a person and pass extra arguments -if using a older version of sdk that doesn't -support certain new API parameters you can add them -this way in the person helper -If calling another method that just takes a dict -add them to the dict directly -""" -try: - ph = PersonHelper(name="New Person") - result = client.persons.create_from_person_helper(ph, hidden_person=True) - pprint(f"Result Create With Extra Args: {result.status}: {result.data}") - result = client.persons.delete(result.data.id) - pprint(f"Result Delete: {result.status}: {result.data}") -except HTTPError as e: - print(e) - pprint(e.response.text) -except Exception as e: - print("Error:") - print(e) diff --git a/examples/fw4.pdf b/examples/fw4.pdf deleted file mode 100644 index 35fa336d6760f0b21508e3eed65a3156dd3a2af7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 187453 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

5d` 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 diff --git a/examples/list_bundles_etc.py b/examples/list_bundles_etc.py deleted file mode 100644 index 47c108c..0000000 --- a/examples/list_bundles_etc.py +++ /dev/null @@ -1,68 +0,0 @@ -from src.blueink import Client, constants - -client = Client() - - -print("\n*********************\nList Bundles") -response = client.bundles.list() -print(f"Retrieved {len(response.data)} Bundles") -print(f"Here are the first 3:") -for bundle in response.data[:3]: - print(f"{bundle.id} {bundle.status}") - -print("\n*********************\nList Bundles - filtering by status") -response = client.bundles.list(status=constants.BUNDLE_STATUS.COMPLETE) -print(f"Retrieved {len(response.data)} Complete Bundles") -print(f"Here are the first 10:") -for bundle in response.data[:10]: - print(f"{bundle.id} {bundle.status}") - -print("\n*********************\nList Bundles - filtering by multiple statuses") -statuses = ",".join([ - constants.BUNDLE_STATUS.COMPLETE, - constants.BUNDLE_STATUS.STARTED -]) -response = client.bundles.list(status__in=statuses) -print(f"Retrieved {len(response.data)} Complete or Started Bundles") -print(f"Here are the first 10:") -for bundle in response.data[:10]: - print(f"{bundle.id} {bundle.status}") - -print("\n*********************\nList Bundles - search for an email address") -response = client.bundles.list(search="example.com") -print(f"Retrieved {len(response.data)} Matching Bundles") -print(f"Here are the first 10:") -for bundle in response.data[:10]: - print(f"{bundle.id} {bundle.status}") - - -# These test pagination. Collects IDs -print("\n*********************\nPaged Bundle Listing") -ids = [] -page = 1 -iterator = client.bundles.paged_list(page=1, per_page=5) -for paged_response in iterator: - print(f"Page {page}, {len(paged_response.data)} Bundles") - for bundle in paged_response.data: - ids.append(bundle.id) - page += 1 -print(f"Found {len(ids)} bundle ids!") -print("") - -if len(ids) > 0: - print(f"---> Single bundle retrieval, id {ids[0]}") - response = client.bundles.retrieve(ids[0], related_data=True) - single_bundle = response.data - print(f"{single_bundle.id}: {single_bundle.status}") - -print("\n*********************\nPaged Persons Listing") -page = 1 -for paged_response in client.persons.paged_list(page=1, per_page=2): - print(f"Page {page}, {len(paged_response.data)} Persons") - page += 1 - -print("\n*********************\nPaged Templates Listing") -page = 1 -for paged_response in client.templates.paged_list(page=1, per_page=2): - print(f"Page {page}, {len(paged_response.data)} Templates") - page += 1 From 0fe343a59229d9bea4c39ebc72dc47fb77b8e563 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Thu, 29 Sep 2022 19:35:04 -0700 Subject: [PATCH 09/20] raise_exceptions flag on Client, default True to aid testing / give users greater flexibility in their own code. --- src/blueink/bundle_helper.py | 68 ++++++++++----- src/blueink/client.py | 41 +++++---- src/blueink/request_helper.py | 10 ++- src/blueink/tests/test_bundle_helper.py | 108 +++++++++++++++++++++++- src/blueink/tests/w4.pdf | Bin 0 -> 187453 bytes src/blueink/utils/testcase.py | 10 ++- 6 files changed, 192 insertions(+), 45 deletions(-) create mode 100644 src/blueink/tests/w4.pdf diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index 27135cf..9c6095e 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -1,4 +1,6 @@ import io +from os.path import basename +from base64 import b64encode from typing import List from .model.bundles import ( @@ -67,37 +69,57 @@ def add_document_by_url(self, url: str, **additional_data) -> str: self._documents[document.key] = document return document.key - def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additional_data) -> str: - """ - Add a document via url, with unique key. - :param file_name: - :param file: - :param additional_data: Optional and will append any additional kwargs to the json of the document - :return: - """ + # DEPRECATED, FILE HANDLE IS NOT CLOSED + # def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additional_data) -> str: + # """ + # Add a document via url, with unique key. + # :param file_name: + # :param file: + # :param additional_data: Optional and will append any additional kwargs to the json of the document + # :return: + # """ + # + # file_index = len(self.files) + # + # if type(file) == io.BufferedReader and file.readable(): + # self.files.append({'file': file, "filename": file_name}) + # else: + # raise ValueError(f"File unreadable.") + # + # document = Document.create(file_index=file_index, **additional_data) + # self._documents[document.key] = document + # return document.key + + # # DEPRECATED, FILE HANDLE IS NOT CLOSED + # def add_document_by_path(self, file_path: str, **additional_data) -> str: + # """ + # Add a document via url, returns generated unique key. + # :param file_path: + # :param additional_data: Optional and will append any additional kwargs to the json of the document + # :return: Document instance + # """ + # + # file = open(file_path, 'rb') + # return self.add_document_by_file(file, file.name, **additional_data) + def add_document_by_path(self, file_path: str, **additional_data) -> str: + filename = basename(file_path) + + file = open(file_path, 'rb') + b64str = b64encode(file.read()) + file.close() + return self.add_document_by_b64(filename, b64str, **additional_data) + + def add_document_by_b64(self, filename:str, b64str:str, **additional_data): file_index = len(self.files) - if type(file) == io.BufferedReader and file.readable(): - self.files.append({'file': file, "filename": file_name}) - else: - raise ValueError(f"File unreadable.") + self.files.append({'file_b64': b64str, "filename": filename}) document = Document.create(file_index=file_index, **additional_data) + print(f"doc -- {document.key}") self._documents[document.key] = document return document.key - def add_document_by_path(self, file_path: str, **additional_data) -> str: - """ - Add a document via url, returns generated unique key. - :param file_path: - :param additional_data: Optional and will append any additional kwargs to the json of the document - :return: Document instance - """ - - file = open(file_path, 'rb') - return self.add_document_by_file(file, file.name, **additional_data) - def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, **additional_data) -> str: ''' diff --git a/src/blueink/client.py b/src/blueink/client.py index ca14adb..774d643 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -30,7 +30,8 @@ def _build_params(page: int = None, per_page: int = None, **query_params): class Client: - def __init__(self, private_api_key: str = None, base_url: str = None): + def __init__(self, private_api_key: str = None, base_url: str = None, + raise_exceptions: bool = True): """Initialize a Client instance to access the Blueink eSignature API Args: @@ -40,6 +41,8 @@ def __init__(self, private_api_key: str = None, base_url: str = None): base_url: override the API base URL. If not supplied, we check the environment variable BLUEINK_API_URL. If that is empty, the default value of "https://api.blueink.com/api/v2" is used. + raise_exceptions (Default True): raise HTTPError if code != 200. Otherwise + return as NormalizedResponse objects. Returns: A Client instance @@ -64,7 +67,7 @@ def __init__(self, private_api_key: str = None, base_url: str = None): if not base_url: base_url = DEFAULT_BASE_URL - self._request_helper = RequestHelper(private_api_key) + self._request_helper = RequestHelper(private_api_key, raise_exceptions) self.bundles = self._Bundles(base_url, self._request_helper) self.persons = self._Persons(base_url, self._request_helper) @@ -113,22 +116,26 @@ def _prepare_files(self, file_list: [io.BufferedReader]): files_data = [] if file_list: for idx, file_dict in enumerate(file_list): - try: + if "file" in file_dict: + print("Actual File") fh = file_dict["file"] - except KeyError: - raise ValueError("Each file dict must have a 'file' key that" - " is a file-like object") - - if not isinstance(fh, io.BufferedReader): - raise ValueError( - f"Bad type for file {idx}. Expected an io.BufferedReader" - f" (e.g. an open file handle)" - ) - - field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), - fh, - file_dict.get("content_type")))) + if not isinstance(fh, io.BufferedReader): + raise ValueError( + f"Bad type for file {idx}. Expected an io.BufferedReader" + f" (e.g. an open file handle)" + ) + field_name = f"files[{idx}]" + files_data.append((field_name, (file_dict.get("filename"), + fh, + file_dict.get("content_type")))) + elif "file_b64" in file_dict: + print("B64 represented File") + + b64 = file_dict["file_b64"] + field_name = f"files[{idx}]" + files_data.append((field_name, (file_dict.get("filename"), + b64, + file_dict.get("content_type")))) return files_data diff --git a/src/blueink/request_helper.py b/src/blueink/request_helper.py index ea01d1c..a0866ce 100644 --- a/src/blueink/request_helper.py +++ b/src/blueink/request_helper.py @@ -1,6 +1,7 @@ import requests from munch import munchify +from requests import Request, Session from .constants import BLUEINK_PAGINATION_HEADER @@ -55,8 +56,9 @@ def __init__(self, response: requests.Response): class RequestHelper: - def __init__(self, private_api_key): + def __init__(self, private_api_key, raise_exceptions=False): self._private_api_key = private_api_key + self._raise_exceptions = raise_exceptions def delete(self, url, **kwargs): return self._make_request("delete", url, **kwargs) @@ -97,6 +99,8 @@ def _build_headers(self, content_type=None, more_headers=None): def _make_request( self, method, url, data=None, json=None, files=None, params=None, headers=None, content_type=None ): + + response = requests.request( method, url, @@ -106,5 +110,7 @@ def _make_request( headers=self._build_headers(content_type=content_type, more_headers=headers), files=files, ) - response.raise_for_status() + + if self._raise_exceptions: + response.raise_for_status() return NormalizedResponse(response) diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py index 8af59dd..5f3a02f 100644 --- a/src/blueink/tests/test_bundle_helper.py +++ b/src/blueink/tests/test_bundle_helper.py @@ -1,11 +1,21 @@ import copy +from base64 import b64encode +from os.path import basename -from src.blueink import BundleHelper +from munch import Munch + +from src.blueink import BundleHelper, Client from src.blueink.utils.testcase import TestCase class TestBundleHelper(TestCase): + DOCUMENT_CREATE_BY_METHOD = Munch( + url="URL", + pth="PATH", + b64="BASE64", + ) + BUNDLE_INIT_DATA = { "label": "TEST_BUNDLE", "email_subject": "EMAIL_SUBJECT", @@ -62,6 +72,9 @@ class TestBundleHelper(TestCase): DOCUMENT_01_URL = "https://www.example.com/example1.pdf" DOCUMENT_02_URL = "https://www.example.com/example2.pdf" + REAL_DOCUMENT_PATH = "w4.pdf" + REAL_DOCUMENT_URL = "https://www.irs.gov/pub/irs-pdf/fw4.pdf" + def test_base_bundle(self): """Test creating a Bundle with no documents, no signers -- just the base Bundle""" input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) @@ -91,6 +104,26 @@ def test_adding_document_via_url(self): self.assert_equal(compiled_bundle["documents"][0]["file_url"], url01) self.assert_equal(compiled_bundle["documents"][1]["file_url"], url02) + def test_adding_document_via_b64(self): + input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) + url01 = self.DOCUMENT_01_URL + url02 = self.DOCUMENT_02_URL + + bh = BundleHelper(**input_data) + bh.add_document_by_url(url01) + bh.add_document_by_url(url02) + + compiled_bundle = bh.as_data() + + self.assert_in("documents", compiled_bundle) + self.assert_len(compiled_bundle["documents"], 2) + + self.assert_in("file_url", compiled_bundle["documents"][0]) + self.assert_in("file_url", compiled_bundle["documents"][1]) + + self.assert_equal(compiled_bundle["documents"][0]["file_url"], url01) + self.assert_equal(compiled_bundle["documents"][1]["file_url"], url02) + def test_adding_fields(self): input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) url01 = self.DOCUMENT_01_URL @@ -156,3 +189,76 @@ def test_adding_fields(self): self.assert_equal(compiled_bundle["packets"][0][k], v) for k, v in signer02_data.items(): self.assert_equal(compiled_bundle["packets"][1][k], v) + + def _construct_complete_bundlehelper(self, file_location, method:str) -> BundleHelper: + input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) + signer01_data = copy.deepcopy(self.SIGNER_01_DATA) + signer02_data = copy.deepcopy(self.SIGNER_02_DATA) + field01_data = copy.deepcopy(self.FIELD_01_DATA) + field02_data = copy.deepcopy(self.FIELD_02_DATA) + + bh = BundleHelper(**input_data) + if method == self.DOCUMENT_CREATE_BY_METHOD.url: + doc01_key = bh.add_document_by_url(file_location) + elif method == self.DOCUMENT_CREATE_BY_METHOD.pth: + doc01_key = bh.add_document_by_path(file_location) + elif method == self.DOCUMENT_CREATE_BY_METHOD.b64: + file = open(file_location, 'rb') + filename = basename(file_location) + b64str = b64encode(file.read()) + doc01_key = bh.add_document_by_b64(filename, b64str) + else: + raise RuntimeError("Invalid Document Add Method") + + self.assert_not_none(doc01_key) + + signer01_key = bh.add_signer(**signer01_data) + signer02_key = bh.add_signer(**signer02_data) + + field01_data["document_key"] = doc01_key + field01_data["editors"].append(signer01_key) + field01_data["editors"].append(signer02_key) + bh.add_field(**field01_data) + + field02_data["document_key"] = doc01_key + field02_data["editors"].append(signer01_key) + bh.add_field(**field02_data) + + return bh + + def test_roundtrip_url(self): + bh = self._construct_complete_bundlehelper( + file_location=self.REAL_DOCUMENT_URL, + method=self.DOCUMENT_CREATE_BY_METHOD.url + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + + self.assert_equal(resp.status, 200, resp.request.url) + + def test_roundtrip_b64(self): + bh = self._construct_complete_bundlehelper( + file_location=self.REAL_DOCUMENT_PATH, + method=self.DOCUMENT_CREATE_BY_METHOD.b64 + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + + self.assert_equal(resp.status, 200) + + def test_roundtrip_path(self): + bh = self._construct_complete_bundlehelper( + file_location=self.REAL_DOCUMENT_PATH, + method=self.DOCUMENT_CREATE_BY_METHOD.pth + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + + self.assert_equal(resp.status, 200) + + + + diff --git a/src/blueink/tests/w4.pdf b/src/blueink/tests/w4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..35fa336d6760f0b21508e3eed65a3156dd3a2af7 GIT binary patch literal 187453 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

5d` z@c3#4Y|!HF=2Fwv5ORCf+ezKB;d-~VG7czvLW}25^NT&^zO9iqM-qM&5k#coNi71phLw~g-uDU2gL_=fX!JVBanj|M4^>13kI#Q z2lmURSoWV%tmz-85SU5FrhQV~QMyBt3^^@XVkBw-hfh#-l<0PZN(5UEUWxVcao%Feks;6&BWuyIB+uK;*#+ zd}EBMXUa~0Bs*n4n7yGl!cJJRpfa6f+HCvDJ3!TbxH$h2Ut3R8BH2R#zQvA9m}fZy5)S|`QO=-|HTPpK3={*A{aJqw*M5ur07Lp z%U}Z`jNYzP<(sYIFQTwwUCFXk*0vNB3<7M(drF#Iv3^-jR+|UZ)gX2@5*RPaav`7H zBDLFh8bh}9Z`73XU&~X=e@LaPLtt{qMi7!aj*%afqqnuCCg>iDQq8Y#aIoTp#7)S@ zd=e&)Nn34D9Zl&1UBRSUAGDU6a}D1jDP@s`CnJ?4*)1JJlf(Uj zF%COw9jZZ)#jPBo;z<#)qcR+36=k^&`rNxfueQ3c=(*a}#RsA?w;PYAA%#+AF{knD z7SY&_>6Bn!yiIT{Q3c0%H;U&@s)7*UJMmOGwevgVzQE?nf^bVg%DPVA+3S~trJi5p zv;tJLRd?Etg5D(HkB|jwM{B>xG#&n!_0&Brz`Jh79kclBCEKY+iTt^SpI<0{0#JOyP(o9bLvbWEOC@&_Q1%0wi zi`Rth8f)0g_;S(HBGpFN%erHFxBEC`|Ywt?0X)E7_25gp|_pk+O z3wFogTy^g06ZaDc`Rac5MCP-TWYC?`rhx&-!@$olIh(PKz4G+>rXFNZ@k@H=%VjMX4?uhxJ2&F?pGFPCmReJuTR#m z<5fKF@9;Kfq=^?pDTy51DbZ}Y=!qPB=kyNm6~(pC?}j>AIQRSODrm3J?mGM3EHvyO z`(>>^k53`}9DW?6Wto|RemC8*Jl0(GJ_3*|J%q+KRG!@NRQ=jqXsXiun3>|%!FFT8 zpsTaaxQl?N-nfl`r_T7E>uGC29n%uG^-Us6)7gBPV#~p5{*8mww)*XpTrxOOjV}ua@;4Pf%o1M8pU2fl&olT?4Os5v>u|LkU_?NKC?H$kbYElr2;;oI+{ zva;XA3zs(2#r_(tL&V!Kh@^I`= zQh@RPN4Jlb8!=m>ucKu;eqUMtQOpWir%13L%02#_Lz;T#Q`yI={;$dZMP$1%x$HfP zvC;ORAxD&j0lok5i}!c(1K+0Q24XLI$8n&i#3QV`zcf5Z^!|Qs{Q!Z|PUBaw@U=y;bzXog269weh964JHzE_zhksl~p7xg! z$HyBZSu;;WJ2w7D(mp;Ci1Oq>SQ@4k2ZLfIeCoL?yS1FE_ek!X@uy+ffF z8S6oLx;evb_u&We{AOgmkoy9upe;IS9em7uVDJ6?@>r5$s&EDJu4nJ|AdR9+>)YA9 zq9Ht{G|scD9JBb%n`tROAk@ZJScLxF7WTh5LC*(#ZO!jr(8tEg#{D0j!f7d56U$)S zGPqQu_q+O>;^7BAhh3xUk{qV)NyeF@gYn>zJ$ZgFT<%%T6o@fFO$1v7Uvxgy?5VeC zSAZ0jZ~n4N71``;DS;OUozMY7>Wqa8%M|x<|8cw{R8*G1>yxQ5DZUxhn@O!dvk>RY zpiqJ~5yEGBRD`P(lD%P-UVh)ts3d_r;)Ewv%tBRld zC#(}9ML9HvGgaj42T3!PW&a=c-UObiuI(RB6PY!K5JHJFPckHPnL-pv`|Pt1GG-nt z4Tz!=%9Nr^l|&PwQfVNBB+0F!jD=`0^uM<1uI{Jjxu5rW-~Z?T|NMS$r?c&|_g-sV zYpv`0Uf=6l`|MNeAmJ4?SARAre)E=GcMlr>OM-^6vwM@WGMUY5ijRyyR)`R zZ#ey|dH(Jr^3(FH0veD5QAhKytI0AV+3mLpGVJA@=jvBPhKox&cnvNem^ULZo|(35 zkCgT_>Dcsj&5dO0R$n1?35?}Xd*6akWm{abp+Jmw%rSg;xyYA!8OtAp9?KOjmkF(g zex47V<`Tfx*LxEAbgaN?!>N%M3)4;|JiWe0{6p9>+G1a;4DR{oc{a(62Wb48%hhJD zD&N%Aw2XH|w@#F_)ogZu{&MESX__q|AKQm}f@i1Qmos{iNjDN#Y&5#S%rUlzi5rxU zXWmoDxnrbeq@o*C(z3bN-Ce8f%F40v4$ol!k>RnLit5DJuKEveFDI@X`lDiGEa=0h z#J=k4#{L(Tc|CdK9VHcw6aAm1%Ri5FzhGZ>82tFbKf?P{Rf^`A@5i8$R);CUpPYw! zxSUUBwE8aEXxGw~uBAO)OCNMC9qL-z_x^BDkkKct=Q9)&$54N7=AngJj{^$@IUfi+ zwx1Muni11J^z0A^nO&n$%`#0gNm`piO{O+6o$1c*+a9?-`p~%7u+XUOEegr`BF_~0 zIQealeD>U0e4}1$w!dyt%)z5_k8hxh)xT|CeiD(QC;J4Q6zF~#gA^Jm#>8>sOlK=r zE2L7PcD0RAyU%^R;+$JXg+^K83SF>!+sNB>t%hmP!j=~?wGjm>{d}PdTi7uhcw>Fv zec!y+3TQy%G$%-3>K-^q`R`vI*YH9h-G@gXgLV18@uwPvBCQ*a`$1E#r{)V5IhY4$T9AmnUD5FXU7+OaoAW_asTg- z=0CVupT#8ogfxFgmaS`|lMMvNZG4P{&pPUBac8cUF<)b7CtlpLR)-JtMo6M0fDtkA zA^z35kSEi9a&-O}x{=WFw(9`*`Ntf#qmp@n0P(3~gzc?eJn>mG=GeN4@1JV&WEcO2 zh#5lXZ3INK56zg)S?YQIap6rJ0g*g)H9p%8QhMQn6ymM!s;TwIkJ+9vHtU*pHt6B= zq}NBn?s^vsa%-IRy3#D4YN}^>6b6_!ZFU{7@)@`orMF)0*nFDP=L>waN2#@u=`4wP zj}7e_4b#QM1G~hX<-~=YjBm?!Y_XGH-y%bf$(1A@(7BiFzxJuI#BFA-R~0v2dD{G< zpknHotk-H==F|wSYC#Vu$ZXu*z@HvqU^^vvC`GD5re?{T=K-c7Cw*#2PD@djlUY>P z8T@i8ZgsUzpY!J!I*4~&t=lK0EL!NhPsq^KY+ja_U7}Nj{h75^F{*b?D;j5rM_kg| zUYe=v)4d=b_0zgDb<^qfr}>{5du6H+KYIt=bv>1<5_wD`D{A&Y%9`9@gNF5+>b<9B zTGg1;3SCH1-6X!zRDdr?y7=~LS7r070teGb@v8dkQuU52>R7q@sZD8z31&u#S+^coUdkVE@Z5G^>r!RK-n-qF zX*OBy1LayfKJ5}nPz0QKEeFCPk9Gx`A1yMMnya9a!n@ZfI#ZiwY#W4sloR2POE|`x zT6yU(zA2UM4s?B>d@@`%$W-jX9|eL^-!=n%B2tnHCdd76kdLd)j4-M<-mPSuv=*wU zra={*2~aJi6IwEcmZ;wN@x#2gpWM+9;n(xrEH*dlk5bup>X$m^{-_f6+9v*}tH>M> zP-Uj6>5Iha-`jmNv*0zK|I;Y@O#jC$jzto6tE>aC|X3iQ)U)T~km~KA3W8RVz zeD{@CuNFIEd5avdVt3`_#%7WF1U%GrK>bPe@1W*C_)Y+e`RB?aiAesNuLk#8--wa~ zsF}C8Z#M<*3eKI1^6lA@vgc@T=WMiU1?9Qm8ONLbpAVMDT2*Wney~ebsxXtVTffyT ze|=DE(1!KtQ>@)~DoH7ct`|`w`iji-G!O_1yTAS3MB_OrQA6JV$AdSdteh?e%GBO@ zmmbC+m|h!g`Ciz*)JvLJs~kHuBd`Pc!XMOyh;j&BzBxfT$mMqfnk>zudin}zr{HO< z^Gv{TlaF%*FG(+(k!?847k0i{a$|mI=fcQT!!s&#HXkj$f^*rI`wwjsTpha~%`QY{sJ@c)qa^lAKH2G5&hDf5y{=z0HpcSxPbF6>Ip^LN(uTl4(Xft$tt^tc1Q z9g_33J3~$-rNoRsRk5yTZKdtYu{k$YR&^yQY@gIyN=yu;$v%w2NRRJkNo=lYJ|shZ zbWF}kof~uF(<&8m9X*L)o@3T4C9GttHgDOY2@Yws()H+VN;ypiRI1!e0E; z3w2A0D2oAAlS^w}*wcA3Jn1Xh9i5UU+Ob2lx;F(5aoL|2)&{ZR=Pa0GbGeCkbNS|Lt$+$GB_f1=kuM>vXRQt)*FJ|_86P|mGS)u+Imk}q$|i?a zSFQ0&WpGa!L+h=(-)N72MC-&vr$hN?zst?8A1c)*zO=SSX(Ct0M&Av)Uu)aY-BH>2 zHgDsr>SPatPfa5uo(klUs-c$yFU|jmZ6u5oq%RsTe(q5Iq~BpYaKLN$xu&UtteL|Z z)g5YKN~=AoI{r`i4gv@QqTS`3h%OeAA$=j<YG| z)VcN^)V{!YclW(Z>!jwcE%wAWc%^oS@Xb8{GB@Qwy@vB{OS2+x2mGjah#@tO7@<4Z z0*@;tG7_gWQVk6N@w<7p1|FPghz~^??_ReaIT5vH92i|CI<*yB^kGogujZXN5qZc) zS3qxnitPNC1q)*xG4%;}hGyEbOZR_=IRC-75LiFm`9>s>|0ayGHi?$_7DnwW?#U~; zv2f~=g^EiQO3H36%+R~9e?DQCU+CR(v-Qf$7ANd2-hkZOq-$bQ9+cbPG?cq$j*|JQ zWev-vsH>8W3E!enb~aM3?Ic`I-{l9(3&Z_9+ONBLbfkykum8~*wq6x`(O1A1$T@1; zkkMW`B3F^HMKAV@Xzm=L;LPsn6O9 z#quz{CmH-3d^<%&N2?B9)a1tSoO+ltW%>nkNe0uhtz5MGBBDOG z*oJLgA6t9!p7ks~F%5Qf$jZi%RK5~}t%v%~=~eq3PdWRU_3^PYO&EE->gCb#<>C<+ zyf>`d+8tlV3>pf0Tt=fd&GJ;CWL=M>H0?a_FhjViP|hV@Ps34mOJ7rf>bcJ?T1W@Gaq zKBtUhmUD`$HceZs=Dpaq3!tg7Il?|RT-BhFzdGiDT#3Y{PP+?Exu%Pr?yG*)ddnj| zcXj>MEbFpQ8G3h+QyS!$$0=tQ85q1i?^0{}+J*2mr;RI#=3Z$QDiYw$-+cDDYg2OH zz(hrKM8)yrA|FI-9Nf2SNows-k}eOuT-JJlx2Y$&q%Z4uQ{_wdl23^L<(9TGjouLv z{~e!N7$w!*60OF8*OwzC#^gIb$5tec4sSbx1p`YPK&i>r7(S zm|L*=rpPmzouB&O^AO(kbQ@fbS~Ontyshj>e|g}JVXxtbRh61*X=S$dJ9f-;2EdW$ zxd~)S7c4h&NJjABD{b1UB;NQb7gyXpFzR4lvpZ;~zSP{PH%kF?-Y4$FiuMIyfOHM6m*n|fMg~|pwc;beeyWLaTag5nVEwN3J^?m77wfqbXCSTK*J^( znXS?;@2HOsf>JvKh*KUjFUS54W&VS2HvGKaKxI+>24#+|b6NcLn+AkEY9~3T`C#|u! z{b+DcJa;sfCn}*kbyK{RTDTMn`vPzgj-uVmyOyuNK>8{^q-jRJbPh7NI;1S-MAdYd@@&5+uxdxg|g_ zQ-sjCAmrG^H97MZ=bqN5&&{%~bPX6)2+U5fRn~Fds#a>XR_e%!VqT@khAhR!JreYg z_ax!ducRs{O|N?2^=c2MwcpNo;lIbxK?)P9aks(F8hpcdB8uX} zeAltA57t6#qQ`Owv9==N%#5|fkiZopgp>E8Vzwvjcg;=}V5S zto*WqEU`Ic(b*yM!$DFxE-J&=E0b}T2DYST!)CjH5$Ct++((Heh2aZSas>7|etDu- zQE1n5Hr(;}VJU}Oydp6%{)$;8d1m?jp=D#^FFUeo2xX$i`O55;|0DLgRv zs_#>Ob&aBpjbll@^uvcWs?W8qs+W8WnQ$B%`Plp3$G_nHz8W*twnxcn4%@Gc4R*bH z(LiY35&FK@i5mFvUCR=;;7s>e*A_V}Sl%P{OpBazFsE7SQ%irhm)wTt*YNbsFN%^H z!@HwD<-AGEIBu%?ysgDP#Ns6owmu7}sQPq*tHyz~ewKUUp-Li$cco6cO*vGdzR z6^q_xO5QPQ^wvsxJz$!gYijWQI}bhWPQMV@+i|DTamN||?)Ry~k5>*StPJdbXmccS?@0L{iOzlnf@Iw= znMnQ{qEqW+=1xsjRvUUV7F4qU{k(mn8wPoPe0AYl8h*au=`F+=sRC+*LK>3iV}DR} z?oFA`7taf>li@qLnz(0Gdf|z}<{}lI$rTDnz~c)QhBvlM-|hV7S?$%jA{9ux%YV(j zpIK!sqde1+bTsPWywt?8>L*bjcr)&({oEW^Pyr<_+I{cMrokeWYx+sneBq*zGf#*v z6dZKCdwj``@UcaMj`YQWD849iI81j!@Dt@#%|R`l?>li_cO`g?CYKj}D)F`G#?+XQ z(&G}er!!7!EA7#qvJbE9&sqc31_#b<)xPAyDa|RKKVz57^64{ok1ZR_x_ex9N7Pu3 ziGk*3IaS)^A_;!r&oh%d_kCVn{I(o(NK0>G?kCGvW`FKDs}9B{H05vWbAA-m)69Cl z&S8N@*|PgC>ylM%{d(7B4(VN*-yCx2oL*>I_KC=$kV9wmu(HS|*(5@)%eqv;$%~P% zqaW+O3z6+k;!87|es^#$EU8|z_GTn>ZCgzCfhf2!Cb_P8Y2xf_Deg8l{QU5UgTsxQZSH}i6HcEJJBACB%P#C2n3z_6Hh4wjr<1<1 zOCj0+VZ&j3_Y|b{`wKv@9;vmHyA4^P}THI2-JGqD$89!xLCB zc&u^hT}WMV<@`^tPnN@vGi>pE()b%ULj4cErtwqGpT+vSMBD~Q`5Ot2E2}9)v@Tnp zBR_A?sx2Z4B?r%sY^Lua-iZ@2RF6&_`x4)Rj&E(`cEq`SPuF!-%O$ zH*1r>%)5S5c<#YlH+I^p>k2ePuG=%8WE)nC7HQ{q@7!s(Q+PGc!XjSLg_74*^`;7~ zdT+N#!Q4QG+B!RXs-GYycT=9+g|&JHt=>Z|NRHDmHQe4x!^UAN)y(hc9dnTalZHp( za@1E3Tyo406=!hoI@|JX?R%50K_mc+*H`7uRTIckR|!y95uckqLWDI=DJIRaw}{0?nI|WL?vID>-Os<%k)6%0Ij-WfuWs1(qy>@@V{P&fLi@{MSI)T}b>w5{2gbRs+RnrP<*9{m276$FPcE&uZ5ce^H@ zIP3`Ux-!v`Ka^F{G=EFX`yI#Ms%{US7>j98G#Zpok{5cvWlM6HTzSwnxs9|(@+tDh zhaL)#=2cYpB`Z3_LM;7!yT%v4PZI${9VUUJJw4+Q(^yxYIBeG}9lC4twkD>{T|_$e zc>dUp=B&KDis1`;+RD{8KlYF8c#)ykm#@*;)zX@0zv5lttNXcL=z5y{dK2sQFV{DI z&fQv+Yiqau?76X^{G5>w?VTToeBYJbipHL9ENfMla@sWfoY$e;UrNy^O+GF&aJJc_ zyK!6xm8E7$p%=HLQG;D`0w47joa!(ttek&8?!NpmHD|xk{go%*$agGW$2sg3^Q1G} z&Hekv;JCz_bCnk~Yj3@q;63hiSjlW_T*FYNno){kyS!1Fm4Z=yCOu1aao{88?&bLA zrg|6Ew^7|$js0qI-Dx@f=VETKD_Kx2)bi~7w@s`j<8E)k;Ho*wAGAJ_gU@V9x>Z=Y zraF!r8=s(9Ev0+}-)NX6X;?GyjXb`gnk88#?#C|4&Ib7VB@G#no$V;$dYVI;QNs zXIiiEj)#VPvzGBH>rTD>a4Fx3i>0gN-|5rGzW7|$8Qrq6Ti`*5{o{*0Ip>m&1?2}D zcRX%6y8J-hm#q@^l2!Bo)&`-O3y)q4JHNZm)0nr`JYt&b^jAB@1NX6-y93*onJ7JW zvW!tHG?{h&sRi$Y`6G+&TF1=0t9hQ6>@Zh2!H77WEWInN>Wqa<)6x%RRnKHE7rXK* zm-%_O1v14ioiL5LE}AFjx=arss@bcS9Tz;)ojN9;Sm$&;nCGHEPk;0NIg!EPjeHTom!jq7YAujF;Ce!in7Lim zDY3f!I^FQhxv9}22O@A(K(h4h-vizKzrFhTb;Kf1qGkWUSj9$6n=8Pt4RqEW+c`V93a4iN#KN-~LV=};^F(LyURrdhOWZHg%U?Rdy{=1qzWlMYhf7Zv+>D;( zydd9E%v>N}E*PE~l4P=NhV968UDLj!Rxh|!2e$?k@ESPESE=fa9~E4eTsE|T;FsSo zmH2$(*){rZjauo^9y2rHrkV-09mT;eu?Lnm?a*wq9~&9$5Sgvu++cK2K08kT@Ojg2 zqmyLkbMo6#sd4hYhZT%^8h>l%@<}|ew!Aua$eTq8tt`_;i6DdXP0zE{eW+uL?%ZN3>n`h45b?qc}} z&8+S1^WKx!YYz7)#@i{bPgY!CAD4U2sPSXwRv!zRdX9L?#{tb#Pun7rU)D4&5?Q*r z)x`Nrc}dqH1-f+UyU@F%+Aq|W1+OqlJ))6NWGvo{IzKjoO(SfsHo+#a0XB=eGgFEe z_GB7QZ<<3Qi)}KybywF@MeGM4v^;zF;PuS=Qqi$gQs~EBe9=5>GL!giw>sUwnX_+Mw7lx+ z6&eLcy=siqgKRztDl}YFOqYwVcwvYpbQ^ZXOF9c~jcG9So?}njD4CO;t=1WGW!37t zjiL&-HVJmk$XWC#{BX$Yo_cD7;GB4OQu?VE^a~1B^}Rud`A=q~tyvaMU3$veKuth5#{6{#YkAK3;B~fQ z+jMg_bkC)ws!Cr?I^(2sS1D({g!N;i+3FREmDN_Nz;1x5|E7f$R}P>?ufD!1>lwV}$&%O_<=9v>D@zg>HRzU8ff ztzmz@tM@@45S>Fqi)HToYu0C4zLhq=A z;*t?-F!T_wo~UQhbUwRn*i5~~h5MtP#VZ(R2Dq%xOym`zXSGB>=!=N0=?{H6KED0K zKz;M;#C$*L=UNYHc5DwC2(lAOaVQPB9ExZhFI8&|owyQO80_yXl;uGnT($|GH9FDL zzx2)P@z=?U5{eoj*-NDQnk-DqJ*0X{4`sBep4;5k0>55R**sotX}`Bg>$uxPGvQ2i zL$|}Plv#%AW{0&82hJ9;IIeh6MmtThPUePsj_~Y8y&qK#0K%>jix{g>-AF0Rk0%dP9qt-GIF=h@M5 zja#I3S=z5n>!Hf%%>9llhV7)-zE?fK3t(xwyRBXu`5tsivznPx9p`y4AZ_|?`5}-j zG--N-y-k|pVn2JLnObjgr}ET0=ag$~rtgQNd66&6+OK#p`z2yV!(lg~Ut&A!)9Du@ z@~`aD_AHf}lGVl>ToO8e^I&&-`MG%vp1kDir)F(x)!mq+l$V^nc8;&_oFb}rUb55L zIc~mlN~t&Uk`JDmwXs##A?c0QAKZ(cbvv%Bcn8+>dVi=g82vK-Axr2SqgwXz1@#j} zWM*j69A2Z->eXR4!kkT|BvU%frBle&hi>H5OG-&5br#)lu9p;-OzYgQmfoe7zK)l= zp0_gY<-n@|b(WM_4D2>7kCn)MZ|4n*XZbjsIQ{AOT%TOz^+Y2wsCrQW|%)O~3 zGu2%ztl|viBvDB~jQNaZbG<#)dxm8DUNPp$IFsw^DmNL*`BvTL&veG7$LJfavpalF zPMR6C_|ui^H$zr1c!%b(W^x3l56v69uB>lpo^tR7)wSw+?93*+DFw#Dxm)#xleVVj z%oTl2T_^7;t`x=dwkqonzQq}aq9pxoc0&t={AN(RH_|plPkj_Fz#nsG`sy7m8+cpt z3g+CpUS}lV8zJ>79Se2Znno>@DOg2)w(H)Smtr*P5`hS1xM?d*>_EH@pNjl~qbE-t zs;E1wW<6`jDs=y@iov4-!u6yDl6Nl6=R5JREc`*_6J#o@F~Y-X-ho4e>tZ^zBPU2! zI#+F-`9DuR6npiL?9^jR;^;|=2Q8E17}x8>^QK<)vsIWU8TwwH9yanY-i zE&A;j-RI7cc=Et>P-B}$UwGGg#(7M~k>wM!IF(@>>-;$=1buKPyj-kFk55ZCTSE3$ zcyK}cX4fmPD9G{zzkFG6`5=xb;e>$4wv-?@w6l`kuY?(Qt%GW=}XsJ|gPKc|#i`+CKdwA!n z^7u}Dyof!OGwa=~yK8p}?R>v?2xF;z}vtWPo$t^nX%OY$%!RopZ(SA zXns|9>q6$Tl44~IhSt3@*Le`2eb#M;Xh!j+shPSYw;3D6*Kn0rRj*rO$MbaRjDmUa zwal%o^V;T@BzJ|m#v?k1^EyQH+B27+qj$qCJN;+e!%h-DZs>g2ho1GGE0F75e#+LS z*_L0E-lL)_I;zRP*~j{{jDceEx+NoxHm?>obB}frNp>zDlU$4rV-Hsy@6>cmU$^hI zpwDs>)hGKub{9Bn&(=M^;F#K~xyOcQxGv+UDjhpQHaL{wlN_xh7q3DPPOw^O|9JkR z!IUt`YDXCZ%jB?x*{PJdET4zhtxwfRMoC_KDySC|b8g3n{&rr`pa5MS^9w24LjppK zd}o@8#J+7SNiW{1qrHu1@6>JD!ZXxoFcS{#+*GTh?H8s$Rb18SM0!bj_*7r*Su;%G z5gzx9Mh?oe;1L`0ip@HQU&+(tjZ7`R?sUn}rgurwUcFgJyY*%+E%S{iZOAeA6zT=^#x-WZQ_6>hD)!&qUNPA#lyQ9n(mGkyBVK-bwON!*C z`SR$^Y^`L8OKVEWd42f_S(L(*y%9^x0gwx(f$S7_FFP5XJ>gH zOsd%Y&MuL*VsBf^8AN5Q(^2ShdyVkpE68Fj){=Q&D$DbThH1M}aH)wwj>=qDr3&^t z{R;+Dn+?NNmYQ0;m^+fu`$y7+(pQ@BX~SBBvLNjif>ULn zN{4`Lar(9EVXt;w+En{k;HjU*=(dS{g}&Y0A1|qut@9j9sEM%4+LYcLllRu(&ZhEm zqn1Et7NKM4QQx`?_2=93cYNtP-tsUu_}t>utl|A_OWLm1ZM*D|9Nclb#BOn=du68G zN-qh<v;8zr(cu=AH6n_@Tpp`J~As z8#MCg!A)h#cB{o&hbu#jBA4rBW(M3}yIeO+c8^o`$*~E^7ME2{ZN&O_A^tHn10MrA z`}barf2n@dPGe0$dEdf{iILq_D;Dw&ho?_d;P6Z=3hxVvTzKWdlGf|?A{cL?PV(*> z56T*Z)vnr2?=B3Ix{{ML#uQ(CcjCDOhv-CTM0^z5qc-5usd-F0kF+u^C@ z)#|!YVxl!lk;VCsb*$7Eh(Fa>Aig(rp7`y?EoU3*)0RWm!6 zRT;iLJmO1Q=_==WFI-~m)&H=WXGKNuPKEo~3G3d}#*HnKTOO{w>#qH6gQdv}3Jr2T zZ@o=Co>nKiuh2)rv;KB=cI=dqorWqIt98aw(r@Q-v#p$*3Iq@4`qk{zN8p_UgAw$Z z;$-D3NzMIGq@D3;JL%HXka8uRsMY48R{GuU8z<0dcZMdAV zb~RQK%E!jXJ`e19ZFqC2a_Hr!ms(%SLS39kj*NFj|KXtZ<%5v2#D>=E33|ON%OlUZ zt(h5A-e&FoVeMsGhZ}88x5wv8q)v#fd|cqA%5E#ruZgXD%h)%^t3D&`>>?YY7jq_d zFjTU+^2DMef?H>*?B+-Y%`Hc`{3xSD`G`L*$jpB~|v>1ScfFC&DJbV)o4Z&OL$G-u50# z{IDdjcWKP{;d$YkJ@WP!hpFHLa(`w5<9tz=hD|}}nL>AD^z)YYr4P0TJuB177*U(! ztU|b*psVusW`aNBvXau|bnWweo9aJ?Gq@hx)>*eM&vW1J+PbiLc~8sPy5XaPAEL)3 zGVE%6T^IHECSHMOX*bx@&!t`1Hhkp5I{&KoN)j*E56(DQ`!JyE&Zoy^VXaOX?nUbu zF}u5i9t;QBJ^y&~V%v$dditHUjF`Rdk^&n?3jFM@J{OTTJO1v#_IY~~%Wf52FIseZ z=IMt-@uTDl!!17H?bq)Lbuvuht{F#N$1P5~mdO!c3(heq-ClBS=RSqOGj$Vf0*pKM zTJyG->IBTQyP2}OFg$*Cx;H<+Kp@w9){hPEM($D1gN~{$%)6AtVK2|l3*oz|-WxOO z@l73drKx!6>5a!}pN%oKb;BdeuWTQf_*mUyQy@OkNSBx|G|eS-*G=uDt1H@N27I!{ zCwfI&ucZviKHhBll9yAuuKbJ9!!Pi4SPe7M@4jA7{SWT&r_qVuSs$H>-6n^P zVDBtG^^vKEKDKUA-agOp5wdFKif)HnB$+LB3qL069~53Fd49)%WACQlD7sa8&-GxW zWG-=8g;1wp;u2$lCw%h_u8_{myXt!V!cLPdv3nGIQ{PR!y@!!4e!&b zay3g>0)a7$_KFTldS^CySEUxDp`YL@J(6o5b+Qr^7Q{=7_1v@HeZJtex!}VOuOF;U zer>+?q4x$WqbJ@Q8djf7J9>MI*&bT-NTTt|qupiRLlw2} z16smgPuy!-?$IzVQ5d~(abeW4#gynnF^AatmHXLOkiqMckEe)qpXyn$lBp3?RI_sX z?ra(7CB}SbTlUV&SZvA9&Js@C^(3d_l#E}u=d#FDwN3o&d{a^bX}$BUn0u=WFVc=Q zQNLtAIQ@2|wy0U*sWzm)T-I`y)6>`B94E8J6{pEq}`xczZ5tv`^TR!g*ZHM21_a6+@ zLk-5y_|=Yb9GmU)TuOrG6|Ph`ezzjUz|p&Q-ikEG=5t$y`TdS#L)UMYi&tmZ7zSSw za3;K49b-DO_!_zJ=(*i_VaJM{ty`&|kI(xewq?pWKd-pok%FJ@H2)U7P-#>;!P1xQ z6X=N%HkcTHRc8~-2jL(-$d6wMSJw*gL{JyZM~00#I=gGgzAY)2m2u{1$lB0Mh$fyo zn3J<%kQZhdWNL*5xu7hLtd=IfdVpGho2MJpCKKT1>h7%;pdpKJJlL2T?Bjp=y-TxGE`NvDoF(;QYkVtvMPneq%+AYWPq2j2t+1N~r-B5YSoo$&3zk4o{YCXfDFeo}&eYz!BH z^J7GQZE&(RZP&jD_d^VPKGa+hcSjA`02L0#MSNX-WHt5NJY78kF-*~0#>Uyl$;rc& zUK+{aVGOB>&hRE`^V?k1O_TYya8Ek%?roj6NukjExHQUy1gcLHb3AuVsJI^zYJ5 z%JtLnzq0_a^gm6&-CK3i&Q(zlH$nj73F=S$RsG>=HJz_hV&&oCs`=IWjh+24oj}wT zlYxev9o;c689hrGmMT%5@Ye!Av{)TK^&PTwL1#2!a7Zd7vI>Q0MWU)vNGe1cV8z!u ze!1|km3VNRxq*LQ#gEJWQo&@8u)nR~r^~)o@IN*S03g4g1vmk-K>2kR;Gmkhmj}le z#k~H03Vylzr=H`-*J6SG9$p;ppWx<~!~fI$ggG}c`F&5n>zkX~ubrJNqNeMC`r?pm zq^s%c>&#Ij(-9U4MNkzIi_21>l9^N$1f^gq3_8XkvluK2o57mY921kD%l_2;uk{+a zd;1{nDE7TxBF3Rm7~rQ+I+vtEC8Asv7K+kU=nN{8#pR-84u$!>-k-|;PmdE!f-i#m z>7Se+;_U1;>7XW065PEB&YWL|>RTx_PsGbdlcbKjCA^lepZ}*t#4-C%`F=$XE<*71 z@^JI;!8qVFywP8!#E+<9ZfuOh!8nFq7HBKRe#<;O>XG z`eK@@s+<1tzm>kWj^!p3XK!?qtB0e=ySwj>n?|+Bu-x#DHm;CQ={TPdXWAA^5 z>)#lpAD8@pK3x1i(lziy;~KL5kc|0VKIo_K0YjF+2lM*PkC6ZQgBSG4RqlV5?xgw99vUx;p_56Z>HNIQRvB9IwM@~y-5p^yKeL-x{&d#-mS!IK z*2l1zsQB+h`{~Pre=iz|^)F@Hf8d(?ZldT;hYou0k^&M(DN1&U%vy};jw2Ey5}VB81b8J;B~G~a*Z#0RBii+ z>uagD>?ZFIyF*1A$D0OrEi|b$UpUh*;f}=IH`DBM96T&SEj^VUp9+&3T}e&0k`fky zhtan(E%<*kI<%j@6Qhfv9vsXZ@pAK4S10Irxca)ed&|%W=3W@b8HJ3842i6%`MV#P zH`29Jr;?atst$|FWRh5P68vEh85Al*j|^`Lb@ggZbuwK~m!!>FO(c<6G+io#r9+|9 zSo%bL9j4xDx(-p(o?zt8^^hS`DfpVB#rFg`nMovAczF2WC-A(Z1;Nre2*W?ozv|Ei z3ye#!u_MV)WJvZuGL25pdmm}3>aJV3YGCxW(8;653Ux|zSKs5e67R^ajdbTfDYJYp zM|{@aq{v${&#YQjFje`Wlh5i5Qs>G;*?U)SJN>ca!8OKEe=uw5?fh3h7gE-&2~>53 zC$$wK&74rplwz!7MGBK0x>&km@5}R7w{$FZwU4c;u_HBEz6x3F)u~|ox~k+%p@}7;w1WNcnX?5%`EV)@4uHl#Hxl`nBNmJALmiF*O zCgroW^lnA>=Qod3sEwuVc>AiQ=HcrPE58?ueK!f5NR)`LH*5pT>I^TLlpmVoi&8e_~4bCscK!asru;^l(RHC&JHVjLMC zFNmSw#J7C03}j>R7EBR0%p0bffm^W!!5nd%{7AuXv;jSUQmBuW7luvh2ji>S;1L@^ z2a?VZauLiiP-hu3je_4BXrZae4={%J2abHZ(;DyEWD!ee$M4ELnL|=FH(zV)4B;1K zwZ9<;!eL{oo-U|2LzM%PqD~lx0Lq7XL0pH~{ZtXIkyc)ayEh)UL8qKNIE3{Ulpn{y z%#cYtvnG&L$zKKdv%uGr1QTyZB`YUqZyETH$XGZ#I{A33=(*!5SdNT2WTwAoAeIrn z@7WRbeO+BG5kJhHpzZGN;p1&b_?jak=t2e=I%6`Kasu=A3?vx2d3t#Hz!XjXF>`ly zc87BK978>j>@{-#%Ox-pZq7cIke=Yc=(=NsuVo0@9L~4;?ZG%5-4P#OFU;;+TlNHV z87|`LjS=+p|0>Nl3BC#iwo8DF7xJf}YXT(T8la?Yp(pb-yEK_Ww`Qu6WX#D_{0A%< zWHNCX!9+<{4bRn)$P^-pN@I{{kf~E75*3$0Pu+d+#JM_!$RrZ!L>3ug(gC07Tn3Rt zBoP@zG6H8N&ywLYi9#Z>DX=;K*V4#rA_k|(B!oyKe!b>*HGmvM;u- zN=NWQc&)f_P$3(kVKf$-g~DvgjC{0>eON z5b-TMmKQ%qrI1J*7)ADMu1>p$rYL3$K+s#8GH|llHtvSy+25R0BBLBKor4hRFa|U-mxNIf zHWQl1SS*aifpKGSIUJNqWgv7W1EEo=ECfR-Tm*UrKM4yJ!VpmzbcBnLnfQ2-V4V?x zUQ$SGE=D6GD3eGfqcj#mp&_soiP53oK#=GZA`5B*wc|iz4B$^>gaXuw!K9!}8k0_^ zGpTf_5k$i@F*b>efZfwv9gL}GozUg#@~;MWmil9>1yl9*6GZ2#haCi@O!4w!|% z@$yXYICLnDBR+U0e1z#V5<;iY0H+v$ULe6Fnge!&2E#DJc{swMv+$9@`vS)R^I;2U zjN?8&7H}3vd@vZiPoQX%XMjQD*iD6_U-5ggchCln0b;`z%1*WjWq;QWoy=f;s~?x_ zFSXN2bOtUfyf~9>QUPCKSia9PbPa+AI6?=DrgG?9-1m@)Yyb(2NJWSo1_PWUn?^$r zE}Kfh&7BG;@YORRKfL&N4T4eou3=STu@X{ANT~i_bDI2W1cu3)iWmbWve*n*nL^lrNDK~}LStj#4}dmN5i$+niNoMB0W?`m1Vv!{;20GJlLqEZ z1m$Lf<1x@~?z*POh;i%wlzK-~Dgzy1x* z_J0Ml{qOQKHU^OmXgP<>U|;|-9Pk?e9uy{n#lgs6)Lg(3Di=5eczYmmz&k)!>7c9N zNdSR>3DC%31SH(5!CYD3GJ$LXJqP|yrqkIRlmjp63GmVMgm1(vEUR7fp$4WAXgmR%E46u`JizqK)k^U5nwE25(BIcxCVd^ ziedlkj$E|?-1NF2IpEDHEQKnV_)0~{8x7>a=G3@!`?0!;#wqXTx+nedny zGK~w5EThr57=;cF2%HDTU;rV&`2d*O4}M05d79KIh*yC@erHekHDCD|G(X8E@K2LI z5yS;Y{*`5cN>Cxz0cHhnoZbDEl}$1e3baAN5$&(c1QJESl)mvXF!`^H416{?eGGj6 z_qg*13&S}Ig--dCw*h|xegIJ+4V)inATSOZa5X$}2sJ>>z#D*B0WbaDGvI|}Kqkmb z!A(mLxZsW*cp+%aFTC(OAN;Kp6o^9c`oHnE-*Q)AVlasR1?~#Me3ube$k$j8+zyN# zM2#d8K0kOq;cLVO;0XR1*e3KI+zhZUxJ87@0fNj1-Gay$-ayTOqeAKL_2Qfe=sLKv z{{mC`CtM4rk^zwdf=6I1h=4FI6Z|oUMWbTi9*JBon@MD$coySd`LZ93iHw4pQZUc~ z4&+r>kU;=TgP#opON96YXfFx!6DX630T+arkBYKrDA+xT4bBu=2d=@QgO&q7p@XTy zO)XFgWio&(0po%I20S~&E(|UWqBejCHVXIvg&;}=;tByN8g0uz7#UPvoQo$u52$@YrQ8o*Q3JBJ? zD3~RXHzFHM5jw&JR3rm~gcy|xC=6_b%Y>Ma2@DyX%%Q_%vq2yjK;V@q7nl+i5>Z?T ztS}NvrgB+8zfpixE(A#c5kw3_Xb^?~?2<4dZX`ehxeze|!zZ#JRe?dA2!v=d2&Ms! z1Hyw?bS}nZ0PF&`GGR_A3^ouWfO8ykIb@6l!_S6b6r2biN&&59QGs%T^T7Z{iA;>k z1#83^6Tm3`mjdzrPmBqVbxA1Hgk#bFz03&055Q5J6@ATD!5v-T`ydzamuwc;{N(G~ z+5c1d;(wP3p(qu+Dib^~!a(rAACi9zE(PooQh%VZWB>rj#^5vwQaNnUW_(EsP6IS? zm?REZACW_Y>=BCyeha)aIBmG64nyJYB+2r2u1<`p~97HGL?(~M}d?A*a)P@ z5WrbT716-+vT&vWyafyi;t&)fAm|j6iHCSxfPP3L(ZDW2AR+=Rj)VZc!rinH<0oJjI2>2%rgIEA)j8CQ zh^eTM>VR}93h+q-dIs(R1^_%35r`Fu3CPI=c;~{shioZla0enGL zn?+?!rU)S!1;fu^pg1lPapi~D3zB_M3VI5D0MHjW7zqQo#JwbR3&Gh46|jNYv~lF!!%l0J_0-IO6>SrhRYomwe$@&h_7BEWcw+{{_DDbC#0|iyOEnn`G1Q=U4AV zX8;9&gcOVoo@xT03>FMoOFEwAg0N#U+XW{;%~|;QUrT>od-|H^gEnwHgcqzla3I|Q z>)bSmn-DNvFignUuz^JaVWmJ!LWj&Ug$||!NeG}ckiq~sg1i(41cgb%Afb-pm2nXU zhsuVG3C@Xtl5>Dt;f1&~6eUq0SptLuqBB4>AcDZH0F{6aK$Vasff^xQil-cj7}yLI zg$NT!7oa7?W*DS&$W$g|`XNn4VL}R-4cGt7G5}(+sBB<N}Pza!oupYpsLc$A% zjmCg!Ldggq4PZS3kEntEa)56Fq{2zaqXN7$C&?`2h)A$b04F$9;9V3l8;}~AoM*^! zgVanWtP#LJi1?swhyZam1uIsdL7*Fxhz0uif5RH!zqwZWn-yBf41x;*Yr}Emr+5~u z54SJK)WK*@uBAd$@{d=5q2f6In=`N!1qkq$D0#A0$Pz;t?l&F>p&icaCXo+ck%ZL* zfKc!t0GhvR4_|GajOqX`(8-i5o5m(XqLoU-U`Ydkg&N4-K;Du9NnxNdpaEpO-+%2J z3nE4^JdhFE`rXlCTg>!Gbp( z#j`uW7q~2l^DyN9Y483+@2cxKjxV=micVuAl8SCx)T*^}f1kTy^EV>Bw58Kl#Kb}{r7(yPw}SoQDne2;kun`+ApNs!Su1c66s1T-!732z@jmx{zu$ZJ z!#1~4=bdbRx9`2*?>(P;&ilOIuh;YS`Gz&a;Y`EGqd@aecwCh8X3f=Rbxd9+-@3D0 zh`}^W{$R9|TS5hANb56{uDDpbhDM`U;-Yrl6NG3`VVHI6^yoenvTB$kEL3aNhTg-R ztY-Rb%3$m`9m0|_i|VxUTvMWo^mS6|MUCC*Am}y(dbKGv5fb7%sphDr05KK|9i}&f zKF$yH0u7d`r;AWm6IFx|-{h z>SnoW<;^uydEfc(M6kMdkj< zj0rkVDQe`5EK!Y+K2rX16CblMu(dr1v5I__rT%ljYeU1hjrcc zn=9o{3z!B<*F=tQ09a20%BODm&5|#ld-ac#Gtc|?PrtN(-Jx$)h*9=Z1iH{bJ*Coj0?v^~2QUHZti+n)T~ zw%yNfS@N}$vxn!ud&kdvKe_YITfZ^y>eV|Rn)mzfJ^JlUkKg&l`)|GHwma6G);RO_ zC$`=G+lN+l7wtRu*UOjQ`=P%+{ra`{zUh{C6wlwZZ{zOEPyhQbPTpSI``|4r-uujj zdxNRHezOSnH6wKGa8s1=m8!qUg{l*uHkO%yGfuB<1U$A*`rGH9eRk2DsU`DIIpnt= zZcs7)?d`NulD;J{K8}=+ljlbUw0Bn4r$Fy3X>jRk5?Y$9T-8Wc8Jw%_77iZ0Iv~}X z^)x8@8!LK!jC)>exuis^t3fuW75@tw*?&#syJY7y%Z{mikx2f?Nk)6W>Ve{l?sLDo z@3xztUa{fsx83^G*4I4t(d|Fl_1Lam-_s3aLWF4!H0W z2@5ZOCdfDzKFo_uu<(~Z7XCrRIvzb}_;Txk5)S{g?LR65F5Uhw*F-|Uf>*DsyW!g2 z$Is8M%V%iuQbUfhHmSXow0OfnX}%^1jrnFZ_#QR;FjM=G2sgjJ08PZ9pK-ArWf*kK zQ7j%uW0v3^aNxl{A4oV8Gme6Arb{MNkWrVLv@me^5669b#wa-yd?p64s|5>%q~b`=NU66qd2D=&cOQ^>s_LXhqM0+ zGA;`#WZ8^WMXzW8_;6&kE^?C7-=`9xg~-_?R;n%!tq=a}^0(OGT>upMnGNrI260^v z5e7w*(mxUerZ2_IV_j3tLZRYAdH6yIcsJl_R8d3WkMfr|SfU73SJ5ByHc^Evo!Ppv}Chnkq|$wS+0Omn*-9j=W-~j zB*c|5)IG^AZ;qm!lA0 zU~HH4UQrh{;`8Q_f#A5uIpuM5ZSja+tq1fETrC6tiFE`-lO|Fc5R?{Rrfb1~`j8vC zsu&Dpu;Y6&vY|CBsU9!48G^NGfWzInNBv+b5WGl;$DFDm3Gs-ael~Lnuf+0mU zp%wGW;~Wo@i%HPzvgU0or=X=QDA_JjEd`mgrIIkSLN6vKll=mg6dDVc<&2B}iYG57KW&;WEp4>&22QmDU- zv%@}2x0fKr|v$(wowUpgRPWCOU zS(#m%rg-Se|D_{2q4{Qtx&9-54{~YV1%Eq&F6EWqr^OxbSh8hV%c-cKblWMsu+M`Q zVbGB}?SXn)gAB8e&j}!g%fg*@dG|3IEImGUD`U0-`_zwa1FFIzcAE_cTpB|iVk|L$ zd>AYahZPzu5#_YjOek!5JR{h{f=jIg#Kp{X^((4^u10_20z(UhQB~z{3C8tnsA}m4 zCUnM|Z3|O06&$2*#xrqQMJ!I&QIkf<)q@Vtml-ddkpYKQgd*=1sNwL|bycmxfjRc3 zix#3M%_Ku1xmN4))j-IpG(38s840*Pj4_NI<%IW!MFJNpO)ycJ?TPdWNQltMX!P)ca+^ROL~Nr0GT=3#e~_9H zh^Vs85d(54fNsYvP@!4q@Sg*QOp!}~<|5J^5G591G-$XXkwK0Z8;vcmNyBYwyL`EW zx~MEVQs)$N=>%q%kA@-EUyb#F?lk3mEoR z*&u}SV5)-)(I1R#p$k{SxVJyT80pGf=&DpCBTL4pygMHSTO@{M1~Y0#v@8*QH5O@) zFfplSP7Ga`RGXKGBosNam=nyPS8yV7W&Xo2o6ms1N{AO6A(VvX>G25^N-snI?`huz zi1qneMTlRfhlLKse1>l~OXBDR9gHZPX;IHWvDIra2URnd;IK3%L{Um`kl+TE(+G%; z35LlFgGe}jjg)?_WBQUL32eq;wN+(-pFkZhaOuhjxHLxUPo zSvxrGG~mgo#F3SQP({Sle2d_z>v3y9fiwchmy#!F_k{BZR(R7aWM=nA z-6yCXqKz1g(6j*^nGi0#0bPouALdnor9I$Gy^dl=j%F9Ba=vp|mHI_Na0;p|mmmk((P;EYeWmp914oieWj~Cj%C_?d^s}Kkv}mjDV&=8X+7>p80%>K!!AVc(_p~N zJ$WJ0hh5!rkg}9h+VPN=im^7EW10y|<#t>;eN1oWb&;TH%&`d)$hk~KXVkD>m!Hx$ znMr5+F&Ksw=}|}1Ks`tDlPH|p7O7e#eo3W8eun}@hNh8G!EWSLVgq21EF^$mKY&!dbT^Yi8n+ zuacX~@zm1vGrgZM)*JK4ID==As$qKycSKt7~ zxZGm0QtqdQI7VN*%o*eI=LRL!i>k@8dVN_n9c7Fq#UrN797#dUJEM%ntQEkAZ8ht{df=ADlPjnwQOA zaL8|eNC3T=99OQn+L)RW*qd^8t^|;+P6^BH_Ucuur%X3VYxOMG>_`3$xaJZMJ{;O? zTkb%cJ0;=l^llt~!uca_MKk|%=~Zu-yKwH@x#!H?bJNa0EU0|t@h?>N|7&jLQ)`wa dA3ka0hTU`KtU3GCA0E80BcQW=%hPGl`9J)?y`KO8 literal 0 HcmV?d00001 diff --git a/src/blueink/utils/testcase.py b/src/blueink/utils/testcase.py index a0c47fc..93d01a9 100644 --- a/src/blueink/utils/testcase.py +++ b/src/blueink/utils/testcase.py @@ -12,8 +12,8 @@ def assert_false(self, val): assert not val, f"{val} is True, not False" - def assert_equal(self, a, b): - assert a == b, f"{a} != {b}" + def assert_equal(self, a, b, msg=None): + assert a == b, f"{a} != {b} {msg}" def assert_not_equal(self, a, b): assert a != b, f"{a} == {b}" @@ -26,3 +26,9 @@ def assert_not_in(self, item, container): def assert_len(self, container, length): assert len(container) == length, f"{len(container)} != {length}" + + def assert_not_none(self, item): + assert item is not None, "f Value is None when it should not be" + + def assert_none(self, item): + assert item is None, "f Value is not None when it should be" From 3342216352a82609346dc2aeb13847d91c1cb40d Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 12:44:13 -0700 Subject: [PATCH 10/20] Big test refactor --- src/blueink/tests/test_bundle_helper.py | 74 +--------- src/blueink/tests/test_client.py | 174 ++++++++++++++++++++++++ src/blueink/tests/test_person_helper.py | 65 +++++++++ 3 files changed, 240 insertions(+), 73 deletions(-) create mode 100644 src/blueink/tests/test_client.py create mode 100644 src/blueink/tests/test_person_helper.py diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py index 5f3a02f..16ab3da 100644 --- a/src/blueink/tests/test_bundle_helper.py +++ b/src/blueink/tests/test_bundle_helper.py @@ -5,6 +5,7 @@ from munch import Munch from src.blueink import BundleHelper, Client +from src.blueink.person_helper import PersonHelper from src.blueink.utils.testcase import TestCase @@ -189,76 +190,3 @@ def test_adding_fields(self): self.assert_equal(compiled_bundle["packets"][0][k], v) for k, v in signer02_data.items(): self.assert_equal(compiled_bundle["packets"][1][k], v) - - def _construct_complete_bundlehelper(self, file_location, method:str) -> BundleHelper: - input_data = copy.deepcopy(self.BUNDLE_INIT_DATA) - signer01_data = copy.deepcopy(self.SIGNER_01_DATA) - signer02_data = copy.deepcopy(self.SIGNER_02_DATA) - field01_data = copy.deepcopy(self.FIELD_01_DATA) - field02_data = copy.deepcopy(self.FIELD_02_DATA) - - bh = BundleHelper(**input_data) - if method == self.DOCUMENT_CREATE_BY_METHOD.url: - doc01_key = bh.add_document_by_url(file_location) - elif method == self.DOCUMENT_CREATE_BY_METHOD.pth: - doc01_key = bh.add_document_by_path(file_location) - elif method == self.DOCUMENT_CREATE_BY_METHOD.b64: - file = open(file_location, 'rb') - filename = basename(file_location) - b64str = b64encode(file.read()) - doc01_key = bh.add_document_by_b64(filename, b64str) - else: - raise RuntimeError("Invalid Document Add Method") - - self.assert_not_none(doc01_key) - - signer01_key = bh.add_signer(**signer01_data) - signer02_key = bh.add_signer(**signer02_data) - - field01_data["document_key"] = doc01_key - field01_data["editors"].append(signer01_key) - field01_data["editors"].append(signer02_key) - bh.add_field(**field01_data) - - field02_data["document_key"] = doc01_key - field02_data["editors"].append(signer01_key) - bh.add_field(**field02_data) - - return bh - - def test_roundtrip_url(self): - bh = self._construct_complete_bundlehelper( - file_location=self.REAL_DOCUMENT_URL, - method=self.DOCUMENT_CREATE_BY_METHOD.url - ) - - client = Client(raise_exceptions=False) - resp = client.bundles.create_from_bundle_helper(bh) - - self.assert_equal(resp.status, 200, resp.request.url) - - def test_roundtrip_b64(self): - bh = self._construct_complete_bundlehelper( - file_location=self.REAL_DOCUMENT_PATH, - method=self.DOCUMENT_CREATE_BY_METHOD.b64 - ) - - client = Client(raise_exceptions=False) - resp = client.bundles.create_from_bundle_helper(bh) - - self.assert_equal(resp.status, 200) - - def test_roundtrip_path(self): - bh = self._construct_complete_bundlehelper( - file_location=self.REAL_DOCUMENT_PATH, - method=self.DOCUMENT_CREATE_BY_METHOD.pth - ) - - client = Client(raise_exceptions=False) - resp = client.bundles.create_from_bundle_helper(bh) - - self.assert_equal(resp.status, 200) - - - - diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py new file mode 100644 index 0000000..52d20e8 --- /dev/null +++ b/src/blueink/tests/test_client.py @@ -0,0 +1,174 @@ +from base64 import b64encode +from os.path import basename + +from munch import Munch + +from src.blueink import Client +from src.blueink.bundle_helper import BundleHelper +from src.blueink.person_helper import PersonHelper +from src.blueink.utils.testcase import TestCase + + +class TestClient(TestCase): + DOC_METHODS = Munch( + PATH="PATH", + URL="URL", + B64="BASE64" + ) + + BUNDLE_LABEL_URL = "A URL Bundle Label!" + BUNDLE_LABEL_PATH = "A PATH Bundle Label!" + BUNDLE_LABEL_B64 = "A B64 Bundle Label!" + EMAIL_SUBJECT = "A Test Bundle!" + EMAIL_MESSAGE = "Email Message!" + + REAL_DOCUMENT_PATH = "w4.pdf" + REAL_DOCUMENT_URL = "https://www.irs.gov/pub/irs-pdf/fw4.pdf" + + SIGNER01_KEY = "signer-01" + SIGNER01_NAME = "Joe Schmoe" + SIGNER01_EMAIL = "joe.schmoe@example.com" + SIGNER01_PHONE = "505 555 5555" + SIGNER01_DELIVERY = "email" + + FIELD01_LABEL = "An Input Field" + FIELD01_KIND = "inp" + FIELD01_X = 15 + FIELD01_Y = 20 + FIELD01_W = 16 + FIELD01_H = 8 + FIELD01_P = 1 + FIELD01_EDITORS = [SIGNER01_KEY] + + + # Person Data + PERSON_NAME = "JOHN DOE" + + PERSON_MD_KEY01 = "KEY01" + PERSON_MD_KEY02 = "KEY02" + PERSON_MD_VAL01 = 12 + PERSON_MD_VAL02 = "VAL" + PERSON_METADATA = { + PERSON_MD_KEY01: PERSON_MD_VAL01, + PERSON_MD_KEY02: PERSON_MD_VAL02, + } + + PERSON_PHONES = ["505 555 5555"] + PERSON_EMAILS = ["johndoe@example.com"] + + def _bundle_label(self, method:str): + if method == self.DOC_METHODS.PATH: + return self.BUNDLE_LABEL_PATH + elif method == self.DOC_METHODS.URL: + return self.BUNDLE_LABEL_URL + elif method == self.DOC_METHODS.B64: + return self.BUNDLE_LABEL_B64 + + def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): + """ + Returns: + (BundleHelper, signerkey, fieldkey) + """ + + bh = BundleHelper(self._bundle_label(method), + self.EMAIL_SUBJECT, + self.EMAIL_MESSAGE, + is_test=True) + + # Add Document + doc01_key = None + if method == self.DOC_METHODS.PATH: + doc01_key = bh.add_document_by_path(self.REAL_DOCUMENT_PATH) + elif method == self.DOC_METHODS.URL: + doc01_key = bh.add_document_by_url(self.REAL_DOCUMENT_URL) + elif method == self.DOC_METHODS.B64: + file = open(self.REAL_DOCUMENT_PATH) + filename = basename(self.REAL_DOCUMENT_PATH) + b64str = b64encode(file.read()) + doc01_key = bh.add_document_by_b64(filename, b64str) + + # Add Signer 1 + signer01_key = bh.add_signer(key=self.SIGNER01_KEY, + name=self.SIGNER01_NAME, + email=self.SIGNER01_EMAIL, + phone=self.SIGNER01_PHONE, + deliver_via=self.SIGNER01_DELIVERY) + + # Add Field + field01_key = bh.add_field(document_key=doc01_key, + x=self.FIELD01_X, + y=self.FIELD01_Y, + w=self.FIELD01_W, + h=self.FIELD01_H, + p=self.FIELD01_P, + kind=self.FIELD01_KIND, + editors=self.FIELD01_EDITORS, + label=self.FIELD01_LABEL + ) + + self._check_bundle_data(bh.as_data(), + signerkey=signer01_key, + fieldkey=field01_key) + + return bh, signer01_key, field01_key + + def _check_bundle_data(self, compiled_bundle:dict, signerkey, fieldkey): + self.assert_in("documents", compiled_bundle) + self.assert_len(compiled_bundle["documents"], 1) + + self.assert_in("fields", compiled_bundle["documents"][0]) + self.assert_len(compiled_bundle["documents"][0]["fields"], 1) + + field01 = compiled_bundle["documents"][0]["fields"][0] + self.assert_len(field01["editors"], 1) + self.assert_in("key", field01) + self.assert_equal(field01["key"], fieldkey) + self.assert_equal(field01["x"], self.FIELD01_X) + self.assert_equal(field01["y"], self.FIELD01_Y) + self.assert_equal(field01["w"], self.FIELD01_W) + self.assert_equal(field01["h"], self.FIELD01_H) + self.assert_equal(field01["page"], self.FIELD01_P) + self.assert_equal(field01["kind"], self.FIELD01_KIND) + self.assert_equal(field01["label"], self.FIELD01_LABEL) + + self.assert_in("packets", compiled_bundle) + self.assert_len(compiled_bundle["packets"], 1) + + self.assert_equal(compiled_bundle["packets"][0]["key"], signerkey) + + def test_roundtrip_url(self): + bh, sk, fk = self._create_test_bundle_helper( + method=self.DOC_METHODS.URL + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + self.assert_equal(resp.status, 201) + + def test_roundtrip_b64(self): + bh, sk, fk = self._create_test_bundle_helper( + method=self.DOC_METHODS.B64 + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + self.assert_equal(resp.status, 201) + + def test_roundtrip_path(self): + bh, sk, fk = self._create_test_bundle_helper( + method=self.DOC_METHODS.PATH + ) + + client = Client(raise_exceptions=False) + resp = client.bundles.create_from_bundle_helper(bh) + self.assert_equal(resp.status, 201) + + def test_person_create(self): + ph = PersonHelper(name=self.PERSON_NAME, + metadata=self.PERSON_METADATA, + phones=self.PERSON_PHONES, + emails=self.PERSON_EMAILS) + + client = Client(raise_exceptions=False) + resp = client.persons.create_from_person_helper(ph) + self.assert_equal(resp.status, 201) diff --git a/src/blueink/tests/test_person_helper.py b/src/blueink/tests/test_person_helper.py new file mode 100644 index 0000000..5cf0309 --- /dev/null +++ b/src/blueink/tests/test_person_helper.py @@ -0,0 +1,65 @@ +from src.blueink.person_helper import PersonHelper +from src.blueink.utils.testcase import TestCase + + +class TestPersonHelper(TestCase): + NAME="JOHN DOE" + + MD_KEY01 = "KEY01" + MD_KEY02 = "KEY02" + MD_VAL01 = 12 + MD_VAL02 = "VAL" + METADATA = { + MD_KEY01: MD_VAL01, + MD_KEY02: MD_VAL02, + } + + PHONES = ["505 555 5555"] + EMAILS = ["johndoe@example.com"] + + def _check_values(self, data:dict): + self.assert_equal(data["name"], self.NAME) + + self.assert_in("channels", data) + self.assert_len(data["channels"], 2) + + has_phone = False + has_email = False + for cc in data["channels"]: + if cc["kind"] == "em": + self.assert_in("email", cc) + self.assert_equal(cc["email"], self.EMAILS[0]) + has_email = True + elif cc["kind"] == "mp": + self.assert_in("phone", cc) + self.assert_equal(cc["phone"], self.PHONES[0]) + has_phone = True + + self.assert_true(has_email) + self.assert_true(has_phone) + + + self.assert_in("metadata", data) + self.assert_len(data["metadata"], 2) + self.assert_in(self.MD_KEY01, data["metadata"]) + self.assert_equal(data["metadata"][self.MD_KEY01], self.MD_VAL01) + self.assert_in(self.MD_KEY02, data["metadata"]) + self.assert_equal(data["metadata"][self.MD_KEY02], self.MD_VAL02) + + def test_atomic(self): + ph = PersonHelper() + ph.set_name(self.NAME) + ph.set_metadata(self.METADATA) + ph.set_phones(self.PHONES) + ph.set_emails(self.EMAILS) + + self._check_values(ph.as_dict()) + + def test_all_in_one(self): + ph = PersonHelper(name=self.NAME, + metadata=self.METADATA, + phones=self.PHONES, + emails=self.EMAILS) + + self._check_values(ph.as_dict()) + From 2d3303ae8c872be75660bdd8f03bfc3e399245dc Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 12:49:18 -0700 Subject: [PATCH 11/20] tests passing h/e b64 string not being read properly --- src/blueink/tests/test_client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py index 52d20e8..a14bae4 100644 --- a/src/blueink/tests/test_client.py +++ b/src/blueink/tests/test_client.py @@ -82,9 +82,10 @@ def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): elif method == self.DOC_METHODS.URL: doc01_key = bh.add_document_by_url(self.REAL_DOCUMENT_URL) elif method == self.DOC_METHODS.B64: - file = open(self.REAL_DOCUMENT_PATH) + file = open(self.REAL_DOCUMENT_PATH, 'rb') filename = basename(self.REAL_DOCUMENT_PATH) b64str = b64encode(file.read()) + file.close() doc01_key = bh.add_document_by_b64(filename, b64str) # Add Signer 1 From 7b23061de873d76566cdddec39e5c945c47fb21b Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 13:51:15 -0700 Subject: [PATCH 12/20] moved subclients to subclient dir --- src/blueink/__init__.py | 6 +- src/blueink/bundle_helper.py | 32 -- src/blueink/client.py | 506 +--------------------------- src/blueink/subclients/__init__.py | 0 src/blueink/subclients/bundle.py | 227 +++++++++++++ src/blueink/subclients/packet.py | 56 +++ src/blueink/subclients/person.py | 122 +++++++ src/blueink/subclients/subclient.py | 50 +++ src/blueink/subclients/template.py | 60 ++++ src/blueink/tests/test_client.py | 5 +- 10 files changed, 529 insertions(+), 535 deletions(-) create mode 100644 src/blueink/subclients/__init__.py create mode 100644 src/blueink/subclients/bundle.py create mode 100644 src/blueink/subclients/packet.py create mode 100644 src/blueink/subclients/person.py create mode 100644 src/blueink/subclients/subclient.py create mode 100644 src/blueink/subclients/template.py diff --git a/src/blueink/__init__.py b/src/blueink/__init__.py index e2e9e23..22446fe 100644 --- a/src/blueink/__init__.py +++ b/src/blueink/__init__.py @@ -1,7 +1,7 @@ from requests import exceptions -from . import constants from .client import Client from .bundle_helper import BundleHelper - -__all__ = ['Client', 'BundleHelper', 'exceptions', 'constants'] +from .person_helper import PersonHelper +from . import constants +__all__ = ['Client', 'BundleHelper', 'PersonHelper', 'exceptions', 'constants'] diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index 9c6095e..5194cf9 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -69,38 +69,6 @@ def add_document_by_url(self, url: str, **additional_data) -> str: self._documents[document.key] = document return document.key - # DEPRECATED, FILE HANDLE IS NOT CLOSED - # def add_document_by_file(self, file: io.BufferedReader, file_name: str, **additional_data) -> str: - # """ - # Add a document via url, with unique key. - # :param file_name: - # :param file: - # :param additional_data: Optional and will append any additional kwargs to the json of the document - # :return: - # """ - # - # file_index = len(self.files) - # - # if type(file) == io.BufferedReader and file.readable(): - # self.files.append({'file': file, "filename": file_name}) - # else: - # raise ValueError(f"File unreadable.") - # - # document = Document.create(file_index=file_index, **additional_data) - # self._documents[document.key] = document - # return document.key - - # # DEPRECATED, FILE HANDLE IS NOT CLOSED - # def add_document_by_path(self, file_path: str, **additional_data) -> str: - # """ - # Add a document via url, returns generated unique key. - # :param file_path: - # :param additional_data: Optional and will append any additional kwargs to the json of the document - # :return: Document instance - # """ - # - # file = open(file_path, 'rb') - # return self.add_document_by_file(file, file.name, **additional_data) def add_document_by_path(self, file_path: str, **additional_data) -> str: filename = basename(file_path) diff --git a/src/blueink/client.py b/src/blueink/client.py index 774d643..5a23abd 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -1,32 +1,15 @@ -import io -import json from os import environ -from typing import List -from munch import Munch - -from . import endpoints -from .bundle_helper import BundleHelper -from .constants import ( - BUNDLE_STATUS, +from src.blueink.constants import ( DEFAULT_BASE_URL, ENV_BLUEINK_API_URL, ENV_BLUEINK_PRIVATE_API_KEY ) -from .paginator import PaginatedIterator -from .person_helper import PersonHelper -from .request_helper import NormalizedResponse, RequestHelper - - -def _build_params(page: int = None, per_page: int = None, **query_params): - params = dict(**query_params) - if page is not None: # page could be zero, although Blueink pagination is 1-indexed - params["page"] = page - - if per_page: - params["per_page"] = per_page - - return params +from src.blueink.request_helper import RequestHelper +from src.blueink.subclients.bundle import BundleSubClient +from src.blueink.subclients.packet import PacketSubClient +from src.blueink.subclients.person import PersonSubClient +from src.blueink.subclients.template import TemplateSubClient class Client: @@ -69,478 +52,9 @@ def __init__(self, private_api_key: str = None, base_url: str = None, self._request_helper = RequestHelper(private_api_key, raise_exceptions) - self.bundles = self._Bundles(base_url, self._request_helper) - self.persons = self._Persons(base_url, self._request_helper) - self.packets = self._Packets(base_url, self._request_helper) - self.templates = self._Templates(base_url, self._request_helper) - - class _SubClient: - def __init__(self, base_url: str, requests_helper: RequestHelper): - self._base_url = base_url - self._requests = requests_helper - - def build_url(self, endpoint: str, **kwargs): - """Shortcut to build a URL using endpoints.URLBuilder - - Args: - endpoint: one of the API endpoints, e.g. endpoints.BUNDLES.create - **kwargs: the arg name should be one of the keys in endpoints. - interpolations, and the arg value will be substituted for the named - placeholder in the endpoint str - - Returns: - The URL as a str - - Raises: - ValueError if one of the kwargs is not a valid endpoint - interpolation key - """ - # All of our current endpoints take 1 parameter, max - if len(kwargs) > 1: - raise ValueError('Only one interpolation parameter is allowed') - - try: - url = endpoints.URLBuilder(self._base_url, endpoint).build(**kwargs) - except KeyError: - arg_name = list(kwargs.keys())[0] - raise ValueError(f'Invalid substitution argument "{arg_name}"' - f' provided for endpoint "{endpoint}"') - - return url - - class _Bundles(_SubClient): - def _prepare_files(self, file_list: [io.BufferedReader]): - if isinstance(file_list, dict): - file_list = [file_list] - - files_data = [] - if file_list: - for idx, file_dict in enumerate(file_list): - if "file" in file_dict: - print("Actual File") - fh = file_dict["file"] - if not isinstance(fh, io.BufferedReader): - raise ValueError( - f"Bad type for file {idx}. Expected an io.BufferedReader" - f" (e.g. an open file handle)" - ) - field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), - fh, - file_dict.get("content_type")))) - elif "file_b64" in file_dict: - print("B64 represented File") - - b64 = file_dict["file_b64"] - field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), - b64, - file_dict.get("content_type")))) - - return files_data - - def create(self, data: dict, - files: List[io.BufferedReader] = []) -> NormalizedResponse: - """ Post a Bundle to the BlueInk application. - - Args: - data: raw data for Bundle, expressed as a python dict - files: list of file-like objects - - Returns: - NormalizedResponse object - """ - if not data: - raise ValueError("data is required") - - url = self.build_url(endpoints.BUNDLES.CREATE) - - if not files: - response = self._requests.post(url, json=data) - else: - files_data = self._prepare_files(files) - if not files_data: - raise ValueError("No valid file data provided") - - bundle_request_data = {"bundle_request": json.dumps(data)} - - response = self._requests.post(url, - data=bundle_request_data, - files=files_data) - - return response - - def create_from_bundle_helper(self, - bdl_helper: BundleHelper) -> NormalizedResponse: - """ Post a Bundle to the BlueInk application. - - Provided as a convenience to simplify posting of a Bundle. This is the - recommended way to create a Bundle. - - Args: - bdl_helper: BundleHelper that has been configured as desired. - - Returns: - NormalizedResponse object - - """ - data = bdl_helper.as_data() - files = bdl_helper.files - return self.create(data=data, files=files) - - def paged_list(self, page: int = 1, per_page: int = 50, - related_data: bool = False, **query_params) -> PaginatedIterator: - """Returns an iterable object such that you may lazily fetch a number of - Bundles - - Typical Usage: - for page in client.bundles.paged_list(): - page.body -> munch of json - - Args: - page: what page to start iterator at - per_page: max number of bundles per page - related_data: toggles whether or not to provide metadata along with - bundles (events, files, data) - - Returns: - PaginatedIterator object, compliant with python iterables - """ - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - related_data=related_data, - **query_params) - return iterator - - def list(self, page: int = None, per_page: int = None, - related_data: bool = False, **query_params) -> NormalizedResponse: - """ Returns a list of bundles - - Args: - page: which page to fetch - per_page: how many bundles to fetch - related_data: (default false), returns events, files, data if true - query_params: Additional query params to be put onto the request - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.BUNDLES.LIST) - response = self._requests.get(url, - params=_build_params(page, - per_page, - **query_params)) - - if related_data: - for bundle in response.data: - self._attach_additional_data(bundle) - - return response - - def _attach_additional_data(self, bundle): - if type(bundle) == Munch and bundle.id is not None: - bundle_id = bundle.id - - events_response = self.list_events(bundle_id) - if events_response.status == 200: - bundle.events = events_response.data - - if bundle.status == BUNDLE_STATUS.COMPLETE: - files_response = self.list_files(bundle_id) - bundle.files = files_response.data - - data_response = self.list_data(bundle_id) - bundle.data = data_response.data - - def retrieve(self, bundle_id: str, - related_data: bool = False) -> NormalizedResponse: - """Request a single bundle - - Args: - bundle_id: bundle slug - related_data: (default false), returns events, files, data if true - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.BUNDLES.RETRIEVE, bundle_id=bundle_id) - response = self._requests.get(url) - - if related_data: - bundle = response.data - self._attach_additional_data(bundle) - - return response - - def cancel(self, bundle_id: str) -> NormalizedResponse: - """Cancel a bundle given bundle slug - - Args: - bundle_id: denotes which bundle to cancel - - Returns: - NormalizedResponse object - - """ - url = self.build_url(endpoints.BUNDLES.CANCEL, bundle_id=bundle_id) - return self._request.put(url) - - def list_events(self, bundle_id: str) -> NormalizedResponse: - """Return a list of events for the supplied bundle corresponding to the id - - Args: - bundle_id: which bundle to return events for - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.BUNDLES.LIST_EVENTS, bundle_id=bundle_id) - return self._requests.get(url) - - def list_files(self, bundle_id: str) -> NormalizedResponse: - """Return a list of files for the supplied bundle corresponding to the id - - Args: - bundle_id: which bundle to return files for - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.BUNDLES.LIST_FILES, bundle_id=bundle_id) - return self._requests.get(url) - - def list_data(self, bundle_id: str) -> NormalizedResponse: - """Return a data for the supplied bundle corresponding to the id - - Args: - bundle_id: which bundle to return data for - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.BUNDLES.LIST_DATA, bundle_id=bundle_id) - return self._requests.get(url) - - class _Persons(_SubClient): - def create(self, data: dict, **kwargs) -> NormalizedResponse: - """Create a person (eg. signer) record. - - Args: - data: A dictionary definition of a person - - Returns: - NormalizedResponse object - """ - if "name" not in data or not data["name"]: - raise ValueError("A name is required to create a Person") - - # Merge the kwargs with the given data - data = {**data, **kwargs} - - url = self.build_url(endpoints.PERSONS.CREATE) - return self._requests.post(url, json=data) - - def create_from_person_helper(self, person_helper: PersonHelper, - **kwargs) -> NormalizedResponse: - """Create a person using PersonHelper convenience object - - Args: - person_helper: PersonHelper setup of a person - - Return: - NormalizedResponse object - """ - return self.create(person_helper.as_dict(**kwargs)) - - def paged_list(self, page: int = 1, per_page: int = 50, - **query_params) -> PaginatedIterator: - """Return an iterable object such that you may lazily fetch a number of - Persons (signers) - - Typical Usage: - for page in client.persons.paged_list(): - page.body -> munch of json - - Args: - page: start page (default 1) - per_page: max # of results per page (default 50) - query_params: Additional query params to be put onto the request - - Returns: - PaginatedIterator object - """ - - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - **query_params) - return iterator - - def list(self, page: int = None, per_page: int = None, - **query_params) -> NormalizedResponse: - """Return a list of persons (signers). - - Args: - page: - per_page: - query_params: Additional query params to be put onto the request - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.PERSONS.LIST) - return self._requests.get(url, - params=_build_params(page, - per_page, - **query_params)) - - def retrieve(self, person_id: str) -> NormalizedResponse: - """Retrieve details on a singular person - - Args: - person_id: identifying which signer to retrieve - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.PERSONS.RETRIEVE, person_id=person_id) - return self._requests.get(url) - - def update(self, person_id: str, data: dict, - partial: bool = False) -> NormalizedResponse: - """Update a Person (signer)'s record - - Args: - person_id: - data: a dictionary representation of person's data - partial: Whether to do a partial update - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.PERSONS.UPDATE, person_id=person_id) - if partial: - response = self._requests.patch(url, json=data) - else: - response = self._requests.put(url, json=data) - return response - - def delete(self, person_id: str) -> NormalizedResponse: - """Delete a person (signer) - - Args: - person_id: - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.PERSONS.DELETE, person_id=person_id) - return self._requests.delete(url) - - class _Packets(_SubClient): - def update(self, packet_id: str, data: dict) -> NormalizedResponse: - """Update a Packet - - Note: this always performs a partial update (PATCH) because that is - the only method supported by the Blueink API for this endpoint - - Args: - packet_id: the ID of the Packet - data: the updated field values for the Packet - - Returns: - A NormalizedResponse, with the updated packet as `data` - - Raises: - exceptions.RequestException (or a more specific exception class) - if an error occured - """ - url = self.build_url(endpoints.PACKETS.UPDATE, packet_id=packet_id) - return self._requests.patch(url, json=data) - - def embed_url(self, packet_id: str) -> NormalizedResponse: - """Create an embedded signing URL - - deliver_via on the Packet must be set to "embed" for this request - to succeed. - - Args: - packet_id: the ID of the Packet. - - Returns: - A NormalizedResponse - """ - url = self.build_url(endpoints.PACKETS.EMBED_URL, packet_id=packet_id) - return self._requests.post(url) - - def retrieve_coe(self, packet_id: str) -> NormalizedResponse: - url = self.build_url(endpoints.PACKETS.RETRIEVE_COE, packet_id=packet_id) - return self._requests.get(url) - - def remind(self, packet_id: str) -> NormalizedResponse: - """Send a reminder to this Packet - - Args: - packet_id: the ID of the Packet - - Returns: - A NormalizedResponse - """ - url = self.build_url(endpoints.PACKETS.REMIND, packet_id=packet_id) - self._requests.put(url) - - class _Templates(_SubClient): - def __init__(self, base_url, private_api_key): - super().__init__(base_url, private_api_key) - - def paged_list(self, page: int = 1, per_page: int = 50, - **query_params) -> PaginatedIterator: - """return an iterable object containing a list of templates - - Typical Usage: - for page in client.templates.paged_list(): - page.body -> munch of json - - Args: - page: start page (default 1) - per_page: max # of results per page (default 50) - query_params: Additional query params to be put onto the request - - Returns: - PaginatedIterator object - """ - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - **query_params) - return iterator - - def list(self, page: int = None, per_page: int = None, - **query_params) -> NormalizedResponse: - """Return a list of Templates. - - Args: - page: - per_page: - query_params: Additional query params to be put onto the request - - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.TEMPLATES.LIST) - return self._requests.get(url, params=_build_params(page, - per_page, - **query_params)) - - def retrieve(self, template_id: str) -> NormalizedResponse: - """Return a singular Template by id. + self.bundles = BundleSubClient(base_url, self._request_helper) + self.persons = PersonSubClient(base_url, self._request_helper) + self.packets = PacketSubClient(base_url, self._request_helper) + self.templates = TemplateSubClient(base_url, self._request_helper) - Args: - template_id: - Returns: - NormalizedResponse object - """ - url = self.build_url(endpoints.TEMPLATES.RETRIEVE, template_id=template_id) - return self._requests.get(url) diff --git a/src/blueink/subclients/__init__.py b/src/blueink/subclients/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/blueink/subclients/bundle.py b/src/blueink/subclients/bundle.py new file mode 100644 index 0000000..fa48818 --- /dev/null +++ b/src/blueink/subclients/bundle.py @@ -0,0 +1,227 @@ +import io +import json +from typing import List + +from munch import Munch + +from src.blueink import endpoints +from src.blueink.bundle_helper import BundleHelper +from src.blueink.constants import BUNDLE_STATUS +from src.blueink.paginator import PaginatedIterator +from src.blueink.request_helper import NormalizedResponse +from src.blueink.subclients.subclient import SubClient + + +class BundleSubClient(SubClient): + def _prepare_files(self, file_list: [io.BufferedReader]): + if isinstance(file_list, dict): + file_list = [file_list] + + files_data = [] + if file_list: + for idx, file_dict in enumerate(file_list): + if "file" in file_dict: + print("Actual File") + fh = file_dict["file"] + if not isinstance(fh, io.BufferedReader): + raise ValueError( + f"Bad type for file {idx}. Expected an io.BufferedReader" + f" (e.g. an open file handle)" + ) + field_name = f"files[{idx}]" + files_data.append((field_name, (file_dict.get("filename"), + fh, + file_dict.get("content_type")))) + elif "file_b64" in file_dict: + print("B64 represented File") + + b64 = file_dict["file_b64"] + field_name = f"files[{idx}]" + files_data.append((field_name, (file_dict.get("filename"), + b64, + file_dict.get("content_type")))) + + return files_data + + def create(self, data: dict, + files: List[io.BufferedReader] = []) -> NormalizedResponse: + """ Post a Bundle to the BlueInk application. + + Args: + data: raw data for Bundle, expressed as a python dict + files: list of file-like objects + + Returns: + NormalizedResponse object + """ + if not data: + raise ValueError("data is required") + + url = self.build_url(endpoints.BUNDLES.CREATE) + + if not files: + response = self._requests.post(url, json=data) + else: + files_data = self._prepare_files(files) + if not files_data: + raise ValueError("No valid file data provided") + + bundle_request_data = {"bundle_request": json.dumps(data)} + + response = self._requests.post(url, + data=bundle_request_data, + files=files_data) + + return response + + def create_from_bundle_helper(self, + bdl_helper: BundleHelper) -> NormalizedResponse: + """ Post a Bundle to the BlueInk application. + + Provided as a convenience to simplify posting of a Bundle. This is the + recommended way to create a Bundle. + + Args: + bdl_helper: BundleHelper that has been configured as desired. + + Returns: + NormalizedResponse object + + """ + data = bdl_helper.as_data() + files = bdl_helper.files + return self.create(data=data, files=files) + + def paged_list(self, page: int = 1, per_page: int = 50, + related_data: bool = False, **query_params) -> PaginatedIterator: + """Returns an iterable object such that you may lazily fetch a number of + Bundles + + Typical Usage: + for page in client.bundles.paged_list(): + page.body -> munch of json + + Args: + page: what page to start iterator at + per_page: max number of bundles per page + related_data: toggles whether or not to provide metadata along with + bundles (events, files, data) + + Returns: + PaginatedIterator object, compliant with python iterables + """ + iterator = PaginatedIterator(paged_api_function=self.list, + page=page, + per_page=per_page, + related_data=related_data, + **query_params) + return iterator + + def list(self, page: int = None, per_page: int = None, + related_data: bool = False, **query_params) -> NormalizedResponse: + """ Returns a list of bundles + + Args: + page: which page to fetch + per_page: how many bundles to fetch + related_data: (default false), returns events, files, data if true + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.BUNDLES.LIST) + response = self._requests.get(url, + params=self.build_params(page, + per_page, + **query_params)) + + if related_data: + for bundle in response.data: + self._attach_additional_data(bundle) + + return response + + def _attach_additional_data(self, bundle): + if type(bundle) == Munch and bundle.id is not None: + bundle_id = bundle.id + + events_response = self.list_events(bundle_id) + if events_response.status == 200: + bundle.events = events_response.data + + if bundle.status == BUNDLE_STATUS.COMPLETE: + files_response = self.list_files(bundle_id) + bundle.files = files_response.data + + data_response = self.list_data(bundle_id) + bundle.data = data_response.data + + def retrieve(self, bundle_id: str, + related_data: bool = False) -> NormalizedResponse: + """Request a single bundle + + Args: + bundle_id: bundle slug + related_data: (default false), returns events, files, data if true + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.BUNDLES.RETRIEVE, bundle_id=bundle_id) + response = self._requests.get(url) + + if related_data: + bundle = response.data + self._attach_additional_data(bundle) + + return response + + def cancel(self, bundle_id: str) -> NormalizedResponse: + """Cancel a bundle given bundle slug + + Args: + bundle_id: denotes which bundle to cancel + + Returns: + NormalizedResponse object + + """ + url = self.build_url(endpoints.BUNDLES.CANCEL, bundle_id=bundle_id) + return self._request.put(url) + + def list_events(self, bundle_id: str) -> NormalizedResponse: + """Return a list of events for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return events for + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.BUNDLES.LIST_EVENTS, bundle_id=bundle_id) + return self._requests.get(url) + + def list_files(self, bundle_id: str) -> NormalizedResponse: + """Return a list of files for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return files for + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.BUNDLES.LIST_FILES, bundle_id=bundle_id) + return self._requests.get(url) + + def list_data(self, bundle_id: str) -> NormalizedResponse: + """Return a data for the supplied bundle corresponding to the id + + Args: + bundle_id: which bundle to return data for + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.BUNDLES.LIST_DATA, bundle_id=bundle_id) + return self._requests.get(url) diff --git a/src/blueink/subclients/packet.py b/src/blueink/subclients/packet.py new file mode 100644 index 0000000..b8ff17a --- /dev/null +++ b/src/blueink/subclients/packet.py @@ -0,0 +1,56 @@ +from src.blueink import endpoints +from src.blueink.request_helper import NormalizedResponse +from src.blueink.subclients.subclient import SubClient + + +class PacketSubClient(SubClient): + def update(self, packet_id: str, data: dict) -> NormalizedResponse: + """Update a Packet + + Note: this always performs a partial update (PATCH) because that is + the only method supported by the Blueink API for this endpoint + + Args: + packet_id: the ID of the Packet + data: the updated field values for the Packet + + Returns: + A NormalizedResponse, with the updated packet as `data` + + Raises: + exceptions.RequestException (or a more specific exception class) + if an error occured + """ + url = self.build_url(endpoints.PACKETS.UPDATE, packet_id=packet_id) + return self._requests.patch(url, json=data) + + def embed_url(self, packet_id: str) -> NormalizedResponse: + """Create an embedded signing URL + + deliver_via on the Packet must be set to "embed" for this request + to succeed. + + Args: + packet_id: the ID of the Packet. + + Returns: + A NormalizedResponse + """ + url = self.build_url(endpoints.PACKETS.EMBED_URL, packet_id=packet_id) + return self._requests.post(url) + + def retrieve_coe(self, packet_id: str) -> NormalizedResponse: + url = self.build_url(endpoints.PACKETS.RETRIEVE_COE, packet_id=packet_id) + return self._requests.get(url) + + def remind(self, packet_id: str) -> NormalizedResponse: + """Send a reminder to this Packet + + Args: + packet_id: the ID of the Packet + + Returns: + A NormalizedResponse + """ + url = self.build_url(endpoints.PACKETS.REMIND, packet_id=packet_id) + self._requests.put(url) diff --git a/src/blueink/subclients/person.py b/src/blueink/subclients/person.py new file mode 100644 index 0000000..cd99477 --- /dev/null +++ b/src/blueink/subclients/person.py @@ -0,0 +1,122 @@ +from src.blueink import endpoints +from src.blueink.paginator import PaginatedIterator +from src.blueink.person_helper import PersonHelper +from src.blueink.request_helper import NormalizedResponse +from src.blueink.subclients.subclient import SubClient + + +class PersonSubClient(SubClient): + def create(self, data: dict, **kwargs) -> NormalizedResponse: + """Create a person (eg. signer) record. + + Args: + data: A dictionary definition of a person + + Returns: + NormalizedResponse object + """ + if "name" not in data or not data["name"]: + raise ValueError("A name is required to create a Person") + + # Merge the kwargs with the given data + data = {**data, **kwargs} + + url = self.build_url(endpoints.PERSONS.CREATE) + return self._requests.post(url, json=data) + + def create_from_person_helper(self, person_helper: PersonHelper, + **kwargs) -> NormalizedResponse: + """Create a person using PersonHelper convenience object + + Args: + person_helper: PersonHelper setup of a person + + Return: + NormalizedResponse object + """ + return self.create(person_helper.as_dict(**kwargs)) + + def paged_list(self, page: int = 1, per_page: int = 50, + **query_params) -> PaginatedIterator: + """Return an iterable object such that you may lazily fetch a number of + Persons (signers) + + Typical Usage: + for page in client.persons.paged_list(): + page.body -> munch of json + + Args: + page: start page (default 1) + per_page: max # of results per page (default 50) + query_params: Additional query params to be put onto the request + + Returns: + PaginatedIterator object + """ + + iterator = PaginatedIterator(paged_api_function=self.list, + page=page, + per_page=per_page, + **query_params) + return iterator + + def list(self, page: int = None, per_page: int = None, + **query_params) -> NormalizedResponse: + """Return a list of persons (signers). + + Args: + page: + per_page: + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.PERSONS.LIST) + return self._requests.get(url, + params=self.build_params(page, + per_page, + **query_params)) + + def retrieve(self, person_id: str) -> NormalizedResponse: + """Retrieve details on a singular person + + Args: + person_id: identifying which signer to retrieve + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.PERSONS.RETRIEVE, person_id=person_id) + return self._requests.get(url) + + def update(self, person_id: str, data: dict, + partial: bool = False) -> NormalizedResponse: + """Update a Person (signer)'s record + + Args: + person_id: + data: a dictionary representation of person's data + partial: Whether to do a partial update + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.PERSONS.UPDATE, person_id=person_id) + if partial: + response = self._requests.patch(url, json=data) + else: + response = self._requests.put(url, json=data) + return response + + def delete(self, person_id: str) -> NormalizedResponse: + """Delete a person (signer) + + Args: + person_id: + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.PERSONS.DELETE, person_id=person_id) + return self._requests.delete(url) diff --git a/src/blueink/subclients/subclient.py b/src/blueink/subclients/subclient.py new file mode 100644 index 0000000..8a5f090 --- /dev/null +++ b/src/blueink/subclients/subclient.py @@ -0,0 +1,50 @@ +from src.blueink import endpoints +from src.blueink.request_helper import RequestHelper + + +class SubClient: + def __init__(self, base_url: str, requests_helper: RequestHelper): + self._base_url = base_url + self._requests = requests_helper + + def build_url(self, endpoint: str, **kwargs): + """Shortcut to build a URL using endpoints.URLBuilder + + Args: + endpoint: one of the API endpoints, e.g. endpoints.BUNDLES.create + **kwargs: the arg name should be one of the keys in endpoints. + interpolations, and the arg value will be substituted for the named + placeholder in the endpoint str + + Returns: + The URL as a str + + Raises: + ValueError if one of the kwargs is not a valid endpoint + interpolation key + """ + # All of our current endpoints take 1 parameter, max + if len(kwargs) > 1: + raise ValueError('Only one interpolation parameter is allowed') + + try: + url = endpoints.URLBuilder(self._base_url, endpoint).build(**kwargs) + except KeyError: + arg_name = list(kwargs.keys())[0] + raise ValueError(f'Invalid substitution argument "{arg_name}"' + f' provided for endpoint "{endpoint}"') + + return url + + @staticmethod + def build_params(page: int = None, per_page: int = None, **query_params): + params = dict(**query_params) + + # page could be zero, although Blueink pagination is 1-indexed + if page is not None: + params["page"] = page + + if per_page: + params["per_page"] = per_page + + return params diff --git a/src/blueink/subclients/template.py b/src/blueink/subclients/template.py new file mode 100644 index 0000000..aca37b5 --- /dev/null +++ b/src/blueink/subclients/template.py @@ -0,0 +1,60 @@ +from src.blueink import endpoints +from src.blueink.paginator import PaginatedIterator +from src.blueink.request_helper import NormalizedResponse +from src.blueink.subclients.subclient import SubClient + + +class TemplateSubClient(SubClient): + def __init__(self, base_url, private_api_key): + super().__init__(base_url, private_api_key) + + def paged_list(self, page: int = 1, per_page: int = 50, + **query_params) -> PaginatedIterator: + """return an iterable object containing a list of templates + + Typical Usage: + for page in client.templates.paged_list(): + page.body -> munch of json + + Args: + page: start page (default 1) + per_page: max # of results per page (default 50) + query_params: Additional query params to be put onto the request + + Returns: + PaginatedIterator object + """ + iterator = PaginatedIterator(paged_api_function=self.list, + page=page, + per_page=per_page, + **query_params) + return iterator + + def list(self, page: int = None, per_page: int = None, + **query_params) -> NormalizedResponse: + """Return a list of Templates. + + Args: + page: + per_page: + query_params: Additional query params to be put onto the request + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.TEMPLATES.LIST) + return self._requests.get(url, params=self.build_params(page, + per_page, + **query_params)) + + def retrieve(self, template_id: str) -> NormalizedResponse: + """Return a singular Template by id. + + Args: + template_id: + + Returns: + NormalizedResponse object + """ + url = self.build_url(endpoints.TEMPLATES.RETRIEVE, template_id=template_id) + return self._requests.get(url) diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py index a14bae4..0d4610b 100644 --- a/src/blueink/tests/test_client.py +++ b/src/blueink/tests/test_client.py @@ -2,10 +2,7 @@ from os.path import basename from munch import Munch - -from src.blueink import Client -from src.blueink.bundle_helper import BundleHelper -from src.blueink.person_helper import PersonHelper +from src.blueink import Client, BundleHelper, PersonHelper from src.blueink.utils.testcase import TestCase From 34754763452a48bbca9c50c1ca1992a8f6412e0d Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 14:24:15 -0700 Subject: [PATCH 13/20] BIC-3219 Stubbed out Webhook support --- src/blueink/client.py | 2 + src/blueink/endpoints.py | 23 ++++++++++ src/blueink/model/webhook.py | 19 ++++++++ src/blueink/subclients/webhook.py | 74 +++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 src/blueink/model/webhook.py create mode 100644 src/blueink/subclients/webhook.py diff --git a/src/blueink/client.py b/src/blueink/client.py index 5a23abd..88dbea0 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -10,6 +10,7 @@ from src.blueink.subclients.packet import PacketSubClient from src.blueink.subclients.person import PersonSubClient from src.blueink.subclients.template import TemplateSubClient +# from src.blueink.subclients.webhook import WebhookSubClient class Client: @@ -56,5 +57,6 @@ def __init__(self, private_api_key: str = None, base_url: str = None, self.persons = PersonSubClient(base_url, self._request_helper) self.packets = PacketSubClient(base_url, self._request_helper) self.templates = TemplateSubClient(base_url, self._request_helper) + # self.webhooks = WebhookSubClient(base_url, self._request_helper) diff --git a/src/blueink/endpoints.py b/src/blueink/endpoints.py index 68307cf..70fdc6e 100644 --- a/src/blueink/endpoints.py +++ b/src/blueink/endpoints.py @@ -36,6 +36,29 @@ class TEMPLATES: RETRIEVE = "/templates/${template_id}/" +# class WEBHOOKS: +# CREATE = "/webhooks/" +# LIST = "/webhooks/" +# RETRIEVE = "/webhooks/${webhook_id}/" +# UPDATE = "/webhooks/${webhook_id}/" +# DELETE = "/webhooks/${webhook_id}/" +# +# CREATE_HEADER = "/webhooks/headers/" +# LIST_HEADERS = "/webhooks/headers/" +# RETRIEVE_HEADER = "/webhooks/headers/${webhook_header_id}/" +# UPDATE_HEADER = "/webhooks/headers/${webhook_header_id}/" +# DELETE_HEADER = "/webhooks/headers/${webhook_header_id}/" +# +# LIST_EVENTS = "/webhooks/events/" +# RETRIEVE_EVENT = "/webhooks/events/${webhook_event_id}/" +# +# LIST_DELIVERIES = "/webhooks/deliveries/" +# RETRIEVE_DELIVERY = "/webhooks/deliveries/${webhook_delivery_id}/" +# +# RETRIEVE_SECRET = "/webhooks/secret/" +# REGENERATE_SECRET = "/webhooks/secret/regenerate/" + + class URLBuilder: def __init__(self, base_url, endpoint: str): self._base_url = base_url diff --git a/src/blueink/model/webhook.py b/src/blueink/model/webhook.py new file mode 100644 index 0000000..3239e0e --- /dev/null +++ b/src/blueink/model/webhook.py @@ -0,0 +1,19 @@ +from typing import List, Optional +from pydantic import BaseModel, validator + + +class WebhookExtraHeader(BaseModel): + id: str + webhook: str + name: str + value: str + order: int + + +class Webhook(BaseModel): + id: str + url: str + enabled: bool + json: bool + event_types: List[str] + extra_header: List[WebhookExtraHeader] diff --git a/src/blueink/subclients/webhook.py b/src/blueink/subclients/webhook.py new file mode 100644 index 0000000..e1a9c59 --- /dev/null +++ b/src/blueink/subclients/webhook.py @@ -0,0 +1,74 @@ +from typing import List + +from src.blueink.model.webhook import WebhookExtraHeader +from src.blueink.subclients.subclient import SubClient + + +class WebhookSubClient(SubClient): + def __init__(self, base_url, private_api_key): + super().__init__(base_url, private_api_key) + + # ---------- + # Webhooks + # ---------- + def create_webhook(self, url: str, event_types:List[str], + extra_headers: List[WebhookExtraHeader], enabled: bool = True, + json: bool = True): + raise RuntimeError("Not Implemented") + + def list_webhooks(self): + raise RuntimeError("Not Implemented") + + def retrieve_webhook(self, webhook_id: str): + raise RuntimeError("Not Implemented") + + def delete_webhook(self, webhook_id: str): + raise RuntimeError("Not Implemented") + + def update_webhook(self, webhook_id: str, **data): + raise RuntimeError("Not Implemented") + + # ---------- + # Extra Header + # ---------- + def create_header(self, webhook_id: str, name: str, value: str, order: int): + raise RuntimeError("Not Implemented") + + def list_headers(self): + raise RuntimeError("Not Implemented") + + def retrieve_header(self, header_id: str): + raise RuntimeError("Not Implemented") + + def delete_header(self, header_id: str): + raise RuntimeError("Not Implemented") + + def update_header(self, header_id: str, **data): + raise RuntimeError("Not Implemented") + + # ---------- + # Events + # ---------- + def list_events(self): + raise RuntimeError("Not Implemented") + + def retrieve_event(self, event_id: str): + raise RuntimeError("Not Implemented") + + # ---------- + # Deliveries + # ---------- + def list_deliveries(self): + raise RuntimeError("Not Implemented") + + def retrieve_delivery(self, event_id: str): + raise RuntimeError("Not Implemented") + + # ---------- + # Secret + # ---------- + def retrieve_secret(self): + raise RuntimeError("Not Implemented") + + def regenerate_secret(self): + raise RuntimeError("Not Implemented") From 2e81663936f46347fe4e250be8a6f3b54784a292 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 16:33:19 -0700 Subject: [PATCH 14/20] readme adjustments --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75e37d6..da74c51 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ includes examples for many common use cases. Additional resources that might be useful include: -* Examples in the `examples/` directory of this repository +* Examples at [blueink-client-python-examples](https://github.com/blueinkhq/blueink-client-python-examples) +repo on GitHub * The detailed [Blueink API Documentation](https://blueink.com/r/api-docs/), for details on the data returned by each API call. @@ -55,6 +56,14 @@ from blueink import Client client = Client("YOUR_PRIVATE_API_KEY") ``` +The Client also has two modes of operations. By default the Client will raise HTTPError +exceptions whenever there's an issue between the client and server (eg. HTTP4xx, +HTTP5xx errors). These come from the `requests` module. If within your application +you already handle exceptions coming out of `requests` then you should be good. +If you set `raise_exceptions = False` then these will be returned as +`NormalizedResponse` objects which are also used for successful communications. See +below for information about these objects. + ### Making API Calls Making API calls with a client instance is easy. For example, to retrieve a list of From a0d74ced1c63b5ce92146c2f14e258f171dec01f Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Fri, 30 Sep 2022 16:33:53 -0700 Subject: [PATCH 15/20] comment out webhook endpoints until implemented in sep branch --- src/blueink/endpoints.py | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/blueink/endpoints.py b/src/blueink/endpoints.py index 70fdc6e..8275aaf 100644 --- a/src/blueink/endpoints.py +++ b/src/blueink/endpoints.py @@ -36,27 +36,27 @@ class TEMPLATES: RETRIEVE = "/templates/${template_id}/" -# class WEBHOOKS: -# CREATE = "/webhooks/" -# LIST = "/webhooks/" -# RETRIEVE = "/webhooks/${webhook_id}/" -# UPDATE = "/webhooks/${webhook_id}/" -# DELETE = "/webhooks/${webhook_id}/" -# -# CREATE_HEADER = "/webhooks/headers/" -# LIST_HEADERS = "/webhooks/headers/" -# RETRIEVE_HEADER = "/webhooks/headers/${webhook_header_id}/" -# UPDATE_HEADER = "/webhooks/headers/${webhook_header_id}/" -# DELETE_HEADER = "/webhooks/headers/${webhook_header_id}/" -# -# LIST_EVENTS = "/webhooks/events/" -# RETRIEVE_EVENT = "/webhooks/events/${webhook_event_id}/" -# -# LIST_DELIVERIES = "/webhooks/deliveries/" -# RETRIEVE_DELIVERY = "/webhooks/deliveries/${webhook_delivery_id}/" -# -# RETRIEVE_SECRET = "/webhooks/secret/" -# REGENERATE_SECRET = "/webhooks/secret/regenerate/" +class WEBHOOKS: + CREATE = "/webhooks/" + LIST = "/webhooks/" + RETRIEVE = "/webhooks/${webhook_id}/" + UPDATE = "/webhooks/${webhook_id}/" + DELETE = "/webhooks/${webhook_id}/" + + CREATE_HEADER = "/webhooks/headers/" + LIST_HEADERS = "/webhooks/headers/" + RETRIEVE_HEADER = "/webhooks/headers/${webhook_header_id}/" + UPDATE_HEADER = "/webhooks/headers/${webhook_header_id}/" + DELETE_HEADER = "/webhooks/headers/${webhook_header_id}/" + + LIST_EVENTS = "/webhooks/events/" + RETRIEVE_EVENT = "/webhooks/events/${webhook_event_id}/" + + LIST_DELIVERIES = "/webhooks/deliveries/" + RETRIEVE_DELIVERY = "/webhooks/deliveries/${webhook_delivery_id}/" + + RETRIEVE_SECRET = "/webhooks/secret/" + REGENERATE_SECRET = "/webhooks/secret/regenerate/" class URLBuilder: From bfbcb445620617f4518842b2c6d07503e1454c0c Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 4 Oct 2022 13:23:52 -0700 Subject: [PATCH 16/20] tests now poll for documents to be processed. --- src/blueink/bundle_helper.py | 6 ++--- src/blueink/tests/test_client.py | 43 +++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index 5194cf9..b922fcb 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -72,16 +72,14 @@ def add_document_by_url(self, url: str, **additional_data) -> str: def add_document_by_path(self, file_path: str, **additional_data) -> str: filename = basename(file_path) - file = open(file_path, 'rb') - b64str = b64encode(file.read()) - file.close() + with open(file_path, 'rb') as file: + b64str = b64encode(file.read()).decode("utf-8") return self.add_document_by_b64(filename, b64str, **additional_data) def add_document_by_b64(self, filename:str, b64str:str, **additional_data): file_index = len(self.files) - self.files.append({'file_b64': b64str, "filename": filename}) document = Document.create(file_index=file_index, **additional_data) print(f"doc -- {document.key}") diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py index 0d4610b..2df04f8 100644 --- a/src/blueink/tests/test_client.py +++ b/src/blueink/tests/test_client.py @@ -1,5 +1,6 @@ from base64 import b64encode from os.path import basename +from time import sleep from munch import Munch from src.blueink import Client, BundleHelper, PersonHelper @@ -37,7 +38,6 @@ class TestClient(TestCase): FIELD01_P = 1 FIELD01_EDITORS = [SIGNER01_KEY] - # Person Data PERSON_NAME = "JOHN DOE" @@ -53,7 +53,7 @@ class TestClient(TestCase): PERSON_PHONES = ["505 555 5555"] PERSON_EMAILS = ["johndoe@example.com"] - def _bundle_label(self, method:str): + def _bundle_label(self, method: str): if method == self.DOC_METHODS.PATH: return self.BUNDLE_LABEL_PATH elif method == self.DOC_METHODS.URL: @@ -81,7 +81,7 @@ def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): elif method == self.DOC_METHODS.B64: file = open(self.REAL_DOCUMENT_PATH, 'rb') filename = basename(self.REAL_DOCUMENT_PATH) - b64str = b64encode(file.read()) + b64str = b64encode(file.read()).decode("utf-8") file.close() doc01_key = bh.add_document_by_b64(filename, b64str) @@ -110,7 +110,7 @@ def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): return bh, signer01_key, field01_key - def _check_bundle_data(self, compiled_bundle:dict, signerkey, fieldkey): + def _check_bundle_data(self, compiled_bundle: dict, signerkey, fieldkey): self.assert_in("documents", compiled_bundle) self.assert_len(compiled_bundle["documents"], 1) @@ -134,6 +134,26 @@ def _check_bundle_data(self, compiled_bundle:dict, signerkey, fieldkey): self.assert_equal(compiled_bundle["packets"][0]["key"], signerkey) + def _poll_for_successful_file_processing(self, client: Client, bundle_id: str, + expected_document_count: int, + max_attempts=5, delay_between_seconds=5): + attempt = 0 + while attempt < max_attempts: + attempt = attempt + 1 + sleep(delay_between_seconds) + + resp = client.bundles.retrieve(bundle_id) + if resp.status != 200: + print(f"Failed to get bundle {bundle_id} on attempt {attempt}" + f" of {max_attempts}") + continue + + ndocs = len(resp.data["documents"]) + if ndocs == expected_document_count: + return True + + return False + def test_roundtrip_url(self): bh, sk, fk = self._create_test_bundle_helper( method=self.DOC_METHODS.URL @@ -143,6 +163,11 @@ def test_roundtrip_url(self): resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) + has_all_docs = self._poll_for_successful_file_processing(client, + resp.data.id, + 1) + self.assert_true(has_all_docs) + def test_roundtrip_b64(self): bh, sk, fk = self._create_test_bundle_helper( method=self.DOC_METHODS.B64 @@ -152,6 +177,11 @@ def test_roundtrip_b64(self): resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) + has_all_docs = self._poll_for_successful_file_processing(client, + resp.data.id, + 1) + self.assert_true(has_all_docs) + def test_roundtrip_path(self): bh, sk, fk = self._create_test_bundle_helper( method=self.DOC_METHODS.PATH @@ -161,6 +191,11 @@ def test_roundtrip_path(self): resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) + has_all_docs = self._poll_for_successful_file_processing(client, + resp.data.id, + 1) + self.assert_true(has_all_docs) + def test_person_create(self): ph = PersonHelper(name=self.PERSON_NAME, metadata=self.PERSON_METADATA, From fd72e4761936d883b7ad735f23d34b7231067404 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 4 Oct 2022 13:37:15 -0700 Subject: [PATCH 17/20] fix b64 / path issue --- src/blueink/bundle_helper.py | 5 +++-- src/blueink/model/bundles.py | 2 ++ src/blueink/subclients/bundle.py | 9 --------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index b922fcb..ceb8bf5 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -80,8 +80,9 @@ def add_document_by_path(self, file_path: str, **additional_data) -> str: def add_document_by_b64(self, filename:str, b64str:str, **additional_data): file_index = len(self.files) - self.files.append({'file_b64': b64str, "filename": filename}) - document = Document.create(file_index=file_index, **additional_data) + document = Document.create(filename=filename, + file_b64=b64str, + **additional_data) print(f"doc -- {document.key}") self._documents[document.key] = document return document.key diff --git a/src/blueink/model/bundles.py b/src/blueink/model/bundles.py index e90ca86..e4c75bd 100644 --- a/src/blueink/model/bundles.py +++ b/src/blueink/model/bundles.py @@ -151,6 +151,8 @@ class Document(BaseModel): # document related file_url: Optional[str] + filename: Optional[str] + file_b64: Optional[str] file_index: Optional[int] fields: Optional[List[Field]] diff --git a/src/blueink/subclients/bundle.py b/src/blueink/subclients/bundle.py index fa48818..03c9580 100644 --- a/src/blueink/subclients/bundle.py +++ b/src/blueink/subclients/bundle.py @@ -32,15 +32,6 @@ def _prepare_files(self, file_list: [io.BufferedReader]): files_data.append((field_name, (file_dict.get("filename"), fh, file_dict.get("content_type")))) - elif "file_b64" in file_dict: - print("B64 represented File") - - b64 = file_dict["file_b64"] - field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), - b64, - file_dict.get("content_type")))) - return files_data def create(self, data: dict, From 60395f3b328e61163be1097d664ae5c4e4122b87 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 4 Oct 2022 13:38:55 -0700 Subject: [PATCH 18/20] Comment out document by byte array due to not closing IO object. Do we want to keep this method around? --- src/blueink/bundle_helper.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index ceb8bf5..e039c1c 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -87,20 +87,20 @@ def add_document_by_b64(self, filename:str, b64str:str, **additional_data): self._documents[document.key] = document return document.key - def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, - **additional_data) -> str: - ''' - Add a document via url, with unique key. - :param byte_array: - :param file_name: - :param mime_type: - :param additional_data: Optional and will append any additional kwargs to the json of the document - :return: - ''' - - bytes = io.BytesIO(byte_array) - file = io.BufferedReader(bytes, len(byte_array)) - return self.add_document_by_file(file, file_name, **additional_data) + # def add_document_by_bytearray(self, byte_array: bytearray, file_name: str, + # **additional_data) -> str: + # ''' + # Add a document via url, with unique key. + # :param byte_array: + # :param file_name: + # :param mime_type: + # :param additional_data: Optional and will append any additional kwargs to the json of the document + # :return: + # ''' + # + # bytes = io.BytesIO(byte_array) + # file = io.BufferedReader(bytes, len(byte_array)) + # return self.add_document_by_file(file, file_name, **additional_data) def add_document_template(self, template_id: str, **additional_data) -> str: """ From eb469d9721702e3f2d74443a541a65f5e65980fa Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 4 Oct 2022 13:55:35 -0700 Subject: [PATCH 19/20] fixes to add document by template ID; include assignment/init val in constructor. --- src/blueink/bundle_helper.py | 82 ++++++++++++++++++++++---------- src/blueink/tests/test_client.py | 36 +++++++++++++- 2 files changed, 92 insertions(+), 26 deletions(-) diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index e039c1c..5124602 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -17,14 +17,14 @@ class BundleHelper: def __init__( - self, - label: str = None, - email_subject: str = None, - email_message: str = None, - in_order: bool = False, - is_test: bool = False, - custom_key: str = None, - team: str = None, + self, + label: str = None, + email_subject: str = None, + email_message: str = None, + in_order: bool = False, + is_test: bool = False, + custom_key: str = None, + team: str = None, ): """Helper class to aid building a Bundle. @@ -77,7 +77,7 @@ def add_document_by_path(self, file_path: str, **additional_data) -> str: return self.add_document_by_b64(filename, b64str, **additional_data) - def add_document_by_b64(self, filename:str, b64str:str, **additional_data): + def add_document_by_b64(self, filename: str, b64str: str, **additional_data): file_index = len(self.files) document = Document.create(filename=filename, @@ -102,22 +102,48 @@ def add_document_by_b64(self, filename:str, b64str:str, **additional_data): # file = io.BufferedReader(bytes, len(byte_array)) # return self.add_document_by_file(file, file_name, **additional_data) - def add_document_template(self, template_id: str, **additional_data) -> str: - """ - Create and add a template reference - :param template_id: - :param additional_data: Optional and will append any additional kwargs to the json of the template - :return:Template object + def add_document_template(self, template_id: str, + assignments: dict, + initial_field_values: dict, + **additional_data) -> str: + """Create and add a template reference + + Args: + template_id: Template UUID from BlueInk + assignments: dict going from Role to signer ID + initial_field_values: dict going from docfield key to initial value + + Returns: + document key """ + if template_id in self._documents.keys(): - raise RuntimeError(f'Document/Template with id {template_id} already added.') + raise RuntimeError( + f'Document/Template with id {template_id} already added.') + + assigns = [] + for role, signer in assignments.items(): + ref = TemplateRefAssignment.create(role=role, signer=signer) + assigns.append(ref) + + vals = [] + for field_key, init_val in initial_field_values.items(): + fieldval = TemplateRefFieldValue.create(key=field_key, + initial_value=init_val) + vals.append(fieldval) + + template = TemplateRef.create(template_id=template_id, + assignments=assigns, + field_values=vals, + **additional_data) - template = TemplateRef.create(template_id=template_id, **additional_data) self._documents[template.key] = template return template.key - def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, kind: str, - editors: List[str] = None, label: str = None, v_pattern: str = None, v_min: int = None, + def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, + kind: str, + editors: List[str] = None, label: str = None, v_pattern: str = None, + v_min: int = None, v_max: int = None, key=None, **additional_data): """Create and add a field to a particular document. @@ -154,8 +180,10 @@ def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, k self._documents[document_key].add_field(field) return field.key - def add_signer(self, name: str, email: str = None, phone: str = None, deliver_via: str = None, - person_id=None, auth_sms: bool = False, auth_selfie: bool = False, auth_id: bool = False, + def add_signer(self, name: str, email: str = None, phone: str = None, + deliver_via: str = None, + person_id=None, auth_sms: bool = False, auth_selfie: bool = False, + auth_id: bool = False, order: int = None, key=None, **additional_data): """Create and add a signer. With at least an email xor phone number. @@ -192,7 +220,8 @@ def add_signer(self, name: str, email: str = None, phone: str = None, deliver_vi self._packets[packet.key] = packet return packet.key - def assign_role(self, document_key: str, signer_key: str, role: str, **additional_data): + def assign_role(self, document_key: str, signer_key: str, role: str, + **additional_data): """Assign a signer to a particular role in a template Args: @@ -204,9 +233,11 @@ def assign_role(self, document_key: str, signer_key: str, role: str, **additiona if document_key not in self._documents: raise RuntimeError(f"No document found with key {document_key}!") if type(self._documents[document_key]) is not TemplateRef: - raise RuntimeError(f"Document found with key {document_key} is not a Template!") + raise RuntimeError( + f"Document found with key {document_key} is not a Template!") if signer_key not in self._packets: - raise RuntimeError(f"Signer {signer_key} does not have a corresponding packet") + raise RuntimeError( + f"Signer {signer_key} does not have a corresponding packet") assignment = TemplateRefAssignment.create(role, signer_key, **additional_data) self._documents[document_key].add_assignment(assignment) @@ -223,7 +254,8 @@ def set_value(self, document_key: str, key: str, value: str, **additional_data): if document_key not in self._documents: raise RuntimeError(f"No document found with key {document_key}!") if type(self._documents[document_key]) is not TemplateRef: - raise RuntimeError(f"Document found with key {document_key} is not a Template!") + raise RuntimeError( + f"Document found with key {document_key} is not a Template!") field_val = TemplateRefFieldValue.create(key, value, **additional_data) self._documents[document_key].field_values.append(field_val) diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py index 2df04f8..536fae7 100644 --- a/src/blueink/tests/test_client.py +++ b/src/blueink/tests/test_client.py @@ -11,7 +11,8 @@ class TestClient(TestCase): DOC_METHODS = Munch( PATH="PATH", URL="URL", - B64="BASE64" + B64="BASE64", + TEMPLATE="TEMPLATE", ) BUNDLE_LABEL_URL = "A URL Bundle Label!" @@ -196,6 +197,39 @@ def test_roundtrip_path(self): 1) self.assert_true(has_all_docs) + # def test_roundtrip_template(self): + # bh = BundleHelper(self._bundle_label("TEMPLATE"), + # self.EMAIL_SUBJECT, + # self.EMAIL_MESSAGE, + # is_test=True) + # + # signer01_key = bh.add_signer(key=self.SIGNER01_KEY, + # name=self.SIGNER01_NAME, + # email=self.SIGNER01_EMAIL, + # phone=self.SIGNER01_PHONE, + # deliver_via=self.SIGNER01_DELIVERY) + # + # assignments = { + # "signer-1": signer01_key, + # } + # initvals = { + # "inp001-a3Y3q": "MUH INIT VAL" + # } + # + # # Add Document + # bh.add_document_template(template_id="e745bb78-7a87-4b9c-b3df-54373a1bb2c3", + # assignments=assignments, + # initial_field_values=initvals) + # + # client = Client(raise_exceptions=False) + # resp = client.bundles.create_from_bundle_helper(bh) + # self.assert_equal(resp.status, 201) + # + # has_all_docs = self._poll_for_successful_file_processing(client, + # resp.data.id, + # 1) + # self.assert_true(has_all_docs) + def test_person_create(self): ph = PersonHelper(name=self.PERSON_NAME, metadata=self.PERSON_METADATA, From 90d01e80cd89b01345ecfcfe7514cc8757daec95 Mon Sep 17 00:00:00 2001 From: Joe Sheldon Date: Tue, 11 Oct 2022 11:35:02 -0700 Subject: [PATCH 20/20] ran black, pre-commit to requirements.txt --- .pre-commit-config.yaml | 6 + requirements.txt | 1 + src/blueink/__init__.py | 3 +- src/blueink/bundle_helper.py | 159 +++++++++++++++--------- src/blueink/client.py | 13 +- src/blueink/model/bundles.py | 67 ++++------ src/blueink/model/persons.py | 6 +- src/blueink/paginator.py | 9 +- src/blueink/request_helper.py | 15 ++- src/blueink/subclients/bundle.py | 75 ++++++----- src/blueink/subclients/person.py | 34 ++--- src/blueink/subclients/subclient.py | 8 +- src/blueink/subclients/template.py | 23 ++-- src/blueink/subclients/webhook.py | 11 +- src/blueink/test.py | 22 ++-- src/blueink/tests/test_bundle_helper.py | 5 +- src/blueink/tests/test_client.py | 110 ++++++++-------- src/blueink/tests/test_person_helper.py | 16 +-- src/blueink/utils/testcase.py | 1 - 19 files changed, 335 insertions(+), 249 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5ed79b8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: + - repo: https://github.com/psf/black + rev: 22.10.0 + hooks: + - id: black + language_version: python3.9 diff --git a/requirements.txt b/requirements.txt index 59833df..eff09b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ munch~=2.5 requests~=2.27 pydantic~=1.9 email-validator~=1.2 +pre-commit~=2.20 diff --git a/src/blueink/__init__.py b/src/blueink/__init__.py index 22446fe..bffa4c0 100644 --- a/src/blueink/__init__.py +++ b/src/blueink/__init__.py @@ -4,4 +4,5 @@ from .bundle_helper import BundleHelper from .person_helper import PersonHelper from . import constants -__all__ = ['Client', 'BundleHelper', 'PersonHelper', 'exceptions', 'constants'] + +__all__ = ["Client", "BundleHelper", "PersonHelper", "exceptions", "constants"] diff --git a/src/blueink/bundle_helper.py b/src/blueink/bundle_helper.py index 5124602..0327d95 100644 --- a/src/blueink/bundle_helper.py +++ b/src/blueink/bundle_helper.py @@ -72,7 +72,7 @@ def add_document_by_url(self, url: str, **additional_data) -> str: def add_document_by_path(self, file_path: str, **additional_data) -> str: filename = basename(file_path) - with open(file_path, 'rb') as file: + with open(file_path, "rb") as file: b64str = b64encode(file.read()).decode("utf-8") return self.add_document_by_b64(filename, b64str, **additional_data) @@ -80,9 +80,9 @@ def add_document_by_path(self, file_path: str, **additional_data) -> str: def add_document_by_b64(self, filename: str, b64str: str, **additional_data): file_index = len(self.files) - document = Document.create(filename=filename, - file_b64=b64str, - **additional_data) + document = Document.create( + filename=filename, file_b64=b64str, **additional_data + ) print(f"doc -- {document.key}") self._documents[document.key] = document return document.key @@ -102,10 +102,13 @@ def add_document_by_b64(self, filename: str, b64str: str, **additional_data): # file = io.BufferedReader(bytes, len(byte_array)) # return self.add_document_by_file(file, file_name, **additional_data) - def add_document_template(self, template_id: str, - assignments: dict, - initial_field_values: dict, - **additional_data) -> str: + def add_document_template( + self, + template_id: str, + assignments: dict, + initial_field_values: dict, + **additional_data, + ) -> str: """Create and add a template reference Args: @@ -119,7 +122,8 @@ def add_document_template(self, template_id: str, if template_id in self._documents.keys(): raise RuntimeError( - f'Document/Template with id {template_id} already added.') + f"Document/Template with id {template_id} already added." + ) assigns = [] for role, signer in assignments.items(): @@ -128,23 +132,38 @@ def add_document_template(self, template_id: str, vals = [] for field_key, init_val in initial_field_values.items(): - fieldval = TemplateRefFieldValue.create(key=field_key, - initial_value=init_val) + fieldval = TemplateRefFieldValue.create( + key=field_key, initial_value=init_val + ) vals.append(fieldval) - template = TemplateRef.create(template_id=template_id, - assignments=assigns, - field_values=vals, - **additional_data) + template = TemplateRef.create( + template_id=template_id, + assignments=assigns, + field_values=vals, + **additional_data, + ) self._documents[template.key] = template return template.key - def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, - kind: str, - editors: List[str] = None, label: str = None, v_pattern: str = None, - v_min: int = None, - v_max: int = None, key=None, **additional_data): + def add_field( + self, + document_key: str, + x: int, + y: int, + w: int, + h: int, + p: int, + kind: str, + editors: List[str] = None, + label: str = None, + v_pattern: str = None, + v_min: int = None, + v_max: int = None, + key=None, + **additional_data, + ): """Create and add a field to a particular document. Args @@ -170,9 +189,18 @@ def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, raise RuntimeError(f"No document found with key {document_key}!") field = Field.create( - x, y, w, h, p, kind, - label=label, v_pattern=v_pattern, v_min=v_min, v_max=v_max, key=key, - **additional_data + x, + y, + w, + h, + p, + kind, + label=label, + v_pattern=v_pattern, + v_min=v_min, + v_max=v_max, + key=key, + **additional_data, ) for packet_key in editors: field.add_editor(packet_key) @@ -180,11 +208,20 @@ def add_field(self, document_key: str, x: int, y: int, w: int, h: int, p: int, self._documents[document_key].add_field(field) return field.key - def add_signer(self, name: str, email: str = None, phone: str = None, - deliver_via: str = None, - person_id=None, auth_sms: bool = False, auth_selfie: bool = False, - auth_id: bool = False, - order: int = None, key=None, **additional_data): + def add_signer( + self, + name: str, + email: str = None, + phone: str = None, + deliver_via: str = None, + person_id=None, + auth_sms: bool = False, + auth_selfie: bool = False, + auth_id: bool = False, + order: int = None, + key=None, + **additional_data, + ): """Create and add a signer. With at least an email xor phone number. Args: @@ -204,24 +241,27 @@ def add_signer(self, name: str, email: str = None, phone: str = None, Packet key """ if phone is None and email is None: - raise ValidationError('Packet must have either an email or phone number') - - packet = Packet.create(name=name, - person_id=person_id, - email=email, - phone=phone, - auth_sms=auth_sms, - auth_selfie=auth_selfie, - auth_id=auth_id, - deliver_via=deliver_via, - order=order, - key=key, - **additional_data) + raise ValidationError("Packet must have either an email or phone number") + + packet = Packet.create( + name=name, + person_id=person_id, + email=email, + phone=phone, + auth_sms=auth_sms, + auth_selfie=auth_selfie, + auth_id=auth_id, + deliver_via=deliver_via, + order=order, + key=key, + **additional_data, + ) self._packets[packet.key] = packet return packet.key - def assign_role(self, document_key: str, signer_key: str, role: str, - **additional_data): + def assign_role( + self, document_key: str, signer_key: str, role: str, **additional_data + ): """Assign a signer to a particular role in a template Args: @@ -234,10 +274,12 @@ def assign_role(self, document_key: str, signer_key: str, role: str, raise RuntimeError(f"No document found with key {document_key}!") if type(self._documents[document_key]) is not TemplateRef: raise RuntimeError( - f"Document found with key {document_key} is not a Template!") + f"Document found with key {document_key} is not a Template!" + ) if signer_key not in self._packets: raise RuntimeError( - f"Signer {signer_key} does not have a corresponding packet") + f"Signer {signer_key} does not have a corresponding packet" + ) assignment = TemplateRefAssignment.create(role, signer_key, **additional_data) self._documents[document_key].add_assignment(assignment) @@ -255,7 +297,8 @@ def set_value(self, document_key: str, key: str, value: str, **additional_data): raise RuntimeError(f"No document found with key {document_key}!") if type(self._documents[document_key]) is not TemplateRef: raise RuntimeError( - f"Document found with key {document_key} is not a Template!") + f"Document found with key {document_key} is not a Template!" + ) field_val = TemplateRefFieldValue.create(key, value, **additional_data) self._documents[document_key].field_values.append(field_val) @@ -270,17 +313,19 @@ def _compile_bundle(self, **additional_data) -> Bundle: """ packets = list(self._packets.values()) documents = list(self._documents.values()) - bundle_out = Bundle.create(packets, - documents, - label=self._label, - in_order=self._in_order, - email_subject=self._email_subj, - email_message=self._email_msg, - is_test=self._is_test, - cc_emails=self._cc_emails, - custom_key=self._custom_key, - team=self._team, - **additional_data) + bundle_out = Bundle.create( + packets, + documents, + label=self._label, + in_order=self._in_order, + email_subject=self._email_subj, + email_message=self._email_msg, + is_test=self._is_test, + cc_emails=self._cc_emails, + custom_key=self._custom_key, + team=self._team, + **additional_data, + ) return bundle_out def as_data(self, **additional_data): diff --git a/src/blueink/client.py b/src/blueink/client.py index 88dbea0..528b55f 100644 --- a/src/blueink/client.py +++ b/src/blueink/client.py @@ -3,19 +3,24 @@ from src.blueink.constants import ( DEFAULT_BASE_URL, ENV_BLUEINK_API_URL, - ENV_BLUEINK_PRIVATE_API_KEY + ENV_BLUEINK_PRIVATE_API_KEY, ) from src.blueink.request_helper import RequestHelper from src.blueink.subclients.bundle import BundleSubClient from src.blueink.subclients.packet import PacketSubClient from src.blueink.subclients.person import PersonSubClient from src.blueink.subclients.template import TemplateSubClient + # from src.blueink.subclients.webhook import WebhookSubClient class Client: - def __init__(self, private_api_key: str = None, base_url: str = None, - raise_exceptions: bool = True): + def __init__( + self, + private_api_key: str = None, + base_url: str = None, + raise_exceptions: bool = True, + ): """Initialize a Client instance to access the Blueink eSignature API Args: @@ -58,5 +63,3 @@ def __init__(self, private_api_key: str = None, base_url: str = None, self.packets = PacketSubClient(base_url, self._request_helper) self.templates = TemplateSubClient(base_url, self._request_helper) # self.webhooks = WebhookSubClient(base_url, self._request_helper) - - diff --git a/src/blueink/model/bundles.py b/src/blueink/model/bundles.py index e4c75bd..029cfb3 100644 --- a/src/blueink/model/bundles.py +++ b/src/blueink/model/bundles.py @@ -12,8 +12,8 @@ def __init__(self, error_text: str): def generate_key(type, length=5): - slug = ''.join(random.choice(string.ascii_letters) for i in range(length)) - return f'{type}_{slug}' + slug = "".join(random.choice(string.ascii_letters) for i in range(length)) + return f"{type}_{slug}" class Field(BaseModel): @@ -31,25 +31,20 @@ class Field(BaseModel): editors: Optional[List[str]] class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, x, y, w, h, page, kind, key=None, **kwargs): if not key: - key = generate_key('field', 5) - obj = Field(key=key, - x=x, - y=y, - w=w, - h=h, - page=page, - kind=kind, - **kwargs) + key = generate_key("field", 5) + obj = Field(key=key, x=x, y=y, w=w, h=h, page=page, kind=kind, **kwargs) return obj - @validator('kind') + @validator("kind") def kind_is_allowed(cls, v): - assert v in FIELD_KIND.values(), f'Field Kind \'{v}\' not allowed. Must be one of {FIELD_KIND.values()}' + assert ( + v in FIELD_KIND.values() + ), f"Field Kind '{v}' not allowed. Must be one of {FIELD_KIND.values()}" return v def add_editor(self, editor: str): @@ -71,22 +66,22 @@ class Packet(BaseModel): order: Optional[str] class Config: - extra = 'allow' + extra = "allow" - @validator('deliver_via') + @validator("deliver_via") def deliver_via_is_allowed(cls, v): if v is not None: - assert v in DELIVER_VIA.values(), f'deliver_via \'{v}\' not allowed. Must be None' \ - f' or one of {DELIVER_VIA.values()}' + assert v in DELIVER_VIA.values(), ( + f"deliver_via '{v}' not allowed. Must be None" + f" or one of {DELIVER_VIA.values()}" + ) return v @classmethod def create(cls, name, key=None, **kwargs): if not key: - key = generate_key('packet', 5) - obj = Packet(key=key, - name=name, - **kwargs) + key = generate_key("packet", 5) + obj = Packet(key=key, name=name, **kwargs) return obj @@ -95,13 +90,11 @@ class TemplateRefAssignment(BaseModel): signer: str = ... class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, role, signer, **kwargs): - obj = TemplateRefAssignment(role=role, - signer=signer, - **kwargs) + obj = TemplateRefAssignment(role=role, signer=signer, **kwargs) return obj @@ -110,13 +103,11 @@ class TemplateRefFieldValue(BaseModel): initial_value: str = ... class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, key, initial_value, **kwargs): - obj = TemplateRefFieldValue(key=key, - initial_value=initial_value, - **kwargs) + obj = TemplateRefFieldValue(key=key, initial_value=initial_value, **kwargs) return obj @@ -126,12 +117,12 @@ class TemplateRef(BaseModel): field_values: Optional[List[TemplateRefFieldValue]] class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, key=None, **kwargs): if not key: - key = generate_key('tmpl', 5) + key = generate_key("tmpl", 5) obj = TemplateRef(key=key, **kwargs) return obj @@ -157,12 +148,12 @@ class Document(BaseModel): fields: Optional[List[Field]] class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, key=None, **kwargs): if not key: - key = generate_key('doc', 5) + key = generate_key("doc", 5) obj = Document(key=key, **kwargs) return obj @@ -190,13 +181,11 @@ class Bundle(BaseModel): team: Optional[str] class Config: - extra = 'allow' + extra = "allow" @classmethod def create(cls, packets: List[Packet], documents: List[Document], **kwargs): - obj = Bundle(packets=packets, - documents=documents, - **kwargs) + obj = Bundle(packets=packets, documents=documents, **kwargs) return obj def add_packet(self, packet: Packet): @@ -208,5 +197,3 @@ def add_document(self, document: Document): if self.documents is None: self.documents = [] self.documents.append(document) - - diff --git a/src/blueink/model/persons.py b/src/blueink/model/persons.py index 7b88a2a..bf4cb96 100644 --- a/src/blueink/model/persons.py +++ b/src/blueink/model/persons.py @@ -8,7 +8,7 @@ class ContactChannelSchema(BaseModel): kind: Optional[str] class Config: - extra = 'allow' + extra = "allow" class PersonSchema(BaseModel): @@ -17,6 +17,4 @@ class PersonSchema(BaseModel): channels: Optional[List[ContactChannelSchema]] class Config: - extra = 'allow' - - + extra = "allow" diff --git a/src/blueink/paginator.py b/src/blueink/paginator.py index 3e69ece..18dad2b 100644 --- a/src/blueink/paginator.py +++ b/src/blueink/paginator.py @@ -35,9 +35,11 @@ def __next__(self): raise StopIteration try: - api_response: NormalizedResponse = self._paged_func(page=self.next_page, - per_page=self._items_per_page, - **self._paged_func_args) + api_response: NormalizedResponse = self._paged_func( + page=self.next_page, + per_page=self._items_per_page, + **self._paged_func_args + ) except HTTPError: raise StopIteration @@ -49,4 +51,3 @@ def __next__(self): self.next_page = self.next_page + 1 return api_response - diff --git a/src/blueink/request_helper.py b/src/blueink/request_helper.py index a0866ce..6b54667 100644 --- a/src/blueink/request_helper.py +++ b/src/blueink/request_helper.py @@ -97,17 +97,26 @@ def _build_headers(self, content_type=None, more_headers=None): return hdrs def _make_request( - self, method, url, data=None, json=None, files=None, params=None, headers=None, content_type=None + self, + method, + url, + data=None, + json=None, + files=None, + params=None, + headers=None, + content_type=None, ): - response = requests.request( method, url, params=params, data=data, json=json, - headers=self._build_headers(content_type=content_type, more_headers=headers), + headers=self._build_headers( + content_type=content_type, more_headers=headers + ), files=files, ) diff --git a/src/blueink/subclients/bundle.py b/src/blueink/subclients/bundle.py index 03c9580..2b17dba 100644 --- a/src/blueink/subclients/bundle.py +++ b/src/blueink/subclients/bundle.py @@ -29,14 +29,22 @@ def _prepare_files(self, file_list: [io.BufferedReader]): f" (e.g. an open file handle)" ) field_name = f"files[{idx}]" - files_data.append((field_name, (file_dict.get("filename"), - fh, - file_dict.get("content_type")))) + files_data.append( + ( + field_name, + ( + file_dict.get("filename"), + fh, + file_dict.get("content_type"), + ), + ) + ) return files_data - def create(self, data: dict, - files: List[io.BufferedReader] = []) -> NormalizedResponse: - """ Post a Bundle to the BlueInk application. + def create( + self, data: dict, files: List[io.BufferedReader] = [] + ) -> NormalizedResponse: + """Post a Bundle to the BlueInk application. Args: data: raw data for Bundle, expressed as a python dict @@ -59,15 +67,14 @@ def create(self, data: dict, bundle_request_data = {"bundle_request": json.dumps(data)} - response = self._requests.post(url, - data=bundle_request_data, - files=files_data) + response = self._requests.post( + url, data=bundle_request_data, files=files_data + ) return response - def create_from_bundle_helper(self, - bdl_helper: BundleHelper) -> NormalizedResponse: - """ Post a Bundle to the BlueInk application. + def create_from_bundle_helper(self, bdl_helper: BundleHelper) -> NormalizedResponse: + """Post a Bundle to the BlueInk application. Provided as a convenience to simplify posting of a Bundle. This is the recommended way to create a Bundle. @@ -83,8 +90,13 @@ def create_from_bundle_helper(self, files = bdl_helper.files return self.create(data=data, files=files) - def paged_list(self, page: int = 1, per_page: int = 50, - related_data: bool = False, **query_params) -> PaginatedIterator: + def paged_list( + self, + page: int = 1, + per_page: int = 50, + related_data: bool = False, + **query_params, + ) -> PaginatedIterator: """Returns an iterable object such that you may lazily fetch a number of Bundles @@ -101,16 +113,23 @@ def paged_list(self, page: int = 1, per_page: int = 50, Returns: PaginatedIterator object, compliant with python iterables """ - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - related_data=related_data, - **query_params) + iterator = PaginatedIterator( + paged_api_function=self.list, + page=page, + per_page=per_page, + related_data=related_data, + **query_params, + ) return iterator - def list(self, page: int = None, per_page: int = None, - related_data: bool = False, **query_params) -> NormalizedResponse: - """ Returns a list of bundles + def list( + self, + page: int = None, + per_page: int = None, + related_data: bool = False, + **query_params, + ) -> NormalizedResponse: + """Returns a list of bundles Args: page: which page to fetch @@ -122,10 +141,9 @@ def list(self, page: int = None, per_page: int = None, NormalizedResponse object """ url = self.build_url(endpoints.BUNDLES.LIST) - response = self._requests.get(url, - params=self.build_params(page, - per_page, - **query_params)) + response = self._requests.get( + url, params=self.build_params(page, per_page, **query_params) + ) if related_data: for bundle in response.data: @@ -148,8 +166,9 @@ def _attach_additional_data(self, bundle): data_response = self.list_data(bundle_id) bundle.data = data_response.data - def retrieve(self, bundle_id: str, - related_data: bool = False) -> NormalizedResponse: + def retrieve( + self, bundle_id: str, related_data: bool = False + ) -> NormalizedResponse: """Request a single bundle Args: diff --git a/src/blueink/subclients/person.py b/src/blueink/subclients/person.py index cd99477..2904235 100644 --- a/src/blueink/subclients/person.py +++ b/src/blueink/subclients/person.py @@ -24,8 +24,9 @@ def create(self, data: dict, **kwargs) -> NormalizedResponse: url = self.build_url(endpoints.PERSONS.CREATE) return self._requests.post(url, json=data) - def create_from_person_helper(self, person_helper: PersonHelper, - **kwargs) -> NormalizedResponse: + def create_from_person_helper( + self, person_helper: PersonHelper, **kwargs + ) -> NormalizedResponse: """Create a person using PersonHelper convenience object Args: @@ -36,8 +37,9 @@ def create_from_person_helper(self, person_helper: PersonHelper, """ return self.create(person_helper.as_dict(**kwargs)) - def paged_list(self, page: int = 1, per_page: int = 50, - **query_params) -> PaginatedIterator: + def paged_list( + self, page: int = 1, per_page: int = 50, **query_params + ) -> PaginatedIterator: """Return an iterable object such that you may lazily fetch a number of Persons (signers) @@ -54,14 +56,14 @@ def paged_list(self, page: int = 1, per_page: int = 50, PaginatedIterator object """ - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - **query_params) + iterator = PaginatedIterator( + paged_api_function=self.list, page=page, per_page=per_page, **query_params + ) return iterator - def list(self, page: int = None, per_page: int = None, - **query_params) -> NormalizedResponse: + def list( + self, page: int = None, per_page: int = None, **query_params + ) -> NormalizedResponse: """Return a list of persons (signers). Args: @@ -73,10 +75,9 @@ def list(self, page: int = None, per_page: int = None, NormalizedResponse object """ url = self.build_url(endpoints.PERSONS.LIST) - return self._requests.get(url, - params=self.build_params(page, - per_page, - **query_params)) + return self._requests.get( + url, params=self.build_params(page, per_page, **query_params) + ) def retrieve(self, person_id: str) -> NormalizedResponse: """Retrieve details on a singular person @@ -90,8 +91,9 @@ def retrieve(self, person_id: str) -> NormalizedResponse: url = self.build_url(endpoints.PERSONS.RETRIEVE, person_id=person_id) return self._requests.get(url) - def update(self, person_id: str, data: dict, - partial: bool = False) -> NormalizedResponse: + def update( + self, person_id: str, data: dict, partial: bool = False + ) -> NormalizedResponse: """Update a Person (signer)'s record Args: diff --git a/src/blueink/subclients/subclient.py b/src/blueink/subclients/subclient.py index 8a5f090..ed67650 100644 --- a/src/blueink/subclients/subclient.py +++ b/src/blueink/subclients/subclient.py @@ -25,14 +25,16 @@ def build_url(self, endpoint: str, **kwargs): """ # All of our current endpoints take 1 parameter, max if len(kwargs) > 1: - raise ValueError('Only one interpolation parameter is allowed') + raise ValueError("Only one interpolation parameter is allowed") try: url = endpoints.URLBuilder(self._base_url, endpoint).build(**kwargs) except KeyError: arg_name = list(kwargs.keys())[0] - raise ValueError(f'Invalid substitution argument "{arg_name}"' - f' provided for endpoint "{endpoint}"') + raise ValueError( + f'Invalid substitution argument "{arg_name}"' + f' provided for endpoint "{endpoint}"' + ) return url diff --git a/src/blueink/subclients/template.py b/src/blueink/subclients/template.py index aca37b5..961d943 100644 --- a/src/blueink/subclients/template.py +++ b/src/blueink/subclients/template.py @@ -8,8 +8,9 @@ class TemplateSubClient(SubClient): def __init__(self, base_url, private_api_key): super().__init__(base_url, private_api_key) - def paged_list(self, page: int = 1, per_page: int = 50, - **query_params) -> PaginatedIterator: + def paged_list( + self, page: int = 1, per_page: int = 50, **query_params + ) -> PaginatedIterator: """return an iterable object containing a list of templates Typical Usage: @@ -24,14 +25,14 @@ def paged_list(self, page: int = 1, per_page: int = 50, Returns: PaginatedIterator object """ - iterator = PaginatedIterator(paged_api_function=self.list, - page=page, - per_page=per_page, - **query_params) + iterator = PaginatedIterator( + paged_api_function=self.list, page=page, per_page=per_page, **query_params + ) return iterator - def list(self, page: int = None, per_page: int = None, - **query_params) -> NormalizedResponse: + def list( + self, page: int = None, per_page: int = None, **query_params + ) -> NormalizedResponse: """Return a list of Templates. Args: @@ -43,9 +44,9 @@ def list(self, page: int = None, per_page: int = None, NormalizedResponse object """ url = self.build_url(endpoints.TEMPLATES.LIST) - return self._requests.get(url, params=self.build_params(page, - per_page, - **query_params)) + return self._requests.get( + url, params=self.build_params(page, per_page, **query_params) + ) def retrieve(self, template_id: str) -> NormalizedResponse: """Return a singular Template by id. diff --git a/src/blueink/subclients/webhook.py b/src/blueink/subclients/webhook.py index e1a9c59..12d6acd 100644 --- a/src/blueink/subclients/webhook.py +++ b/src/blueink/subclients/webhook.py @@ -11,9 +11,14 @@ def __init__(self, base_url, private_api_key): # ---------- # Webhooks # ---------- - def create_webhook(self, url: str, event_types:List[str], - extra_headers: List[WebhookExtraHeader], enabled: bool = True, - json: bool = True): + def create_webhook( + self, + url: str, + event_types: List[str], + extra_headers: List[WebhookExtraHeader], + enabled: bool = True, + json: bool = True, + ): raise RuntimeError("Not Implemented") def list_webhooks(self): diff --git a/src/blueink/test.py b/src/blueink/test.py index fe794fd..1b3cc07 100644 --- a/src/blueink/test.py +++ b/src/blueink/test.py @@ -1,15 +1,15 @@ - - def lilboi(a=1, b=1, **kwargs): - print('lb.a', a) - print('lb.b', b) - print('lb.kwargs', kwargs) + print("lb.a", a) + print("lb.b", b) + print("lb.kwargs", kwargs) + def bigboi(a=1, b=1, c=1, **kwargs): - print('bb.a', a) - print('bb.b', b) - print('bb.c', c) - print('bb.kwargs', kwargs) - lilboi(a,b,c=c,**kwargs) + print("bb.a", a) + print("bb.b", b) + print("bb.c", c) + print("bb.kwargs", kwargs) + lilboi(a, b, c=c, **kwargs) + -bigboi(2, 2, c=2) \ No newline at end of file +bigboi(2, 2, c=2) diff --git a/src/blueink/tests/test_bundle_helper.py b/src/blueink/tests/test_bundle_helper.py index 16ab3da..9c2dc35 100644 --- a/src/blueink/tests/test_bundle_helper.py +++ b/src/blueink/tests/test_bundle_helper.py @@ -56,7 +56,7 @@ class TestBundleHelper(TestCase): "p": 1, "kind": "inp", "editors": [], - "label": "MY_INPUT_01" + "label": "MY_INPUT_01", } FIELD_02_DATA = { @@ -67,7 +67,7 @@ class TestBundleHelper(TestCase): "p": 1, "kind": "inp", "editors": [], - "label": "MY_INPUT_02" + "label": "MY_INPUT_02", } DOCUMENT_01_URL = "https://www.example.com/example1.pdf" @@ -133,7 +133,6 @@ def test_adding_fields(self): field01_data = copy.deepcopy(self.FIELD_01_DATA) field02_data = copy.deepcopy(self.FIELD_02_DATA) - bh = BundleHelper(**input_data) doc01_key = bh.add_document_by_url(url01) signer01_key = bh.add_signer(**signer01_data) diff --git a/src/blueink/tests/test_client.py b/src/blueink/tests/test_client.py index 536fae7..0bada4d 100644 --- a/src/blueink/tests/test_client.py +++ b/src/blueink/tests/test_client.py @@ -68,10 +68,12 @@ def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): (BundleHelper, signerkey, fieldkey) """ - bh = BundleHelper(self._bundle_label(method), - self.EMAIL_SUBJECT, - self.EMAIL_MESSAGE, - is_test=True) + bh = BundleHelper( + self._bundle_label(method), + self.EMAIL_SUBJECT, + self.EMAIL_MESSAGE, + is_test=True, + ) # Add Document doc01_key = None @@ -80,34 +82,37 @@ def _create_test_bundle_helper(self, method: str) -> (BundleHelper, str, str): elif method == self.DOC_METHODS.URL: doc01_key = bh.add_document_by_url(self.REAL_DOCUMENT_URL) elif method == self.DOC_METHODS.B64: - file = open(self.REAL_DOCUMENT_PATH, 'rb') + file = open(self.REAL_DOCUMENT_PATH, "rb") filename = basename(self.REAL_DOCUMENT_PATH) b64str = b64encode(file.read()).decode("utf-8") file.close() doc01_key = bh.add_document_by_b64(filename, b64str) # Add Signer 1 - signer01_key = bh.add_signer(key=self.SIGNER01_KEY, - name=self.SIGNER01_NAME, - email=self.SIGNER01_EMAIL, - phone=self.SIGNER01_PHONE, - deliver_via=self.SIGNER01_DELIVERY) + signer01_key = bh.add_signer( + key=self.SIGNER01_KEY, + name=self.SIGNER01_NAME, + email=self.SIGNER01_EMAIL, + phone=self.SIGNER01_PHONE, + deliver_via=self.SIGNER01_DELIVERY, + ) # Add Field - field01_key = bh.add_field(document_key=doc01_key, - x=self.FIELD01_X, - y=self.FIELD01_Y, - w=self.FIELD01_W, - h=self.FIELD01_H, - p=self.FIELD01_P, - kind=self.FIELD01_KIND, - editors=self.FIELD01_EDITORS, - label=self.FIELD01_LABEL - ) - - self._check_bundle_data(bh.as_data(), - signerkey=signer01_key, - fieldkey=field01_key) + field01_key = bh.add_field( + document_key=doc01_key, + x=self.FIELD01_X, + y=self.FIELD01_Y, + w=self.FIELD01_W, + h=self.FIELD01_H, + p=self.FIELD01_P, + kind=self.FIELD01_KIND, + editors=self.FIELD01_EDITORS, + label=self.FIELD01_LABEL, + ) + + self._check_bundle_data( + bh.as_data(), signerkey=signer01_key, fieldkey=field01_key + ) return bh, signer01_key, field01_key @@ -135,9 +140,14 @@ def _check_bundle_data(self, compiled_bundle: dict, signerkey, fieldkey): self.assert_equal(compiled_bundle["packets"][0]["key"], signerkey) - def _poll_for_successful_file_processing(self, client: Client, bundle_id: str, - expected_document_count: int, - max_attempts=5, delay_between_seconds=5): + def _poll_for_successful_file_processing( + self, + client: Client, + bundle_id: str, + expected_document_count: int, + max_attempts=5, + delay_between_seconds=5, + ): attempt = 0 while attempt < max_attempts: attempt = attempt + 1 @@ -145,8 +155,10 @@ def _poll_for_successful_file_processing(self, client: Client, bundle_id: str, resp = client.bundles.retrieve(bundle_id) if resp.status != 200: - print(f"Failed to get bundle {bundle_id} on attempt {attempt}" - f" of {max_attempts}") + print( + f"Failed to get bundle {bundle_id} on attempt {attempt}" + f" of {max_attempts}" + ) continue ndocs = len(resp.data["documents"]) @@ -156,45 +168,39 @@ def _poll_for_successful_file_processing(self, client: Client, bundle_id: str, return False def test_roundtrip_url(self): - bh, sk, fk = self._create_test_bundle_helper( - method=self.DOC_METHODS.URL - ) + bh, sk, fk = self._create_test_bundle_helper(method=self.DOC_METHODS.URL) client = Client(raise_exceptions=False) resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) - has_all_docs = self._poll_for_successful_file_processing(client, - resp.data.id, - 1) + has_all_docs = self._poll_for_successful_file_processing( + client, resp.data.id, 1 + ) self.assert_true(has_all_docs) def test_roundtrip_b64(self): - bh, sk, fk = self._create_test_bundle_helper( - method=self.DOC_METHODS.B64 - ) + bh, sk, fk = self._create_test_bundle_helper(method=self.DOC_METHODS.B64) client = Client(raise_exceptions=False) resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) - has_all_docs = self._poll_for_successful_file_processing(client, - resp.data.id, - 1) + has_all_docs = self._poll_for_successful_file_processing( + client, resp.data.id, 1 + ) self.assert_true(has_all_docs) def test_roundtrip_path(self): - bh, sk, fk = self._create_test_bundle_helper( - method=self.DOC_METHODS.PATH - ) + bh, sk, fk = self._create_test_bundle_helper(method=self.DOC_METHODS.PATH) client = Client(raise_exceptions=False) resp = client.bundles.create_from_bundle_helper(bh) self.assert_equal(resp.status, 201) - has_all_docs = self._poll_for_successful_file_processing(client, - resp.data.id, - 1) + has_all_docs = self._poll_for_successful_file_processing( + client, resp.data.id, 1 + ) self.assert_true(has_all_docs) # def test_roundtrip_template(self): @@ -231,10 +237,12 @@ def test_roundtrip_path(self): # self.assert_true(has_all_docs) def test_person_create(self): - ph = PersonHelper(name=self.PERSON_NAME, - metadata=self.PERSON_METADATA, - phones=self.PERSON_PHONES, - emails=self.PERSON_EMAILS) + ph = PersonHelper( + name=self.PERSON_NAME, + metadata=self.PERSON_METADATA, + phones=self.PERSON_PHONES, + emails=self.PERSON_EMAILS, + ) client = Client(raise_exceptions=False) resp = client.persons.create_from_person_helper(ph) diff --git a/src/blueink/tests/test_person_helper.py b/src/blueink/tests/test_person_helper.py index 5cf0309..1ac1329 100644 --- a/src/blueink/tests/test_person_helper.py +++ b/src/blueink/tests/test_person_helper.py @@ -3,7 +3,7 @@ class TestPersonHelper(TestCase): - NAME="JOHN DOE" + NAME = "JOHN DOE" MD_KEY01 = "KEY01" MD_KEY02 = "KEY02" @@ -17,7 +17,7 @@ class TestPersonHelper(TestCase): PHONES = ["505 555 5555"] EMAILS = ["johndoe@example.com"] - def _check_values(self, data:dict): + def _check_values(self, data: dict): self.assert_equal(data["name"], self.NAME) self.assert_in("channels", data) @@ -38,7 +38,6 @@ def _check_values(self, data:dict): self.assert_true(has_email) self.assert_true(has_phone) - self.assert_in("metadata", data) self.assert_len(data["metadata"], 2) self.assert_in(self.MD_KEY01, data["metadata"]) @@ -56,10 +55,11 @@ def test_atomic(self): self._check_values(ph.as_dict()) def test_all_in_one(self): - ph = PersonHelper(name=self.NAME, - metadata=self.METADATA, - phones=self.PHONES, - emails=self.EMAILS) + ph = PersonHelper( + name=self.NAME, + metadata=self.METADATA, + phones=self.PHONES, + emails=self.EMAILS, + ) self._check_values(ph.as_dict()) - diff --git a/src/blueink/utils/testcase.py b/src/blueink/utils/testcase.py index 93d01a9..a8cd04b 100644 --- a/src/blueink/utils/testcase.py +++ b/src/blueink/utils/testcase.py @@ -1,5 +1,4 @@ class TestCase: - def assert_true(self, val): if val is None: assert False, f"{val} is None, not True"