From 5cdc2fc2203b3d1f634940dde778e60b924dfb9f Mon Sep 17 00:00:00 2001 From: Jen Young Date: Thu, 10 Jan 2019 18:03:09 -0800 Subject: [PATCH 01/18] Add parameters to send signature request endpoint --- hellosign_sdk/hsclient.py | 68 +++++++++++++++------------------ hellosign_sdk/utils/hsformat.py | 21 +++++++--- setup.py | 2 +- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 8006c69..7e772c3 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -36,7 +36,7 @@ class HSClient(object): ''' - version = '3.8.7' # SDK version + version = '3.8.8' # SDK version API_VERSION = 'v3' # API version API_URL = '' @@ -261,15 +261,13 @@ def verify_account(self, email_address): # ---- SIGNATURE REQUEST METHODS ------------------- @api_resource(SignatureRequest) - def get_signature_request(self, signature_request_id, ux_version=None): + def get_signature_request(self, signature_request_id): ''' Get a signature request by its ID Args: signature_request_id (str): The id of the SignatureRequest to retrieve - ux_version (int): UX version, either 1 (default) or 2. - Returns: A SignatureRequest object @@ -278,15 +276,10 @@ def get_signature_request(self, signature_request_id, ux_version=None): request = self._get_request() parameters = None - if ux_version is not None: - parameters = { - 'ux_version': ux_version - } - return request.get(self.SIGNATURE_REQUEST_INFO_URL + signature_request_id, parameters=parameters) @api_resource_list(SignatureRequest) - def get_signature_request_list(self, page=1, ux_version=None): + def get_signature_request_list(self, page=1): ''' Get a list of SignatureRequest that you can access This includes SignatureRequests you have sent as well as received, but @@ -296,8 +289,6 @@ def get_signature_request_list(self, page=1, ux_version=None): page (int, optional): Which page number of the SignatureRequest list to return. Defaults to 1. - ux_version (int): UX version, either 1 (default) or 2. - Returns: A ResourceList object @@ -308,9 +299,6 @@ def get_signature_request_list(self, page=1, ux_version=None): "page": page } - if ux_version is not None: - parameters['ux_version'] = ux_version - return request.get(self.SIGNATURE_REQUEST_LIST_URL, parameters=parameters) def get_signature_request_file(self, signature_request_id, path_or_file=None, file_type=None, filename=None): @@ -336,7 +324,7 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi url += '?file_type=%s' % file_type return request.get_file(url, path_or_file or filename) - def send_signature_request(self, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, ux_version=None, allow_decline=False): + def send_signature_request(self, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, custom_fields=None, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates and sends a new SignatureRequest with the submitted documents Creates and sends a new SignatureRequest with the submitted documents. @@ -348,15 +336,15 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - files (list of str): The uploaded file(s) to send for signature + files (list of str): The uploaded file(s) to send for signature. file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest. - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers. - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers. signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. @@ -367,19 +355,23 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti order (str, optional): The order the signer is required to sign in pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - cc_email_addresses (list, optional): A list of email addresses that should be CC'd + cc_email_addresses (list, optional): A list of email addresses that should be CC'd on the request. - form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) + form_fields_per_document (str): The signer components that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://app.hellosign.com/api/reference#SignatureRequest). - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to specify signer components. - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas. - metadata (dict, optional): Metadata to associate with the signature request + custom_fields (list of dict, optional): A list of custom fields defined by Text Tags for Form Fields per Document. An item of the list should look like this: `{'name: value'}` - ux_version (int): UX version, either 1 (default) or 2. + metadata (dict, optional): Metadata associated with the signature request. + + allow_decline (bool, optional): Allows signers to decline to sign a document if set to True. Defaults to False. - allow_decline(bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -408,12 +400,11 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti 'use_text_tags': use_text_tags, 'hide_text_tags': hide_text_tags, 'metadata': metadata, - 'allow_decline': allow_decline + 'allow_decline': allow_decline, + 'allow_reassign': allow_reassign, + 'signing_options': signing_options } - if ux_version is not None: - params['ux_version'] = ux_version - return self._send_signature_request(**params) def send_signature_request_with_template(self, test_mode=False, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, ux_version=None, allow_decline=False): @@ -1353,7 +1344,7 @@ def _check_required_fields(self, fields=None, either_fields=None): raise HSException("One of the following fields is required: %s" % ", ".join(field.keys())) @api_resource(SignatureRequest) - def _send_signature_request(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, ux_version=None, allow_decline=False): + def _send_signature_request(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, custom_fields=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' To share the same logic between send_signature_request & send_signature_request_embedded functions @@ -1392,10 +1383,12 @@ def _send_signature_request(self, test_mode=False, client_id=None, files=None, f metadata (dict, optional): Metadata to associate with the signature request - ux_version (int): UX version, either 1 (default) or 2. - allow_decline (bool, optional); Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + Returns: A SignatureRequest object @@ -1426,12 +1419,11 @@ def _send_signature_request(self, test_mode=False, client_id=None, files=None, f "form_fields_per_document": form_fields_per_document, "use_text_tags": self._boolean(use_text_tags), "hide_text_tags": self._boolean(hide_text_tags), - "allow_decline": self._boolean(allow_decline) + "allow_decline": self._boolean(allow_decline), + "allow_reassign": self._boolean(allow_reassign), + "signing_options": json.dumps(signing_options) } - if ux_version is not None: - payload['ux_version'] = ux_version - # remove attributes with none value payload = HSFormat.strip_none_values(payload) diff --git a/hellosign_sdk/utils/hsformat.py b/hellosign_sdk/utils/hsformat.py index d110c1f..3bc9ae8 100644 --- a/hellosign_sdk/utils/hsformat.py +++ b/hellosign_sdk/utils/hsformat.py @@ -1,8 +1,8 @@ # # The MIT License (MIT) -# +# # Copyright (C) 2014 hellosign.com -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -82,13 +82,13 @@ def format_dict_list(list_of_dicts, output_name, key=None): and outputs: signers[0][name] : val1 signers[0][email] : val2 - ... + ... Args: list_of_dicts (list of dicts) - the list to format - + output_name (str) - the parameter name to prepend to each key - + key (str, optional) - Used for substituting a key present in the dictionaries for the index. The above might become signers['Lawyer']['name'] instead of using a numerical index if the key "role_name" was specified. ''' @@ -126,7 +126,16 @@ def format_custom_fields(list_of_custom_fields): output_payload["custom_fields[" + key + "]"] = value return output_payload + @staticmethod + def format_signing_options(listed_params): + ''' + Utility method for formatting signing options for api consumption + Args: + listed_params (list of values) - the list to format + ''' + return listed_params + @staticmethod def strip_none_values(dictionary): if dictionary: - return dict((key, value) for (key, value) in dictionary.items() if value) \ No newline at end of file + return dict((key, value) for (key, value) in dictionary.items() if value) diff --git a/setup.py b/setup.py index 3b8c6aa..3b532cd 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def readme(): setup( name='hellosign-python-sdk', - version='3.8.7', + version='3.8.8', description="A Python wrapper for the HelloSign API (http://www.hellosign.com/api)", long_description=readme(), classifiers=[ From e04a2349ad7bbf7ce6bc5954e9ded527c52cc736 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 09:48:53 -0800 Subject: [PATCH 02/18] Add parameters to send_with_template endpoint --- hellosign_sdk/hsclient.py | 49 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 7e772c3..acc99c5 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -407,7 +407,7 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti return self._send_signature_request(**params) - def send_signature_request_with_template(self, test_mode=False, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, ux_version=None, allow_decline=False): + def send_signature_request_with_template(self, test_mode=False, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): ''' Creates and sends a new SignatureRequest based off of a Template Creates and sends a new SignatureRequest based off of the Template @@ -445,10 +445,14 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None metadata (dict, optional): Metadata to associate with the signature request - ux_version (int): UX version, either 1 (default) or 2. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + files (list of str): The uploaded file(s) to append to the Signature Request. + + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + Returns: A SignatureRequest object @@ -458,7 +462,9 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None "signers": signers }, [{ "template_id": template_id, - "template_ids": template_ids + "template_ids": template_ids, + "files": files, + "file_urls": file_urls }] ) @@ -474,12 +480,12 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None 'ccs': ccs, 'custom_fields': custom_fields, 'metadata': metadata, - 'allow_decline': allow_decline + 'allow_decline': allow_decline, + 'files': files, + 'file_urls': file_urls, + 'signing_options': signing_options } - if ux_version is not None: - params['ux_version'] = ux_version - return self._send_signature_request_with_template(**params) @api_resource(SignatureRequest) @@ -1443,7 +1449,7 @@ def _send_signature_request(self, test_mode=False, client_id=None, files=None, f return response @api_resource(SignatureRequest) - def _send_signature_request_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, ux_version=None, allow_decline=False): + def _send_signature_request_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): ''' To share the same logic between send_signature_request_with_template and send_signature_request_embedded_with_template @@ -1451,7 +1457,7 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. @@ -1481,10 +1487,14 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, metadata (dict, optional): Metadata to associate with the signature request - ux_version (int): UX version, either 1 (default) or 2. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + files (list of str): The uploaded file(s) to append to the Signature Request. + + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + Returns: A SignatureRequest object @@ -1508,6 +1518,12 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, for i in range(len(template_ids)): template_ids_payload["template_ids[%s]" % i] = template_ids[i] + # Files + files_payload = HSFormat.format_file_params(files) + + # File URLs + file_urls_payload = HSFormat.format_file_url_params(file_urls) + payload = { "test_mode": self._boolean(test_mode), "client_id": client_id, @@ -1516,12 +1532,10 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, "subject": subject, "message": message, "signing_redirect_url": signing_redirect_url, - "allow_decline": self._boolean(allow_decline) + "allow_decline": self._boolean(allow_decline), + "signing_options": json.dumps(signing_options) } - if ux_version is not None: - payload['ux_version'] = ux_version - # remove attributes with empty value payload = HSFormat.strip_none_values(payload) @@ -1535,9 +1549,10 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, data.update(custom_fields_payload) data.update(metadata_payload) data.update(template_ids_payload) + data.update(file_urls_payload) request = self._get_request() - response = request.post(url, data=data) + response = request.post(url, data=data, files=files_payload) return response From eb6d402b78e349ed9c8bd69aaa76ea632091b54d Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 10:09:40 -0800 Subject: [PATCH 03/18] Add missing param to remind_signature_request --- hellosign_sdk/hsclient.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index acc99c5..4eea1cf 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -489,7 +489,7 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None return self._send_signature_request_with_template(**params) @api_resource(SignatureRequest) - def remind_signature_request(self, signature_request_id, email_address): + def remind_signature_request(self, signature_request_id, email_address, name=None): ''' Sends an email to the signer reminding them to sign the signature request Sends an email to the signer reminding them to sign the signature @@ -502,13 +502,16 @@ def remind_signature_request(self, signature_request_id, email_address): email_address (str): The email address of the signer to send a reminder to + name (str, optional): The name of the signer to send a reminder to + Returns: A SignatureRequest object ''' request = self._get_request() return request.post(self.SIGNATURE_REQUEST_REMIND_URL + signature_request_id, data={ - "email_address": email_address + "email_address": email_address, + "name": name }) def cancel_signature_request(self, signature_request_id): From 3ba2790fed89006c6e3dbeff3dd8124f4bc588b5 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 10:22:09 -0800 Subject: [PATCH 04/18] Add method to update signature request --- hellosign_sdk/hsclient.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 4eea1cf..eb45595 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -141,6 +141,7 @@ def _init_endpoints(self): self.SIGNATURE_REQUEST_CREATE_URL = self.API_URL + '/signature_request/send' self.SIGNATURE_REQUEST_CREATE_WITH_TEMPLATE_URL = self.API_URL + '/signature_request/send_with_template' self.SIGNATURE_REQUEST_REMIND_URL = self.API_URL + '/signature_request/remind/' + self.SIGNATURE_REQUEST_UPDATE_URL = self.API_URL + '/signature_request/update/' self.SIGNATURE_REQUEST_CANCEL_URL = self.API_URL + '/signature_request/cancel/' self.SIGNATURE_REQUEST_CREATE_EMBEDDED_URL = self.API_URL + '/signature_request/create_embedded' self.SIGNATURE_REQUEST_CREATE_EMBEDDED_WITH_TEMPLATE_URL = self.API_URL + '/signature_request/create_embedded_with_template' @@ -514,6 +515,27 @@ def remind_signature_request(self, signature_request_id, email_address, name=Non "name": name }) + def update_signature_request(self, signature_request_id, signature_id, email_address): + ''' Updates the email address for a given signer on a signature request. + + Args: + + signature_request_id (str): The id of the SignatureRequest to update + + signature_id (str): The signature id for the recipient + + email_address (str): The new email address of the recipient + + Returns: + A SignatureRequest object + + ''' + request = self._get_request() + return request.post(self.SIGNATURE_REQUEST_UPDATE_URL + signature_request_id, data={ + "signature_id": signature_id, + "email_address": email_address + }) + def cancel_signature_request(self, signature_request_id): ''' Cancels a SignatureRequest From a3820bc8b22fe55f37f8d7ee588c6438ad8fd399 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 10:23:33 -0800 Subject: [PATCH 05/18] Update args in cancel_signature_request --- hellosign_sdk/hsclient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index eb45595..d60b3ba 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -545,7 +545,7 @@ def cancel_signature_request(self, signature_request_id): Args: - signing_request_id (str): The id of the signature request to cancel + signature_request_id (str): The id of the signature request to cancel Returns: None From 08a0b462b979f374645afcb8c5de2aff9b32951d Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 10:40:38 -0800 Subject: [PATCH 06/18] Add remove signature request access method --- hellosign_sdk/hsclient.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index d60b3ba..53d0146 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -143,6 +143,7 @@ def _init_endpoints(self): self.SIGNATURE_REQUEST_REMIND_URL = self.API_URL + '/signature_request/remind/' self.SIGNATURE_REQUEST_UPDATE_URL = self.API_URL + '/signature_request/update/' self.SIGNATURE_REQUEST_CANCEL_URL = self.API_URL + '/signature_request/cancel/' + self.SIGNATURE_REQUEST_REMOVE_ACCESS_URL = self.API_URL + '/signature_request/remove/' self.SIGNATURE_REQUEST_CREATE_EMBEDDED_URL = self.API_URL + '/signature_request/create_embedded' self.SIGNATURE_REQUEST_CREATE_EMBEDDED_WITH_TEMPLATE_URL = self.API_URL + '/signature_request/create_embedded_with_template' @@ -554,6 +555,22 @@ def cancel_signature_request(self, signature_request_id): request = self._get_request() request.post(url=self.SIGNATURE_REQUEST_CANCEL_URL + signature_request_id, get_json=False) + def remove_signature_request_access(self, signature_request_id): + ''' Removes your access to a completed SignatureRequest + + The SignatureRequest must be fully executed by all parties (signed or declined to sign). Other parties will continue to maintain access to the completed signature request document(s). + + Args: + + signature_request_id (str): The id of the signature request to remove + + Returns: + None + + ''' + request = self._get_request() + request.post(url=self.SIGNATURE_REQUEST_REMOVE_ACCESS_URL + signature_request_id, get_json=False) + def send_signature_request_embedded(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, ux_version=None, allow_decline=False): ''' Creates and sends a new SignatureRequest with the submitted documents From 848418e204417b1a41288fc6ae8ba4e57d1968e3 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 13:45:07 -0800 Subject: [PATCH 07/18] Add missing params for send embedded signature requests --- hellosign_sdk/hsclient.py | 41 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 53d0146..f313404 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -571,7 +571,7 @@ def remove_signature_request_access(self, signature_request_id): request = self._get_request() request.post(url=self.SIGNATURE_REQUEST_REMOVE_ACCESS_URL + signature_request_id, get_json=False) - def send_signature_request_embedded(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, ux_version=None, allow_decline=False): + def send_signature_request_embedded(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates and sends a new SignatureRequest with the submitted documents Creates a new SignatureRequest with the submitted documents to be signed @@ -617,10 +617,12 @@ def send_signature_request_embedded(self, test_mode=False, client_id=None, files metadata (dict, optional): Metadata to associate with the signature request - ux_version (int): UX version, either 1 (default) or 2. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + Returns: A SignatureRequest object @@ -650,15 +652,14 @@ def send_signature_request_embedded(self, test_mode=False, client_id=None, files 'use_text_tags': use_text_tags, 'hide_text_tags': hide_text_tags, 'metadata': metadata, - 'allow_decline': allow_decline + 'allow_decline': allow_decline, + 'allow_reassign': allow_reassign, + 'signing_options': signing_options } - if ux_version is not None: - params['ux_version'] = ux_version - return self._send_signature_request(**params) - def send_signature_request_embedded_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, ux_version=None, allow_decline=False): + def send_signature_request_embedded_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): ''' Creates and sends a new SignatureRequest based off of a Template Creates a new SignatureRequest based on the given Template to be @@ -670,7 +671,7 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. @@ -699,10 +700,14 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ metadata (dict, optional): Metadata to associate with the signature request - ux_version (int): UX version, either 1 (default) or 2. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + files (list of str): The uploaded file(s) to append to the Signature Request. + + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + + signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + Returns: A SignatureRequest object of the newly created Signature Request @@ -713,7 +718,9 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ "client_id": client_id }, [{ "template_id": template_id, - "template_ids": template_ids + "template_ids": template_ids, + "files": files, + "file_urls": file_urls }] ) @@ -730,15 +737,15 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ 'ccs': ccs, 'custom_fields': custom_fields, 'metadata': metadata, - 'allow_decline': allow_decline + 'allow_decline': allow_decline, + 'files': files, + 'file_urls': file_urls, + 'signing_options': signing_options } - if ux_version is not None: - params['ux_version'] = ux_version - return self._send_signature_request_with_template(**params) - # ---- REUSABLE FORM METHODS ----------------------- + # ---- TEMPLATE METHODS ----------------------- @api_resource(Template) def get_template(self, template_id): From 20d1ccc6fe618aba159242d8b0a011dbb668f2c7 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 11 Jan 2019 14:10:04 -0800 Subject: [PATCH 08/18] Add missing parameters for create embedded template draft --- hellosign_sdk/hsclient.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index f313404..9999f00 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -860,7 +860,7 @@ def get_template_files(self, template_id, filename): return request.get_file(url, filename) - def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, use_preexisting_fields=False): + def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, allow_reassign=False, metadata=None): ''' Creates an embedded Template draft for further editing. Args: @@ -891,7 +891,13 @@ def create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fals name (str): The name of the merge field. Must be unique. type (str): Can only be "text" or "checkbox". - use_preexisting_fields (bool): Whether to use preexisting PDF fields + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + + use_preexisting_fields (bool, optional): Whether to use preexisting PDF fields + + metadata (dict, optional): Metadata to associate with the draft + + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. Returns: A Template object specifying the Id of the draft @@ -908,7 +914,10 @@ def create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fals 'signer_roles': signer_roles, 'cc_roles': cc_roles, 'merge_fields': merge_fields, - 'use_preexisting_fields': use_preexisting_fields + 'skip_me_now': skip_me_now, + 'use_preexisting_fields': use_preexisting_fields, + 'metadata': metadata, + 'allow_reassign': allow_reassign } return self._create_embedded_template_draft(**params) @@ -1788,7 +1797,7 @@ def _add_remove_team_member(self, url, email_address=None, account_id=None): return response @api_resource(Template) - def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, use_preexisting_fields=False): + def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, metadata=None, allow_reassign=False): ''' Helper method for creating embedded template drafts. See public function for params. ''' @@ -1801,7 +1810,9 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal 'title': title, 'subject': subject, 'message': message, - 'use_preexisting_fields': self._boolean(use_preexisting_fields) + 'skip_me_now': self._boolean(skip_me_now), + 'use_preexisting_fields': self._boolean(use_preexisting_fields), + 'allow_reassign': self._boolean(allow_reassign) } # Prep files @@ -1816,6 +1827,8 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal merge_fields_payload = { 'merge_fields': json.dumps(merge_fields) } + # Prep Metadata + metadata_payload = HSFormat.format_single_dict(metadata, 'metadata') # Assemble data for sending data = {} @@ -1823,6 +1836,7 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal data.update(file_urls_payload) data.update(signer_roles_payload) data.update(ccs_payload) + data.update(metadata_payload) if (merge_fields is not None): data.update(merge_fields_payload) data = HSFormat.strip_none_values(data) From 4590a9665f4cedfa95c35b484ea0af75c3b0bb9e Mon Sep 17 00:00:00 2001 From: Jen Young Date: Tue, 22 Jan 2019 09:16:32 -0800 Subject: [PATCH 09/18] Add parameters to Get Files and Get Template Files endpoints to retrieve file URL or data URI --- hellosign_sdk/hsclient.py | 98 +++++++++++++++++++++++++++------- hellosign_sdk/utils/request.py | 14 ++--- 2 files changed, 87 insertions(+), 25 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 9999f00..e8c0e1d 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -161,6 +161,7 @@ def _init_endpoints(self): self.TEMPLATE_ADD_USER_URL = self.API_URL + '/template/add_user/' self.TEMPLATE_REMOVE_USER_URL = self.API_URL + '/template/remove_user/' self.TEMPLATE_CREATE_EMBEDDED_DRAFT_URL = self.API_URL + '/template/create_embedded_draft' + self.TEMPLATE_UPDATE_FILES_URL = self.API_URL + '/template/update_files/' self.TEAM_INFO_URL = self.API_URL + '/team' self.TEAM_UPDATE_URL = self.TEAM_INFO_URL @@ -303,7 +304,7 @@ def get_signature_request_list(self, page=1): return request.get(self.SIGNATURE_REQUEST_LIST_URL, parameters=parameters) - def get_signature_request_file(self, signature_request_id, path_or_file=None, file_type=None, filename=None): + def get_signature_request_file(self, signature_request_id, path_or_file=None, file_type=None, filename=None, get_url=False, get_data_uri=False): ''' Download the PDF copy of the current documents Args: @@ -316,15 +317,25 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. + get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. + + get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. + Returns: - True if file is downloaded and successfully written, False otherwise. + Returns a PDF file, URL link to file, or base64 encoded file ''' request = self._get_request() url = self.SIGNATURE_REQUEST_DOWNLOAD_PDF_URL + signature_request_id if file_type: url += '?file_type=%s' % file_type - return request.get_file(url, path_or_file or filename) + return request.get_file(url, path_or_file or filename) + + if get_url: + url += '?get_url=1' + elif get_data_uri: + url += '?get_data_uri=1' + return request.get(url) def send_signature_request(self, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, custom_fields=None, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates and sends a new SignatureRequest with the submitted documents @@ -840,27 +851,73 @@ def delete_template(self, template_id): return response - # def get_template_files(self, template_id): - def get_template_files(self, template_id, filename): - ''' Download a PDF copy of a template's original files + def get_template_files(self, template_id, path_or_file=None, file_type=None, filename=None, get_url=False, get_data_uri=False): + ''' Download a copy of a template's original files Args: - template_id (str): The id of the template to retrieve. + template_id (str): id of the template to download - filename (str): Filename to save the PDF file to. This should be a full path. + path_or_file (str or file): A writable File-like object or a full path to save the PDF file to. + + filename (str): [DEPRECATED] Filename to save the PDF file to. This should be a full path. + + file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. + + get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. + + get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. Returns: - Returns a PDF file + Returns a PDF file, URL link to file, or base64 encoded file ''' - - url = self.TEMPLATE_GET_FILES_URL + template_id request = self._get_request() + url = self.TEMPLATE_GET_FILES_URL + template_id + if file_type: + url += '?file_type=%s' % file_type + return request.get_file(url, path_or_file or filename) + + if get_url: + url += '?get_url=1' + elif get_data_uri: + url += '?get_data_uri=1' + return request.get(url) + + def update_template_files(self, template_id, files=None, file_urls=None, subject=None, message=None, client_id=None, test_mode=False): + ''' Overlays a new file with the overlay of an existing template. + + Args: + + template_id (str): The id of the template whose files to update + + files (list of str): The file(s) to use for the template. - return request.get_file(url, filename) + file_urls (list of str): URLs of the file for HelloSign to use for the template. Use either `files` or `file_urls`, but not both. - def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, allow_reassign=False, metadata=None): + subject (str, optional): The default template email subject + + message (str, optional): The default template email message + + test_mode (bool, optional): Whether this is a test, the signature request created from this Template will not be legally binding if set to 1. Defaults to 0. + + client_id (str): Client id of the app associated with the Template + + Returns: + A Template object + + ''' + request = self._get_request() + return request.post(self.TEMPLATE_UPDATE_FILES_URL + template_id, data={ + "files": files, + "file_urls": file_urls, + "subject": subject, + "message": message, + "test_mode": self._boolean(test_mode), + "client_id": client_id + }) + + def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, allow_reassign=False, metadata=None, allow_ccs=False): ''' Creates an embedded Template draft for further editing. Args: @@ -895,9 +952,11 @@ def create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fals use_preexisting_fields (bool, optional): Whether to use preexisting PDF fields - metadata (dict, optional): Metadata to associate with the draft + metadata (dict, optional): Metadata to associate with the draft - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when creating a tempate. Defaults to False. Returns: A Template object specifying the Id of the draft @@ -917,7 +976,8 @@ def create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fals 'skip_me_now': skip_me_now, 'use_preexisting_fields': use_preexisting_fields, 'metadata': metadata, - 'allow_reassign': allow_reassign + 'allow_reassign': allow_reassign, + 'allow_ccs': allow_ccs } return self._create_embedded_template_draft(**params) @@ -1797,7 +1857,7 @@ def _add_remove_team_member(self, url, email_address=None, account_id=None): return response @api_resource(Template) - def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, metadata=None, allow_reassign=False): + def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, metadata=None, allow_reassign=False, allow_ccs=False): ''' Helper method for creating embedded template drafts. See public function for params. ''' @@ -1812,7 +1872,9 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal 'message': message, 'skip_me_now': self._boolean(skip_me_now), 'use_preexisting_fields': self._boolean(use_preexisting_fields), - 'allow_reassign': self._boolean(allow_reassign) + 'allow_reassign': self._boolean(allow_reassign), + 'allow_ccs': + self._boolean(allow_ccs) } # Prep files diff --git a/hellosign_sdk/utils/request.py b/hellosign_sdk/utils/request.py index 517ce8f..adcc584 100644 --- a/hellosign_sdk/utils/request.py +++ b/hellosign_sdk/utils/request.py @@ -5,9 +5,9 @@ # # The MIT License (MIT) -# +# # Copyright (C) 2014 hellosign.com -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -111,7 +111,7 @@ def get_file(self, url, path_or_file=None, headers=None, filename=None): return True def get(self, url, headers=None, parameters=None, get_json=True): - ''' Send a GET request with custome headers and parameters + ''' Send a GET request with custom headers and parameters Args: url (str): URL to send the request to @@ -166,7 +166,7 @@ def post(self, url, data=None, files=None, headers=None, get_json=True): response = requests.post(url, headers=self.headers, data=data, auth=self.auth, files=files, verify=self.verify_ssl) json_response = self._process_json_response(response) - + return json_response if get_json is True else response @@ -200,7 +200,7 @@ def _process_json_response(self, response): ''' Process a given response ''' json_response = self._get_json_response(response) - + if self.response_callback is not None: json_response = self.response_callback(json_response) response._content = json.dumps(json_response) @@ -225,7 +225,7 @@ def _check_error(self, response, json_response=None): Returns: True if status code is not error code - + ''' # If status code is 4xx or 5xx, that should be an error @@ -246,7 +246,7 @@ def _check_warnings(self, json_response): Args: json_response (dict): JSON response - + ''' self.warnings = None From bb4b301c27b7094cc74f452d02a9a16026253281 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Wed, 23 Jan 2019 03:05:29 -0800 Subject: [PATCH 10/18] Add parameters for Get Template Edit URL endpoint --- hellosign_sdk/hsclient.py | 50 +++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index e8c0e1d..12d4c25 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -1079,7 +1079,7 @@ def remove_team_member(self, account_id=None, email_address=None): @api_resource(Embedded) def get_embedded_object(self, signature_id): - ''' Retrieves a embedded signing object + ''' Retrieves an embedded signing object Retrieves an embedded object containing a signature url that can be opened in an iFrame. @@ -1095,21 +1095,61 @@ def get_embedded_object(self, signature_id): return request.get(self.EMBEDDED_OBJECT_GET_URL + signature_id) @api_resource(Embedded) - def get_template_edit_url(self, template_id): + def get_template_edit_url(self, template_id, test_mode=False, cc_roles=None, merge_fields=None, skip_signer_roles=False, skip_subject_message=False): ''' Retrieves a embedded template for editing - Retrieves an embedded object containing a template url that can be opened in an iFrame. + Retrieves an embedded object containing a template edit url that can be opened in an iFrame. Args: - template_id (str): The id of the template to get a signature url for + template_id (str): The id of the template to get an edit url for + + test_mode (bool, optional): Whether this is a test, the signature requests created from this template will not be legally binding if set to True. Defaults to False. + + cc_roles (list of str, optional): The CC roles that must be assigned when using the template to send a signature request + + merge_fields (list of dict, optional): The merge fields that can be placed on the template's document(s) by the user claiming the template draft. Each must have the following two parameters: + + name (str): The name of the merge field. Must be unique. + type (str): Can only be "text" or "checkbox". + + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to False. + + skip_subject_message (bool, optional): Disables the option to edit the template's default subject and message. Defaults to False. Returns: An Embedded object ''' + + # Prep CCs + ccs_payload = HSFormat.format_param_list(cc_roles, 'cc_roles') + # Prep Merge Fields + merge_fields_payload = { + 'merge_fields': json.dumps(merge_fields) + } + + payload = { + "test_mode": self._boolean(test_mode), + "skip_signer_roles": self._boolean(skip_signer_roles), + "skip_subject_message": self._boolean(skip_subject_message) + } + + # remove attributes with none value + payload = HSFormat.strip_none_values(payload) + + url = self.EMBEDDED_TEMPLATE_EDIT_URL + template_id + + data = {} + data.update(payload) + data.update(ccs_payload) + data.update(merge_fields_payload) + request = self._get_request() - return request.get(self.EMBEDDED_TEMPLATE_EDIT_URL + template_id) + response = request.post(url, data=data) + return response + # request = self._get_request() + # return request.get(self.EMBEDDED_TEMPLATE_EDIT_URL + template_id) # ---- UNCLAIMED DRAFT METHODS --------------------- From c29f9fd7d919a5ba93fecd483243932d08041f27 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 25 Jan 2019 12:45:54 +0100 Subject: [PATCH 11/18] Add ApiApp Resource and endpoints --- hellosign_sdk/hsclient.py | 163 +++++++++++++++++++++++- hellosign_sdk/resource/__init__.py | 3 +- hellosign_sdk/resource/apiapp.py | 96 ++++++++++++++ hellosign_sdk/resource/resource.py | 6 +- hellosign_sdk/resource/resource_list.py | 7 +- hellosign_sdk/utils/hsformat.py | 9 ++ hellosign_sdk/utils/request.py | 22 ++++ 7 files changed, 296 insertions(+), 10 deletions(-) create mode 100644 hellosign_sdk/resource/apiapp.py diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 12d4c25..1307d56 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -1,5 +1,5 @@ from hellosign_sdk.utils import HSRequest, HSException, NoAuthMethod, HSAccessTokenAuth, HSFormat, api_resource, api_resource_list -from hellosign_sdk.resource import Account, SignatureRequest, Template, Team, Embedded, UnclaimedDraft +from hellosign_sdk.resource import Account, ApiApp, SignatureRequest, Template, Team, Embedded, UnclaimedDraft from requests.auth import HTTPBasicAuth import json @@ -77,6 +77,12 @@ class HSClient(object): TEAM_ADD_MEMBER_URL = '' TEAM_REMOVE_MEMBER_URL = '' + API_APP_INFO_URL = '' + API_APP_LIST_URL = '' + API_APP_CREATE_URL = '' + API_APP_UPDATE_URL = '' + API_APP_DELETE_URL = '' + OAUTH_TOKEN_URL = '' request = None @@ -170,6 +176,12 @@ def _init_endpoints(self): self.TEAM_ADD_MEMBER_URL = self.API_URL + '/team/add_member' self.TEAM_REMOVE_MEMBER_URL = self.API_URL + '/team/remove_member' + self.API_APP_INFO_URL = self.API_URL + '/api_app/' + self.API_APP_LIST_URL = self.API_URL + '/api_app/list' + self.API_APP_CREATE_URL = self.API_URL + '/api_app' + self.API_APP_UPDATE_URL = self.API_APP_INFO_URL + self.API_APP_DELETE_URL = self.API_APP_INFO_URL + # ---- ACCOUNT METHODS ----------------------------- @api_resource(Account) @@ -1148,8 +1160,153 @@ def get_template_edit_url(self, template_id, test_mode=False, cc_roles=None, mer request = self._get_request() response = request.post(url, data=data) return response - # request = self._get_request() - # return request.get(self.EMBEDDED_TEMPLATE_EDIT_URL + template_id) + + # ---- API APP METHODS -------------------------------- + + @api_resource(ApiApp) + def get_api_app_info(self, client_id): + ''' Gets an API App by its Client ID + + Returns information about the specified API App + + Returns: + An ApiApp object + + ''' + request = self._get_request() + return request.get(self.API_APP_INFO_URL + client_id) + + @api_resource_list(ApiApp) + def get_api_app_list(self, page=1, page_size=None): + ''' Lists your API Apps + + Args: + + page (int, optional): Page number of the API App List to return. Defaults to 1. + page_size (int, optional): Number of objects to be returned per page, must be between 1 and 100, default is 20. + + Returns: + A ResourceList object + + ''' + request = self._get_request() + parameters = { + 'page': page, + 'page_size': page_size + } + return request.get(self.API_APP_LIST_URL, parameters=parameters) + + @api_resource(ApiApp) + def create_api_app(self, name, domain, callback_url=None, custom_logo_file=None, oauth_callback_url=None, oauth_scopes=None, white_labeling_options=None, option_insert_everywhere=False): + ''' Creates a new API App + + Creates a new API App with the specified settings. + + Args: + + name (str): The name of the API App + + domain (str): The domain name associated with the API App + + callback_url (str, optional): The URL that HelloSign events will be POSTed to + + custom_logo_file (str, optional): The image file to use as a custom logo + + oauth_callback_url (str, optional): The URL that HelloSign OAuth events will be POSTed to + + oauth_scopes (list of str, optional): List of the API App's OAuth scopes + + white_labeling_options (dict, optional): Customization options for the API App's signer page + + option_insert_everywhere (bool, optional): Denotes if signers can "Insert Everywhere" when + signing a document + + Returns: + An ApiApp object + + ''' + + # Prep custom logo + custom_logo_payload = HSFormat.format_logo_params(custom_logo_file) + + payload = { + "name": name, + "domain": domain, + "callback_url": callback_url, + "oauth[callback_url]": oauth_callback_url, + "oauth[scopes]": oauth_scopes, + "white_labeling_options": json.dumps(white_labeling_options), + "options[can_insert_everywhere]": self._boolean(option_insert_everywhere) + } + + # remove attributes with none value + payload = HSFormat.strip_none_values(payload) + + request = self._get_request() + return request.post(self.API_APP_CREATE_URL, data=payload, files=custom_logo_payload) + + @api_resource(ApiApp) + def update_api_app(self, client_id, name=None, domain=None, callback_url=None, custom_logo_file=None, oauth_callback_url=None, oauth_scopes=None, white_labeling_options=None, option_insert_everywhere=False): + ''' Updates the specified API App + + Updates an API App with the specified settings. + + Args: + + name (str): The name of the API App + + domain (str): The domain name associated with the API App + + callback_url (str, optional): The URL that HelloSign events will be POSTed to + + custom_logo_file (str, optional): The image file to use as a custom logo + + oauth_callback_url (str, optional): The URL that HelloSign OAuth events will be POSTed to + + oauth_scopes (list of str, optional): List of the API App's OAuth scopes + + white_labeling_options (dict, optional): Customization options for the API App's signer page + + option_insert_everywhere (bool, optional): Denotes if signers can "Insert Everywhere" when + signing a document + + Returns: + An ApiApp object + + ''' + + # Prep custom logo + custom_logo_payload = HSFormat.format_logo_params(custom_logo_file) + + payload = { + "name": name, + "domain": domain, + "callback_url": callback_url, + "oauth[callback_url]": oauth_callback_url, + "oauth[scopes]": oauth_scopes, + "white_labeling_options": json.dumps(white_labeling_options), + "options[can_insert_everywhere]": self._boolean(option_insert_everywhere) + } + + # remove attributes with none value + payload = HSFormat.strip_none_values(payload) + + request = self._get_request() + url = self.API_APP_UPDATE_URL + client_id + + return request.post(url, data=payload, files=custom_logo_payload) + + def delete_api_app(self, client_id): + ''' Deletes the specified API App + + Deletes an API App. Can only be involved for API Apps you own. + + Returns: + None + + ''' + request = self._get_request() + request.delete(url=self.API_APP_DELETE_URL + client_id) # ---- UNCLAIMED DRAFT METHODS --------------------- diff --git a/hellosign_sdk/resource/__init__.py b/hellosign_sdk/resource/__init__.py index 11669bd..34a3bb0 100644 --- a/hellosign_sdk/resource/__init__.py +++ b/hellosign_sdk/resource/__init__.py @@ -1,4 +1,5 @@ from .account import Account +from .apiapp import ApiApp from .embedded import Embedded from .signature import Signature from .signature_request import SignatureRequest @@ -8,4 +9,4 @@ from .resource_list import ResourceList from .resource import Resource -__all__ = [Account, Embedded, Signature, SignatureRequest, Team, Template, UnclaimedDraft, Resource, ResourceList] +__all__ = [Account, ApiApp, Embedded, Signature, SignatureRequest, Team, Template, UnclaimedDraft, Resource, ResourceList] diff --git a/hellosign_sdk/resource/apiapp.py b/hellosign_sdk/resource/apiapp.py new file mode 100644 index 0000000..f8156eb --- /dev/null +++ b/hellosign_sdk/resource/apiapp.py @@ -0,0 +1,96 @@ +from .resource import Resource +from hellosign_sdk.utils import HSAccessTokenAuth + +# +# The MIT License (MIT) +# +# Copyright (C) 2014 hellosign.com +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + + +class ApiApp(Resource): + ''' Contains information about an API App. + + Attributes: + client_id (str): The API App's Client ID + + created_at (int): Unix timestamp of when the API App was created + + name (str): The name of the API App + + domain (str): The domain name associated with the API App + + callback_url (str) : The URL that HelloSign events will be POSTed to + + is_approved (bool): Indicates if the API App is approved + + owner_account (dict): Information about the API App owner + + account_id (str): The id of the Account + + email_address (str): The email address associated with the Account + + options (dict): Options that override the Account settings + + can_insert_everywhere (bool): Denotes if signers can "Insert Everywhere" when + signing a document + + oauth (dict): Information about the API App's OAuth properties. Null if OAuth is + not configured for the API App. + + callback_url (str): The URL that HelloSign OAuth events will be POSTed to + + secret (str): The API App's OAuth secret + + scopes (list): List of the API App's OAuth scopes + + charges_users (bool): Indicates whether the API App or the authorized user + is billed for OAuth requests. + + white_labeling_options (dict): Customization options for the API App's signer page + + Examples: + To print the client_id + + >>> from hsclient import HSClient + >>> client = HSClient() + >>> app = client.get_api_app_info() + >>> print app.client_id + + ''' + + def __init__(self, jsonstr=None, key=None, warnings=None): + ''' Initialization of the object + + Args: + jsonstr (str): a raw JSON string that is returned by a request. + We store all the data in `self.json_data` and use `__getattr__` + and `__setattr__` to make the data accessible like attributes + of the object + key (str): Optional key to use with jsonstr. If `key` exists, we'll + load the data of `jsonstr[key]` instead of the whole `jsonstr` + warnings (list): List of associated warnings + ''' + super(ApiApp, self).__init__(jsonstr, key, warnings) + + def __str__(self): + ''' Return a string representation of this Account ''' + return 'ApiApp %s (%s)' % (self.name, self.client_id) diff --git a/hellosign_sdk/resource/resource.py b/hellosign_sdk/resource/resource.py index f6fbc16..45fee83 100644 --- a/hellosign_sdk/resource/resource.py +++ b/hellosign_sdk/resource/resource.py @@ -2,9 +2,9 @@ # # The MIT License (MIT) -# +# # Copyright (C) 2014 hellosign.com -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -27,7 +27,7 @@ class Resource(object): ''' An abstract class to represent some objects used by our SDK such as - Account, SignatureRequest, Template, Team, UnclaimedDraft, Embedded. + Account, ApiAp, SignatureRequest, Template, Team, UnclaimedDraft, Embedded. These objects share the same way of storing data. Information and settings are stored physically in `self.json_data`, and diff --git a/hellosign_sdk/resource/resource_list.py b/hellosign_sdk/resource/resource_list.py index 31cb888..f399691 100644 --- a/hellosign_sdk/resource/resource_list.py +++ b/hellosign_sdk/resource/resource_list.py @@ -2,9 +2,9 @@ # # The MIT License (MIT) -# +# # Copyright (C) 2014 hellosign.com -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -30,7 +30,8 @@ class ResourceList(list): items_keys = { 'SignatureRequest': 'signature_requests', - 'Template': 'templates' + 'Template': 'templates', + 'ApiApp': 'api_apps' } page = 0 diff --git a/hellosign_sdk/utils/hsformat.py b/hellosign_sdk/utils/hsformat.py index 3bc9ae8..bbc47fd 100644 --- a/hellosign_sdk/utils/hsformat.py +++ b/hellosign_sdk/utils/hsformat.py @@ -59,6 +59,15 @@ def format_file_url_params(file_urls): file_urls_payload["file_url[" + str(idx) + "]"] = fileurl return file_urls_payload + @staticmethod + def format_logo_params(logo): + ''' + Utility method for formatting custom logo parameters for API Apps + ''' + logo_payload = {} + logo_payload["custom_logo_file"] = open(logo, 'rb') + return logo_payload + @staticmethod def format_param_list(listed_params, output_name): ''' diff --git a/hellosign_sdk/utils/request.py b/hellosign_sdk/utils/request.py index adcc584..d0c63d7 100644 --- a/hellosign_sdk/utils/request.py +++ b/hellosign_sdk/utils/request.py @@ -169,6 +169,28 @@ def post(self, url, data=None, files=None, headers=None, get_json=True): return json_response if get_json is True else response + def delete(self, url, headers=None): + ''' Make POST request to a url + + Args: + url (str): URL to send the request to + headers (str, optional): custom headers + + Returns: + None + + ''' + + if self.debug: + print("POST: %s, headers=%s" % (url, headers)) + + self.headers = self._get_default_headers() + if headers is not None: + self.headers.update(headers) + + response = requests.delete(url, headers=self.headers, auth=self.auth, verify=self.verify_ssl) + + return response #### HELPERS ######################################## From ce28d1a2c9e315f7c24c2d7a4a103b0ac4f89352 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Fri, 25 Jan 2019 17:36:45 +0100 Subject: [PATCH 12/18] Fix hyperlinks and typos --- CONTRIBUTING.md | 4 ++-- README.md | 4 ++-- hellosign_sdk/resource/account.py | 8 ++++---- hellosign_sdk/resource/apiapp.py | 1 - hellosign_sdk/resource/resource.py | 3 ++- setup.py | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4265e83..8667f74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ We're excited you're considering contributing to our project! Your patches are e * Make sure you have a [GitHub account](https://github.com/signup/free) * Make sure you have a [HelloSign account](http://www.hellosign.com) -* Submit a new [issue ticket](https://github.com/HelloFax/hellosign-java-sdk/issues), assuming one does not already exist. +* Submit a new [issue ticket](https://github.com/hellosign/hellosign-python-sdk), assuming one does not already exist. * Clearly describe the issue including steps to reproduce when it is a bug. * Make sure to include the version you are using which has the issue (and confirm that the issue you are having has not been fixed in a later version) * Fork the repository on GitHub @@ -27,7 +27,7 @@ always necessary to create a new issue ticket. ## Submitting Changes * Push your changes to your fork of the repository. -* Submit a pull request to the repository in the HelloFax organization. +* Submit a pull request to the repository in the HelloSign organization. * Update your issue ticket to mark that you have submitted code and are ready for it to be reviewed (Status: Ready for Merge). * Include a link to the pull request in the ticket. * The HelloSign dev team looks at Pull Requests on a regular basis. diff --git a/README.md b/README.md index c624191..e6eb0b6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ pip install hellosign-python-sdk Install from code: ````sh -git clone https://github.com/HelloFax/hellosign-python-sdk.git +git clone https://github.com/HelloSign/hellosign-python-sdk.git cd hellosign-python-sdk python setup.py install ```` @@ -213,7 +213,7 @@ draft = client.create_embedded_unclaimed_draft( claim_url = draft.claim_url ```` -More information about the asscociated front-end code can be found [here](https://www.hellosign.com/api/embeddedRequestingWalkthrough#ClientSideRequesting) +More information about the associated front-end code can be found [here](https://app.hellosign.com/api/embeddedRequestingWalkthrough#EmbeddedRequestingClientSide) Once the user edits the draft in the embedded iFrame and sends the signature request your app callback will receive a `signature_request_sent` event containing a `SignatureRequest` object. If we had used `is_for_embedded_signing=True`, we would want to get the signature ids out of the `SignatureRequest` from that event and fetch the signature urls at this point. In your event callback handler, you will need to do something like this: diff --git a/hellosign_sdk/resource/account.py b/hellosign_sdk/resource/account.py index d7abc28..2a564a4 100644 --- a/hellosign_sdk/resource/account.py +++ b/hellosign_sdk/resource/account.py @@ -3,9 +3,9 @@ # # The MIT License (MIT) -# +# # Copyright (C) 2014 hellosign.com -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -47,8 +47,8 @@ class Account(Resource): callback_url (str): The URL that HelloSign events will be POSTed to - role_code (str): The membership role for the team. - a = Admin, + role_code (str): The membership role for the team. + a = Admin, m = Member d = Developer diff --git a/hellosign_sdk/resource/apiapp.py b/hellosign_sdk/resource/apiapp.py index f8156eb..2350881 100644 --- a/hellosign_sdk/resource/apiapp.py +++ b/hellosign_sdk/resource/apiapp.py @@ -1,5 +1,4 @@ from .resource import Resource -from hellosign_sdk.utils import HSAccessTokenAuth # # The MIT License (MIT) diff --git a/hellosign_sdk/resource/resource.py b/hellosign_sdk/resource/resource.py index 45fee83..ec21371 100644 --- a/hellosign_sdk/resource/resource.py +++ b/hellosign_sdk/resource/resource.py @@ -24,10 +24,11 @@ # SOFTWARE. # + class Resource(object): ''' An abstract class to represent some objects used by our SDK such as - Account, ApiAp, SignatureRequest, Template, Team, UnclaimedDraft, Embedded. + Account, ApiApp, SignatureRequest, Template, Team, UnclaimedDraft, Embedded. These objects share the same way of storing data. Information and settings are stored physically in `self.json_data`, and diff --git a/setup.py b/setup.py index 3b532cd..6ac3162 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ def readme(): 'Programming Language :: Python :: 2.7' ], keywords='hellosign python sdk', - url='https://github.com/HelloFax/hellosign-python-sdk', + url='https://github.com/hellosign/hellosign-python-sdk', author='HelloSign', author_email='apisupport@hellosign.com', license='MIT', From 369561fdac60fe731b0188b43c923e96993219f7 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Wed, 30 Jan 2019 12:46:42 -0800 Subject: [PATCH 13/18] Add missing parameters for unclaimed drafts --- hellosign_sdk/hsclient.py | 81 ++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 1307d56..47ae3a7 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -396,7 +396,7 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -476,7 +476,7 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -644,7 +644,7 @@ def send_signature_request_embedded(self, test_mode=False, client_id=None, files allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -729,7 +729,7 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object of the newly created Signature Request @@ -968,7 +968,7 @@ def create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fals allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when creating a tempate. Defaults to False. + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when creating a template. Defaults to False. Returns: A Template object specifying the Id of the draft @@ -1310,7 +1310,7 @@ def delete_api_app(self, client_id): # ---- UNCLAIMED DRAFT METHODS --------------------- - def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, cc_email_addresses=None, signing_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, allow_decline=False): + def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, allow_decline=False, signing_options=None): ''' Creates a new Draft that can be claimed using the claim URL Creates a new Draft that can be claimed using the claim URL. The first @@ -1342,6 +1342,8 @@ def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, dr email_address (str): Email address of the signer order (str, optional): The order the signer is required to sign in + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. @@ -1352,8 +1354,14 @@ def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, dr use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + + hide_text_tags (bool, optional): Hide text tag areas + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + Returns: An UnclaimedDraft object @@ -1376,16 +1384,20 @@ def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, dr 'message': message, 'signing_redirect_url': signing_redirect_url, 'signers': signers, + 'custom_fields': custom_fields, 'cc_email_addresses': cc_email_addresses, 'form_fields_per_document': form_fields_per_document, 'metadata': metadata, 'use_preexisting_fields': use_preexisting_fields, - 'allow_decline': allow_decline + 'use_text_tags': use_text_tags, + 'hide_text_tags': hide_text_tags, + 'allow_decline': allow_decline, + 'signing_options': signing_options } return self._create_unclaimed_draft(**params) - def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, allow_decline=False): + def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None, allow_ccs=False): ''' Creates a new Draft to be used for embedded requesting Args: @@ -1414,6 +1426,8 @@ def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_fo email_address (str): Email address of the signer order (str, optional): The order the signer is required to sign in + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags for form_fields_per_document. An item of the list should look like this: `{'name: value'}` + cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. @@ -1426,8 +1440,18 @@ def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_fo use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + + hide_text_tags (bool, optional): Hide text tag areas + + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. + Returns: An UnclaimedDraft object @@ -1456,11 +1480,18 @@ def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_fo 'signing_redirect_url': signing_redirect_url, 'requesting_redirect_url': requesting_redirect_url, 'signers': signers, + 'custom_fields': custom_fields, 'cc_email_addresses': cc_email_addresses, 'form_fields_per_document': form_fields_per_document, 'metadata': metadata, 'use_preexisting_fields': use_preexisting_fields, - 'allow_decline': allow_decline + 'use_text_tags': use_text_tags, + 'hide_text_tags': hide_text_tags, + 'skip_me_now': skip_me_now, + 'signing_options': signing_options, + 'allow_reassign': allow_reassign, + 'allow_decline': allow_decline, + 'allow_ccs': allow_ccs } return self._create_unclaimed_draft(**params) @@ -1708,7 +1739,7 @@ def _send_signature_request(self, test_mode=False, client_id=None, files=None, f allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -1808,7 +1839,7 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - signing_options (dict, optional): Allows the reqeuster to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -1872,7 +1903,7 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, return response @api_resource(UnclaimedDraft) - def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, allow_decline=False): + def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, skip_me_now=False, allow_reassign=False, allow_decline=False, signing_options=None, allow_ccs=False): ''' Creates a new Draft that can be claimed using the claim URL Args: @@ -1901,6 +1932,8 @@ def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedd email_address (str): Email address of the signer order (str, optional): The order the signer is required to sign in + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags or form_fields_per_document. An item of the list should look like this: `{'name: value'}` + cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. @@ -1913,8 +1946,20 @@ def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedd use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + + hide_text_tags (bool, optional): Hide text tag areas + + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. + Returns: An UnclaimedDraft object @@ -1938,6 +1983,9 @@ def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedd # CCs cc_email_addresses_payload = HSFormat.format_param_list(cc_email_addresses, 'cc_email_addresses') + # Custom fields + custom_fields_payload = HSFormat.format_custom_fields(custom_fields) + # Metadata metadata_payload = HSFormat.format_single_dict(metadata, 'metadata') @@ -1949,7 +1997,13 @@ def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedd "signing_redirect_url": signing_redirect_url, "form_fields_per_document": form_fields_per_document, "use_preexisting_fields": self._boolean(use_preexisting_fields), - "allow_decline": self._boolean(allow_decline) + "use_text_tags": self._boolean(use_text_tags), + "hide_text_tags": self._boolean(hide_text_tags), + "skip_me_now": self._boolean(skip_me_now), + "allow_reassign": self._boolean(allow_reassign), + "allow_decline": self._boolean(allow_decline), + "signing_options": json.dumps(signing_options), + "allow_ccs": self._boolean(allow_ccs) } url = self.UNCLAIMED_DRAFT_CREATE_URL @@ -1968,6 +2022,7 @@ def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedd data = payload.copy() data.update(signers_payload) + data.update(custom_fields_payload) data.update(cc_email_addresses_payload) data.update(file_urls_payload) data.update(metadata_payload) From a1c0aee459709421a3222eb147d173d4acfd780c Mon Sep 17 00:00:00 2001 From: Jen Young Date: Wed, 30 Jan 2019 15:04:16 -0800 Subject: [PATCH 14/18] Add parameters for unclaimed draft with template endpont --- hellosign_sdk/hsclient.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 47ae3a7..8f5f7b7 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -1496,7 +1496,7 @@ def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_fo return self._create_unclaimed_draft(**params) - def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, allow_decline=False): + def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, files=None, file_urls=None, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates a new Draft to be used for embedded requesting Args: @@ -1534,8 +1534,18 @@ def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_ custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + files (list of str): The uploaded file(s) to append to the Signature Request. + + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + ''' self._check_required_fields({ @@ -1561,9 +1571,14 @@ def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_ 'requesting_redirect_url': requesting_redirect_url, 'signers': signers, 'ccs': ccs, - 'custom_fields': custom_fields, 'metadata': metadata, - 'allow_decline': allow_decline + 'custom_fields': custom_fields, + 'files': files, + 'file_urls': file_urls, + 'skip_me_now': skip_me_now, + 'allow_decline': allow_decline, + 'allow_reassign': allow_reassign, + 'signing_options': signing_options } return self._create_embedded_unclaimed_draft_with_template(**params) @@ -2162,7 +2177,7 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal return response @api_resource(UnclaimedDraft) - def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, allow_decline=False): + def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, files=None, file_urls=None, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None): ''' Helper method for creating unclaimed drafts from templates See public function for params. ''' @@ -2179,7 +2194,10 @@ def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client "message": message, "signing_redirect_url": signing_redirect_url, "requesting_redirect_url": requesting_redirect_url, - "allow_decline": self._boolean(allow_decline) + "skip_me_now": self._boolean(skip_me_now), + "allow_decline": self._boolean(allow_decline), + "allow_reassign": self._boolean(allow_reassign), + "signing_options": json.dumps(signing_options) } #format multi params @@ -2189,6 +2207,12 @@ def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client metadata_payload = HSFormat.format_single_dict(metadata, 'metadata') custom_fields_payload = HSFormat.format_custom_fields(custom_fields) + # Files + files_payload = HSFormat.format_file_params(files) + + # File URLs + file_urls_payload = HSFormat.format_file_url_params(file_urls) + #assemble payload data = {} data.update(payload) @@ -2197,11 +2221,12 @@ def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client data.update(ccs_payload) data.update(metadata_payload) data.update(custom_fields_payload) + data.update(file_urls_payload) data = HSFormat.strip_none_values(data) #send call url = self.UNCLAIMED_DRAFT_CREATE_EMBEDDED_WITH_TEMPLATE_URL request = self._get_request() - response = request.post(url, data=data) + response = request.post(url, data=data, files=files_payload) return response From eae32c506fcea3c75e661437dccbfe9ed41a7540 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Wed, 30 Jan 2019 15:26:35 -0800 Subject: [PATCH 15/18] Add edit and resend endpoint --- hellosign_sdk/hsclient.py | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 8f5f7b7..9aaf6b7 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -61,6 +61,7 @@ class HSClient(object): UNCLAIMED_DRAFT_CREATE_URL = '' UNCLAIMED_DRAFT_CREATE_EMBEDDED_URL = '' UNCLAIMED_DRAFT_CREATE_EMBEDDED_WITH_TEMPLATE_URL = '' + UNCLAIMED_DRAFT_EDIT_AND_RESEND_URL = '' TEMPLATE_GET_URL = '' TEMPLATE_GET_LIST_URL = '' @@ -159,6 +160,7 @@ def _init_endpoints(self): self.UNCLAIMED_DRAFT_CREATE_URL = self.API_URL + '/unclaimed_draft/create' self.UNCLAIMED_DRAFT_CREATE_EMBEDDED_URL = self.API_URL + '/unclaimed_draft/create_embedded' self.UNCLAIMED_DRAFT_CREATE_EMBEDDED_WITH_TEMPLATE_URL = self.API_URL + '/unclaimed_draft/create_embedded_with_template' + self.UNCLAIMED_DRAFT_EDIT_AND_RESEND_URL = self.API_URL + '/unclaimed_draft/edit_and_resend/' self.TEMPLATE_GET_URL = self.API_URL + '/template/' self.TEMPLATE_GET_LIST_URL = self.API_URL + '/template/list' @@ -539,6 +541,7 @@ def remind_signature_request(self, signature_request_id, email_address, name=Non "name": name }) + @api_resource(SignatureRequest) def update_signature_request(self, signature_request_id, signature_id, email_address): ''' Updates the email address for a given signer on a signature request. @@ -1546,6 +1549,9 @@ def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_ signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + Returns: + An UnclaimedDraft object + ''' self._check_required_fields({ @@ -1583,6 +1589,50 @@ def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_ return self._create_embedded_unclaimed_draft_with_template(**params) + @api_resource(UnclaimedDraft) + def unclaimed_draft_edit_and_resend(self, signature_request_id, client_id, test_mode=False, requesting_redirect_url=None, signing_redirect_url=None, is_for_embedded_signing=False, requester_email_address=None): + ''' Updates a new signature request from an embedded request that can be edited prior to being sent. + + Args: + + signature_request_id (str): The id of the SignatureRequest to edit and resend + + client_id (str): Client id of the app you're using to create this draft. Visit our embedded page to learn more about this parameter. + + test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + + requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. + + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + + is_for_embedded_signing (bool, optional): The request created from this draft will also be signable in embedded mode if set to True. The default is False. + + requester_email_address (str, optional): The email address of the user that should be designated as the requester of this draft, if the draft type is "request_signature." + + Returns: + A UnclaimedDraft object + + ''' + + self._check_required_fields({ + "client_id": client_id + } + ) + + data = { + 'client_id': client_id, + 'test_mode': self._boolean(test_mode), + 'requesting_redirect_url': requesting_redirect_url, + 'signing_redirect_url': signing_redirect_url, + 'is_for_embedded_signing': self._boolean(is_for_embedded_signing), + 'requester_email_address': requester_email_address + } + + data = HSFormat.strip_none_values(data) + + request = self._get_request() + return request.post(self.UNCLAIMED_DRAFT_EDIT_AND_RESEND_URL + signature_request_id, data=data) + # ---- OAUTH METHODS ------------------------------- def get_oauth_data(self, code, client_id, client_secret, state): From ffb5ce3f2b74ab76b8b6df3065426632c9f370e2 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Wed, 30 Jan 2019 16:33:21 -0800 Subject: [PATCH 16/18] Update comments for consistency --- hellosign_sdk/hsclient.py | 802 ++++++++++++++++++++++---------------- 1 file changed, 457 insertions(+), 345 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index 9aaf6b7..bc3af9e 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -89,19 +89,19 @@ class HSClient(object): request = None response_callback = None - def __init__(self, email_address=None, password=None, api_key=None, access_token=None, access_token_type="Bearer", env='production'): + def __init__(self, email_address=None, password=None, api_key=None, access_token=None, access_token_type='Bearer', env='production'): '''Initialize the client object with authentication information to send requests Args: - email_address (str): E-mail of the account to make the requests + email_address (str): E-mail of the account to make the requests - password (str): Password of the account used with email address + password (str): Password of the account used with email address - api_key (str): API Key. You can find your API key in https://www.hellosign.com/home/myAccount/current_tab/integrations + api_key (str): API Key. You can find your API key in https://app.hellosign.com/home/myAccount/current_tab/integrations#api - access_token (str): OAuth access token to use + access_token (str): OAuth access token to use - access_token_type (str): Type of OAuth token (defaults to Bearer, which is the only value supported for now) + access_token_type (str): Type of OAuth token (defaults to Bearer, which is the only value supported for now) ''' @@ -194,13 +194,13 @@ def create_account(self, email_address, password=None, client_id=None, client_se OAuth data that can be used to execute actions on behalf of the newly created account. Args: - email_address (str): Email address of the new account to create + email_address (str): Email address of the new account to create - password (str): [DEPRECATED] This parameter will be ignored + password (str): [DEPRECATED] This parameter will be ignored - client_id (str, optional): Client id of the app to use to create this account + client_id (str, optional): Client id of the app to use to create this account - client_secret (str, optional): Secret of the app to use to create this account + client_secret (str, optional): Secret of the app to use to create this account Returns: The new Account object @@ -262,12 +262,12 @@ def update_account_info(self): def verify_account(self, email_address): ''' Verify whether a HelloSign Account exists - Args: + Args: - email_address (str): Email address for the account to verify + email_address (str): Email address of the new account to create - Returns: - True or False + Returns: + True or False ''' request = self._get_request() resp = request.post(self.ACCOUNT_VERIFY_URL, { @@ -283,7 +283,7 @@ def get_signature_request(self, signature_request_id): Args: - signature_request_id (str): The id of the SignatureRequest to retrieve + signature_request_id (str): The id of the SignatureRequest to retrieve Returns: A SignatureRequest object @@ -304,7 +304,7 @@ def get_signature_request_list(self, page=1): Args: - page (int, optional): Which page number of the SignatureRequest list to return. Defaults to 1. + page (int, optional): Which page number of the SignatureRequest list to return. Defaults to 1. Returns: A ResourceList object @@ -327,13 +327,14 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi path_or_file (str or file): A writable File-like object or a full path to save the PDF file to. - filename (str): [DEPRECATED] Filename to save the PDF file to. This should be a full path. + filename (str): [DEPRECATED] Filename to save the PDF file to. This should be a full path. - file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. + file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" + for a collection of individual documents. Defaults to "pdf" if not specified. - get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. + get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. - get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. + get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. Returns: Returns a PDF file, URL link to file, or base64 encoded file @@ -351,7 +352,11 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi url += '?get_data_uri=1' return request.get(url) - def send_signature_request(self, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, custom_fields=None, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): + def send_signature_request(self, test_mode=False, files=None, file_urls=None, + title=None, subject=None, message=None, signing_redirect_url=None, + signers=None, cc_email_addresses=None, form_fields_per_document=None, + use_text_tags=False, hide_text_tags=False, custom_fields=None, + metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates and sends a new SignatureRequest with the submitted documents Creates and sends a new SignatureRequest with the submitted documents. @@ -361,44 +366,47 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding + if set to True. Defaults to False. - files (list of str): The uploaded file(s) to send for signature. + files (list of str): The uploaded file(s) to send for signature. - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - title (str, optional): The title you want to assign to the SignatureRequest. + title (str, optional): The title you want to assign to the SignatureRequest. - subject (str, optional): The subject in the email that will be sent to the signers. + subject (str, optional): The subject in the email that will be sent to the signers. - message (str, optional): The custom message in the email that will be sent to the signers. + message (str, optional): The custom message in the email that will be sent to the signers. - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - cc_email_addresses (list, optional): A list of email addresses that should be CC'd on the request. + cc_email_addresses (list, optional): A list of email addresses that should be CC'd on the request. - form_fields_per_document (str): The signer components that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://app.hellosign.com/api/reference#SignatureRequest). + form_fields_per_document (str): The signer components that should appear on the document, expressed as a serialized + JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://app.hellosign.com/api/reference#SignatureRequest). - use_text_tags (bool, optional): Use text tags in the provided file(s) to specify signer components. + use_text_tags (bool, optional): Use text tags in the provided file(s) to specify signer components. - hide_text_tags (bool, optional): Hide text tag areas. + hide_text_tags (bool, optional): Hide text tag areas. - custom_fields (list of dict, optional): A list of custom fields defined by Text Tags for Form Fields per Document. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields defined by Text Tags for Form Fields per Document. + An item of the list should look like this: `{'name: value'}` - metadata (dict, optional): Metadata associated with the signature request. + metadata (dict, optional): Metadata associated with the signature request. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to True. Defaults to False. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to True. Defaults to False. - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -434,7 +442,10 @@ def send_signature_request(self, test_mode=False, files=None, file_urls=None, ti return self._send_signature_request(**params) - def send_signature_request_with_template(self, test_mode=False, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): + def send_signature_request_with_template(self, test_mode=False, template_id=None, + template_ids=None, title=None, subject=None, message=None, + signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, + metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): ''' Creates and sends a new SignatureRequest based off of a Template Creates and sends a new SignatureRequest based off of the Template @@ -442,43 +453,47 @@ def send_signature_request_with_template(self, test_mode=False, template_id=None Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. + template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. - template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. + template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - role_name (str): Signer role - name (str): The name of the signer - email_address (str): Email address of the signer - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + role_name (str): Signer role + name (str): The name of the signer + email_address (str): Email address of the signer + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - ccs (list of str, optional): The email address of the CC filling the role of RoleName. Required when a CC role exists for the Template. Each dict has the following attributes: + ccs (list of str, optional): The email address of the CC filling the role of RoleName. + Required when a CC role exists for the Template. Each dict has the following attributes: - role_name (str): CC role name - email_address (str): CC email address + role_name (str): CC role name + email_address (str): CC email address - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. + Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` - metadata (dict, optional): Metadata to associate with the signature request + metadata (dict, optional): Metadata to associate with the signature request - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - files (list of str): The uploaded file(s) to append to the Signature Request. + files (list of str): The uploaded file(s) to append to the Signature Request. - file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. + Use either `files` or `file_urls` - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. + Defaults to account settings. Returns: A SignatureRequest object @@ -527,9 +542,9 @@ def remind_signature_request(self, signature_request_id, email_address, name=Non signature_request_id (str): The id of the SignatureRequest to send a reminder for - email_address (str): The email address of the signer to send a reminder to + email_address (str): The email address of the signer to send a reminder to - name (str, optional): The name of the signer to send a reminder to + name (str, optional): The name of the signer to send a reminder to Returns: A SignatureRequest object @@ -549,9 +564,9 @@ def update_signature_request(self, signature_request_id, signature_id, email_add signature_request_id (str): The id of the SignatureRequest to update - signature_id (str): The signature id for the recipient + signature_id (str): The signature id for the recipient - email_address (str): The new email address of the recipient + email_address (str): The new email address of the recipient Returns: A SignatureRequest object @@ -584,7 +599,8 @@ def cancel_signature_request(self, signature_request_id): def remove_signature_request_access(self, signature_request_id): ''' Removes your access to a completed SignatureRequest - The SignatureRequest must be fully executed by all parties (signed or declined to sign). Other parties will continue to maintain access to the completed signature request document(s). + The SignatureRequest must be fully executed by all parties (signed or declined to sign). + Other parties will continue to maintain access to the completed signature request document(s). Args: @@ -597,11 +613,15 @@ def remove_signature_request_access(self, signature_request_id): request = self._get_request() request.post(url=self.SIGNATURE_REQUEST_REMOVE_ACCESS_URL + signature_request_id, get_json=False) - def send_signature_request_embedded(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): + def send_signature_request_embedded(self, test_mode=False, client_id=None, + files=None, file_urls=None, title=None, subject=None, message=None, + signing_redirect_url=None, signers=None, cc_email_addresses=None, + form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, + metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): ''' Creates and sends a new SignatureRequest with the submitted documents Creates a new SignatureRequest with the submitted documents to be signed - in an embedded iFrame . If form_fields_per_document is not specified, a + in an embedded iFrame. If form_fields_per_document or text tags are not specified, a signature page will be affixed where all signers will be required to add their signature, signifying their agreement to all contained documents. Note that embedded signature requests can only be signed in embedded @@ -610,44 +630,46 @@ def send_signature_request_embedded(self, test_mode=False, client_id=None, files Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. + Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) - files (list of str): The uploaded file(s) to send for signature + files (list of str): The uploaded file(s) to send for signature - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - cc_email_addresses (list, optional): A list of email addresses that should be CCed + cc_email_addresses (list, optional): A list of email addresses that should be CCed - form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) + form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized + JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas - metadata (dict, optional): Metadata to associate with the signature request + metadata (dict, optional): Metadata to associate with the signature request - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -685,7 +707,11 @@ def send_signature_request_embedded(self, test_mode=False, client_id=None, files return self._send_signature_request(**params) - def send_signature_request_embedded_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): + def send_signature_request_embedded_with_template(self, test_mode=False, + client_id=None, template_id=None, template_ids=None, title=None, + subject=None, message=None, signing_redirect_url=None, signers=None, + ccs=None, custom_fields=None, metadata=None, allow_decline=False, + files=None, file_urls=None, signing_options=None): ''' Creates and sends a new SignatureRequest based off of a Template Creates a new SignatureRequest based on the given Template to be @@ -695,47 +721,50 @@ def send_signature_request_embedded_with_template(self, test_mode=False, client_ Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. + Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) - template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. + template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. - template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. + template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + name (str): The name of the signer + email_address (str): Email address of the signer + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - ccs (list of dict, optional): The email address of the CC filling the role of RoleName. Required when a CC role exists for the Template. Each dict has the following attributes: + ccs (list of dict, optional): The email address of the CC filling the role of RoleName. + Required when a CC role exists for the Template. Each dict has the following attributes: - role_name (str): CC role name - email_address (str): CC email address + role_name (str): CC role name + email_address (str): CC email address - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. + An item of the list should look like this: `{'name: value'}` - metadata (dict, optional): Metadata to associate with the signature request + metadata (dict, optional): Metadata to associate with the signature request - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - files (list of str): The uploaded file(s) to append to the Signature Request. + files (list of str): The uploaded file(s) to append to the Signature Request. - file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: - A SignatureRequest object of the newly created Signature Request + A SignatureRequest object ''' @@ -794,10 +823,14 @@ def get_template_list(self, page=1, page_size=None, account_id=None, query=None) Args: - page (int, optional): Page number of the template List to return. Defaults to 1. - page_size (int, optional): Number of objects to be returned per page, must be between 1 and 100, default is 20. - account_id (str, optional): Which account to return Templates for. Must be a team member. Use "all" to indicate all team members. Defaults to your account. - query (str, optional): String that includes search terms and/or fields to be used to filter the Template objects. + page (int, optional): Page number of the template List to return. Defaults to 1. + + page_size (int, optional): Number of objects to be returned per page, must be between 1 and 100, default is 20. + + account_id (str, optional): Which account to return Templates for. Must be a team member. + Use "all" to indicate all team members. Defaults to your account. + + query (str, optional): String that includes search terms and/or fields to be used to filter the Template objects. Returns: A ResourceList object @@ -818,11 +851,11 @@ def add_user_to_template(self, template_id, account_id=None, email_address=None) Args: - template_id (str): The id of the template to give the account access to + template_id (str): The id of the template to give the account access to - account_id (str): The id of the account to give access to the template. The account id prevails if both account_id and email_address are provided. + account_id (str): The id of the account to give access to the template. The account id prevails if both account_id and email_address are provided. - email_address (str): The email address of the account to give access to. + email_address (str): The email address of the account to give access to. Returns: A Template object @@ -835,11 +868,12 @@ def remove_user_from_template(self, template_id, account_id=None, email_address= Args: - template_id (str): The id of the template to remove the account's access from. + template_id (str): The id of the template to remove the account's access from. - account_id (str): The id of the account to remove access from the template. The account id prevails if both account_id and email_address are provided. + account_id (str): The id of the account to remove access from the template. + The account id prevails if both account_id and email_address are provided. - email_address (str): The email address of the account to remove access from. + email_address (str): The email address of the account to remove access from. Returns: An Template object @@ -866,22 +900,24 @@ def delete_template(self, template_id): return response - def get_template_files(self, template_id, path_or_file=None, file_type=None, filename=None, get_url=False, get_data_uri=False): - ''' Download a copy of a template's original files + def get_template_files(self, template_id, path_or_file=None, file_type=None, + filename=None, get_url=False, get_data_uri=False): + ''' Downloads a copy of a template's original files Args: - template_id (str): id of the template to download + template_id (str): id of the template to download path_or_file (str or file): A writable File-like object or a full path to save the PDF file to. - filename (str): [DEPRECATED] Filename to save the PDF file to. This should be a full path. + filename (str): [DEPRECATED] Filename to save the PDF file to. This should be a full path. - file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. + file_type (str): Type of file to return. Either "pdf" for a single merged document or + "zip" for a collection of individual documents. Defaults to "pdf" if not specified. - get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. + get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. - get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. + get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. Returns: Returns a PDF file, URL link to file, or base64 encoded file @@ -899,24 +935,27 @@ def get_template_files(self, template_id, path_or_file=None, file_type=None, fil url += '?get_data_uri=1' return request.get(url) - def update_template_files(self, template_id, files=None, file_urls=None, subject=None, message=None, client_id=None, test_mode=False): + def update_template_files(self, template_id, files=None, file_urls=None, + subject=None, message=None, client_id=None, test_mode=False): ''' Overlays a new file with the overlay of an existing template. Args: - template_id (str): The id of the template whose files to update + template_id (str): The id of the template whose files to update - files (list of str): The file(s) to use for the template. + files (list of str): The file(s) to use for the template. - file_urls (list of str): URLs of the file for HelloSign to use for the template. Use either `files` or `file_urls`, but not both. + file_urls (list of str): URLs of the file for HelloSign to use for the template. + Use either `files` or `file_urls`, but not both. - subject (str, optional): The default template email subject + subject (str, optional): The default template email subject - message (str, optional): The default template email message + message (str, optional): The default template email message - test_mode (bool, optional): Whether this is a test, the signature request created from this Template will not be legally binding if set to 1. Defaults to 0. + test_mode (bool, optional): Whether this is a test, the signature request created + from this Template will not be legally binding if set to 1. Defaults to 0. - client_id (str): Client id of the app associated with the Template + client_id (str): Client id of the app associated with the Template Returns: A Template object @@ -932,49 +971,58 @@ def update_template_files(self, template_id, files=None, file_urls=None, subject "client_id": client_id }) - def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, allow_reassign=False, metadata=None, allow_ccs=False): + def create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, + files=None, file_urls=None, title=None, subject=None, message=None, + cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, + allow_reassign=False, metadata=None, allow_ccs=False): ''' Creates an embedded Template draft for further editing. Args: - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to 1. Defaults to 0. + test_mode (bool, optional): Whether this is a test, the signature request + created from this draft will not be legally binding if set to 1. Defaults to 0. - client_id (str): Client id of the app you're using to create this draft. + client_id (str): Client id of the app you're using to create this draft. - files (list of str): The file(s) to use for the template. + files (list of str): The file(s) to use for the template. - file_urls (list of str): URLs of the file for HelloSign to use for the template. Use either `files` or `file_urls`, but not both. + file_urls (list of str): URLs of the file for HelloSign to use for the template. + Use either `files` or `file_urls`, but not both. - title (str, optional): The template title + title (str, optional): The template title - subject (str, optional): The default template email subject + subject (str, optional): The default template email subject - message (str, optional): The default template email message + message (str, optional): The default template email message - signer_roles (list of dict): A list of signer roles, each of which has the following attributes: + signer_roles (list of dict): A list of signer roles, each of which has the following attributes: - name (str): The role name of the signer that will be displayed when the template is used to create a signature request. - order (str, optional): The order in which this signer role is required to sign. + name (str): The role name of the signer that will be displayed when the + template is used to create a signature request. + order (str, optional): The order in which this signer role is required to sign. - cc_roles (list of str, optional): The CC roles that must be assigned when using the template to send a signature request + cc_roles (list of str, optional): The CC roles that must be assigned when using the template to send a signature request - merge_fields (list of dict, optional): The merge fields that can be placed on the template's document(s) by the user claiming the template draft. Each must have the following two parameters: + merge_fields (list of dict, optional): The merge fields that can be placed on the template's + document(s) by the user claiming the template draft. Each must have the following two parameters: - name (str): The name of the merge field. Must be unique. - type (str): Can only be "text" or "checkbox". + name (str): The name of the merge field. Must be unique. + type (str): Can only be "text" or "checkbox". - skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. - use_preexisting_fields (bool, optional): Whether to use preexisting PDF fields + use_preexisting_fields (bool, optional): Whether to use preexisting PDF fields - metadata (dict, optional): Metadata to associate with the draft + metadata (dict, optional): Metadata to associate with the draft - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature + requests to other signers if set to True. Defaults to False. - allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when creating a template. Defaults to False. + allow_ccs (bool, optional): Specifies whether the user is allowed to + provide email addresses to CC when creating a template. Defaults to False. Returns: - A Template object specifying the Id of the draft + A Template object specifying the id of the draft ''' params = { @@ -1064,9 +1112,10 @@ def add_team_member(self, account_id=None, email_address=None): Args: - account_id (str): The id of the account of the user to invite to your team. + account_id (str): The id of the account of the user to invite to your team. - email_address (str): The email address of the account to invite to your team. The account id prevails if both account_id and email_address are provided. + email_address (str): The email address of the account to invite to your team. + The account id prevails if both account_id and email_address are provided. Returns: A Team object @@ -1080,9 +1129,10 @@ def remove_team_member(self, account_id=None, email_address=None): Args: - account_id (str): The id of the account of the user to remove from your team. + account_id (str): The id of the account of the user to remove from your team. - email_address (str): The email address of the account to remove from your team. The account id prevails if both account_id and email_address are provided. + email_address (str): The email address of the account to remove from your team. + The account id prevails if both account_id and email_address are provided. Returns: A Team object @@ -1110,27 +1160,33 @@ def get_embedded_object(self, signature_id): return request.get(self.EMBEDDED_OBJECT_GET_URL + signature_id) @api_resource(Embedded) - def get_template_edit_url(self, template_id, test_mode=False, cc_roles=None, merge_fields=None, skip_signer_roles=False, skip_subject_message=False): + def get_template_edit_url(self, template_id, test_mode=False, cc_roles=None, + merge_fields=None, skip_signer_roles=False, skip_subject_message=False): ''' Retrieves a embedded template for editing Retrieves an embedded object containing a template edit url that can be opened in an iFrame. Args: - template_id (str): The id of the template to get an edit url for + template_id (str): The id of the template to get an edit url for - test_mode (bool, optional): Whether this is a test, the signature requests created from this template will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature requests created + from this template will not be legally binding if set to True. Defaults to False. - cc_roles (list of str, optional): The CC roles that must be assigned when using the template to send a signature request + cc_roles (list of str, optional): The CC roles that must be assigned when using + the template to send a signature request - merge_fields (list of dict, optional): The merge fields that can be placed on the template's document(s) by the user claiming the template draft. Each must have the following two parameters: + merge_fields (list of dict, optional): The merge fields that can be placed on the template's document(s) + by the user claiming the template draft. Each must have the following two parameters: - name (str): The name of the merge field. Must be unique. - type (str): Can only be "text" or "checkbox". + name (str): The name of the merge field. Must be unique. + type (str): Can only be "text" or "checkbox". - skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to False. + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. + Defaults to False. - skip_subject_message (bool, optional): Disables the option to edit the template's default subject and message. Defaults to False. + skip_subject_message (bool, optional): Disables the option to edit the template's default + subject and message. Defaults to False. Returns: An Embedded object @@ -1185,8 +1241,9 @@ def get_api_app_list(self, page=1, page_size=None): Args: - page (int, optional): Page number of the API App List to return. Defaults to 1. - page_size (int, optional): Number of objects to be returned per page, must be between 1 and 100, default is 20. + page (int, optional): Page number of the API App List to return. Defaults to 1. + + page_size (int, optional): Number of objects to be returned per page, must be between 1 and 100, default is 20. Returns: A ResourceList object @@ -1200,7 +1257,9 @@ def get_api_app_list(self, page=1, page_size=None): return request.get(self.API_APP_LIST_URL, parameters=parameters) @api_resource(ApiApp) - def create_api_app(self, name, domain, callback_url=None, custom_logo_file=None, oauth_callback_url=None, oauth_scopes=None, white_labeling_options=None, option_insert_everywhere=False): + def create_api_app(self, name, domain, callback_url=None, custom_logo_file=None, + oauth_callback_url=None, oauth_scopes=None, white_labeling_options=None, + option_insert_everywhere=False): ''' Creates a new API App Creates a new API App with the specified settings. @@ -1217,7 +1276,7 @@ def create_api_app(self, name, domain, callback_url=None, custom_logo_file=None, oauth_callback_url (str, optional): The URL that HelloSign OAuth events will be POSTed to - oauth_scopes (list of str, optional): List of the API App's OAuth scopes + oauth_scopes (list of str, optional): List of the API App's OAuth scopes white_labeling_options (dict, optional): Customization options for the API App's signer page @@ -1249,7 +1308,9 @@ def create_api_app(self, name, domain, callback_url=None, custom_logo_file=None, return request.post(self.API_APP_CREATE_URL, data=payload, files=custom_logo_payload) @api_resource(ApiApp) - def update_api_app(self, client_id, name=None, domain=None, callback_url=None, custom_logo_file=None, oauth_callback_url=None, oauth_scopes=None, white_labeling_options=None, option_insert_everywhere=False): + def update_api_app(self, client_id, name=None, domain=None, callback_url=None, + custom_logo_file=None, oauth_callback_url=None, oauth_scopes=None, + white_labeling_options=None, option_insert_everywhere=False): ''' Updates the specified API App Updates an API App with the specified settings. @@ -1266,7 +1327,7 @@ def update_api_app(self, client_id, name=None, domain=None, callback_url=None, c oauth_callback_url (str, optional): The URL that HelloSign OAuth events will be POSTed to - oauth_scopes (list of str, optional): List of the API App's OAuth scopes + oauth_scopes (list of str, optional): List of the API App's OAuth scopes white_labeling_options (dict, optional): Customization options for the API App's signer page @@ -1313,7 +1374,11 @@ def delete_api_app(self, client_id): # ---- UNCLAIMED DRAFT METHODS --------------------- - def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, allow_decline=False, signing_options=None): + def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, + draft_type=None, subject=None, message=None, signers=None, custom_fields=None, + cc_email_addresses=None, signing_redirect_url=None, form_fields_per_document=None, + metadata=None, use_preexisting_fields=False, use_text_tags=False, + hide_text_tags=False, allow_decline=False, signing_options=None): ''' Creates a new Draft that can be claimed using the claim URL Creates a new Draft that can be claimed using the claim URL. The first @@ -1327,43 +1392,47 @@ def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, dr Args: - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. - files (list of str): The uploaded file(s) to send for signature + files (list of str): The uploaded file(s) to send for signature - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. + draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" + for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. + An item of the list should look like this: `{'name: value'}` cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - form_fields_per_document (str, optional): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) + form_fields_per_document (str, optional): The fields that should appear on the document, expressed as a serialized JSON + data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) - metadata (dict, optional): Metadata to associate with the draft + metadata (dict, optional): Metadata to associate with the draft - use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_preexisting_fields (bool): Whether to use preexisting PDF fields - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. + Defaults to account settings. Returns: An UnclaimedDraft object @@ -1400,60 +1469,67 @@ def create_unclaimed_draft(self, test_mode=False, files=None, file_urls=None, dr return self._create_unclaimed_draft(**params) - def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None, allow_ccs=False): + def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, + is_for_embedded_signing=False, requester_email_address=None, files=None, + file_urls=None, draft_type=None, subject=None, message=None, signers=None, + custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, + requesting_redirect_url=None, form_fields_per_document=None, metadata=None, + use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, + skip_me_now=False, allow_decline=False, allow_reassign=False, + signing_options=None, allow_ccs=False): ''' Creates a new Draft to be used for embedded requesting Args: - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app used to create the embedded draft. + client_id (str): Client id of the app used to create the embedded draft. - is_for_embedded_signing (bool, optional): Whether this is also for embedded signing. Defaults to False. + is_for_embedded_signing (bool, optional): Whether this is also for embedded signing. Defaults to False. - requester_email_address (str): Email address of the requester. + requester_email_address (str): Email address of the requester. - files (list of str): The uploaded file(s) to send for signature. + files (list of str): The uploaded file(s) to send for signature. - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. + draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags for form_fields_per_document. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags for form_fields_per_document. An item of the list should look like this: `{'name: value'}` cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. + requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. - form_fields_per_document (str, optional): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) + form_fields_per_document (str, optional): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) - metadata (dict, optional): Metadata to associate with the draft + metadata (dict, optional): Metadata to associate with the draft - use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_preexisting_fields (bool): Whether to use preexisting PDF fields - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas - skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. Returns: An UnclaimedDraft object @@ -1499,55 +1575,61 @@ def create_embedded_unclaimed_draft(self, test_mode=False, client_id=None, is_fo return self._create_unclaimed_draft(**params) - def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, files=None, file_urls=None, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None): + def create_embedded_unclaimed_draft_with_template(self, test_mode=False, + client_id=None, is_for_embedded_signing=False, template_id=None, + template_ids=None, requester_email_address=None, title=None, + subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, + requesting_redirect_url=None, metadata=None, custom_fields=None, + files=None, file_urls=None, skip_me_now=False, allow_decline=False, + allow_reassign=False, signing_options=None): ''' Creates a new Draft to be used for embedded requesting Args: - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this draft. Visit our embedded page to learn more about this parameter. + client_id (str): Client id of the app you're using to create this draft. Visit our embedded page to learn more about this parameter. - template_id (str): The id of the Template to use when creating the Unclaimed Draft. Mutually exclusive with template_ids. + template_id (str): The id of the Template to use when creating the Unclaimed Draft. Mutually exclusive with template_ids. - template_ids (list of str): The ids of the Templates to use when creating the Unclaimed Draft. Mutually exclusive with template_id. + template_ids (list of str): The ids of the Templates to use when creating the Unclaimed Draft. Mutually exclusive with template_id. - requester_email_address (str): The email address of the user that should be designated as the requester of this draft, if the draft type is "request_signature." + requester_email_address (str): The email address of the user that should be designated as the requester of this draft, if the draft type is "request_signature." - title (str, optional): The title you want to assign to the Unclaimed Draft + title (str, optional): The title you want to assign to the Unclaimed Draft - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer + name (str): The name of the signer + email_address (str): Email address of the signer - ccs (list of str, optional): A list of email addresses that should be CC'd + ccs (list of str, optional): A list of email addresses that should be CC'd - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. + requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. - is_for_embedded_signing (bool, optional): The request created from this draft will also be signable in embedded mode if set to True. The default is False. + is_for_embedded_signing (bool, optional): The request created from this draft will also be signable in embedded mode if set to True. The default is False. - metadata (dict, optional): Metadata to associate with the draft. Each request can include up to 10 metadata keys, with key names up to 40 characters long and values up to 500 characters long. + metadata (dict, optional): Metadata to associate with the draft. Each request can include up to 10 metadata keys, with key names up to 40 characters long and values up to 500 characters long. - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` - files (list of str): The uploaded file(s) to append to the Signature Request. + files (list of str): The uploaded file(s) to append to the Signature Request. - file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: An UnclaimedDraft object @@ -1590,24 +1672,29 @@ def create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_ return self._create_embedded_unclaimed_draft_with_template(**params) @api_resource(UnclaimedDraft) - def unclaimed_draft_edit_and_resend(self, signature_request_id, client_id, test_mode=False, requesting_redirect_url=None, signing_redirect_url=None, is_for_embedded_signing=False, requester_email_address=None): + def unclaimed_draft_edit_and_resend(self, signature_request_id, client_id, + test_mode=False, requesting_redirect_url=None, signing_redirect_url=None, + is_for_embedded_signing=False, requester_email_address=None): ''' Updates a new signature request from an embedded request that can be edited prior to being sent. Args: - signature_request_id (str): The id of the SignatureRequest to edit and resend + signature_request_id (str): The id of the SignatureRequest to edit and resend - client_id (str): Client id of the app you're using to create this draft. Visit our embedded page to learn more about this parameter. + client_id (str): Client id of the app you're using to create this draft. - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request created from this + draft will not be legally binding if set to True. Defaults to False. - requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. + requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - is_for_embedded_signing (bool, optional): The request created from this draft will also be signable in embedded mode if set to True. The default is False. + is_for_embedded_signing (bool, optional): The request created from this draft will also be signable in + embedded mode if set to True. The default is False. - requester_email_address (str, optional): The email address of the user that should be designated as the requester of this draft, if the draft type is "request_signature." + requester_email_address (str, optional): The email address of the user that should be designated as the + requester of this draft, if the draft type is "request_signature." Returns: A UnclaimedDraft object @@ -1640,11 +1727,11 @@ def get_oauth_data(self, code, client_id, client_secret, state): Args: - code (str): Code returned by HelloSign for our callback url + code (str): Code returned by HelloSign for our callback url - client_id (str): Client id of the associated app + client_id (str): Client id of the associated app - client_secret (str): Secret token of the associated app + client_secret (str): Secret token of the associated app Returns: A HSAccessTokenAuth object @@ -1703,20 +1790,21 @@ def _get_request(self, auth=None): self.request.response_callback = self.response_callback return self.request - def _authenticate(self, email_address=None, password=None, api_key=None, access_token=None, access_token_type=None): + def _authenticate(self, email_address=None, password=None, api_key=None, + access_token=None, access_token_type=None): ''' Create authentication object to send requests Args: - email_address (str): Email address of the account to make the requests + email_address (str): Email address of the account to make the requests - password (str): Password of the account used with email address + password (str): Password of the account used with email address - api_key (str): API Key. You can find your API key in https://www.hellosign.com/home/myAccount/current_tab/integrations + api_key (str): API Key. You can find your API key in https://app.hellosign.com/home/myAccount/current_tab/integrations#api - access_token (str): OAuth access token + access_token (str): OAuth access token - access_token_type (str): Type of OAuth access token + access_token_type (str): Type of OAuth access token Raises: NoAuthMethod: If no authentication information found @@ -1761,50 +1849,55 @@ def _check_required_fields(self, fields=None, either_fields=None): raise HSException("One of the following fields is required: %s" % ", ".join(field.keys())) @api_resource(SignatureRequest) - def _send_signature_request(self, test_mode=False, client_id=None, files=None, file_urls=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, custom_fields=None, cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, hide_text_tags=False, metadata=None, allow_decline=False, allow_reassign=False, signing_options=None): + def _send_signature_request(self, test_mode=False, client_id=None, files=None, + file_urls=None, title=None, subject=None, message=None, + signing_redirect_url=None, signers=None, custom_fields=None, + cc_email_addresses=None, form_fields_per_document=None, use_text_tags=False, + hide_text_tags=False, metadata=None, allow_decline=False, allow_reassign=False, + signing_options=None): ''' To share the same logic between send_signature_request & send_signature_request_embedded functions Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://www.hellosign.com/api/embeddedSigningWalkthrough) - files (list of str): The uploaded file(s) to send for signature + files (list of str): The uploaded file(s) to send for signature - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - cc_email_addresses (list, optional): A list of email addresses that should be CCed + cc_email_addresses (list, optional): A list of email addresses that should be CCed - form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) + form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest) - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas - metadata (dict, optional): Metadata to associate with the signature request + metadata (dict, optional): Metadata to associate with the signature request allow_decline (bool, optional); Allows signers to decline to sign a document if set to 1. Defaults to 0. - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -1860,51 +1953,54 @@ def _send_signature_request(self, test_mode=False, client_id=None, files=None, f return response @api_resource(SignatureRequest) - def _send_signature_request_with_template(self, test_mode=False, client_id=None, template_id=None, template_ids=None, title=None, subject=None, message=None, signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): + def _send_signature_request_with_template(self, test_mode=False, client_id=None, + template_id=None, template_ids=None, title=None, subject=None, message=None, + signing_redirect_url=None, signers=None, ccs=None, custom_fields=None, + metadata=None, allow_decline=False, files=None, file_urls=None, signing_options=None): ''' To share the same logic between send_signature_request_with_template and send_signature_request_embedded_with_template Args: - test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) + client_id (str): Client id of the app you're using to create this embedded signature request. Visit the embedded page to learn more about this parameter (https://app.hellosign.com/api/embeddedSigningWalkthrough) - template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. + template_id (str): The id of the Template to use when creating the SignatureRequest. Mutually exclusive with template_ids. - template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. + template_ids (list): The ids of the Templates to use when creating the SignatureRequest. Mutually exclusive with template_id. - title (str, optional): The title you want to assign to the SignatureRequest + title (str, optional): The title you want to assign to the SignatureRequest - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - role_name (str): Role the signer is assigned to - name (str): The name of the signer - email_address (str): Email address of the signer - pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page + role_name (str): Role the signer is assigned to + name (str): The name of the signer + email_address (str): Email address of the signer + pin (str, optional): The 4- to 12-character access code that will secure this signer's signature page - ccs (list of dict, optional): The email address of the CC filling the role of RoleName. Required when a CC role exists for the Template. Each dict has the following attributes: + ccs (list of dict, optional): The email address of the CC filling the role of RoleName. Required when a CC role exists for the Template. Each dict has the following attributes: - role_name (str): CC role name - email_address (str): CC email address + role_name (str): CC role name + email_address (str): CC email address custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists in the Template. An item of the list should look like this: `{'name: value'}` - metadata (dict, optional): Metadata to associate with the signature request + metadata (dict, optional): Metadata to associate with the signature request - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - files (list of str): The uploaded file(s) to append to the Signature Request. + files (list of str): The uploaded file(s) to append to the Signature Request. - file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to append to the Signature Request. Use either `files` or `file_urls` - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. Returns: A SignatureRequest object @@ -1968,62 +2064,69 @@ def _send_signature_request_with_template(self, test_mode=False, client_id=None, return response @api_resource(UnclaimedDraft) - def _create_unclaimed_draft(self, test_mode=False, client_id=None, is_for_embedded_signing=False, requester_email_address=None, files=None, file_urls=None, draft_type=None, subject=None, message=None, signers=None, custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, requesting_redirect_url=None, form_fields_per_document=None, metadata=None, use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, skip_me_now=False, allow_reassign=False, allow_decline=False, signing_options=None, allow_ccs=False): + def _create_unclaimed_draft(self, test_mode=False, client_id=None, + is_for_embedded_signing=False, requester_email_address=None, files=None, + file_urls=None, draft_type=None, subject=None, message=None, signers=None, + custom_fields=None, cc_email_addresses=None, signing_redirect_url=None, + requesting_redirect_url=None, form_fields_per_document=None, metadata=None, + use_preexisting_fields=False, use_text_tags=False, hide_text_tags=False, + skip_me_now=False, allow_reassign=False, allow_decline=False, + signing_options=None, allow_ccs=False): ''' Creates a new Draft that can be claimed using the claim URL Args: - test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. + test_mode (bool, optional): Whether this is a test, the signature request created from this draft will not be legally binding if set to True. Defaults to False. - client_id (str): Client id of the app used to create the embedded draft. + client_id (str): Client id of the app used to create the embedded draft. - is_for_embedded_signing (bool): Whether this is for embedded signing on top of being for embedded requesting. + is_for_embedded_signing (bool): Whether this is for embedded signing on top of being for embedded requesting. - requester_email_address (str): Email address of the requester when creating a draft for embedded requesting. + requester_email_address (str): Email address of the requester when creating a draft for embedded requesting. - files (list of str): The uploaded file(s) to send for signature. + files (list of str): The uploaded file(s) to send for signature. - file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` + file_urls (list of str): URLs of the file for HelloSign to download to send for signature. Use either `files` or `file_urls` - draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. + draft_type (str): The type of unclaimed draft to create. Use "send_document" to create a claimable file, and "request_signature" for a claimable signature request. If the type is "request_signature" then signers name and email_address are not optional. - subject (str, optional): The subject in the email that will be sent to the signers + subject (str, optional): The subject in the email that will be sent to the signers - message (str, optional): The custom message in the email that will be sent to the signers + message (str, optional): The custom message in the email that will be sent to the signers - signers (list of dict): A list of signers, which each has the following attributes: + signers (list of dict): A list of signers, which each has the following attributes: - name (str): The name of the signer - email_address (str): Email address of the signer - order (str, optional): The order the signer is required to sign in + name (str): The name of the signer + email_address (str): Email address of the signer + order (str, optional): The order the signer is required to sign in - custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags or form_fields_per_document. An item of the list should look like this: `{'name: value'}` + custom_fields (list of dict, optional): A list of custom fields. Required when a CustomField exists using text tags or form_fields_per_document. An item of the list should look like this: `{'name: value'}` - cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd + cc_email_addresses (list of str, optional): A list of email addresses that should be CC'd - signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. + signing_redirect_url (str, optional): The URL you want the signer redirected to after they successfully sign. - requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. + requesting_redirect_url (str, optional): The URL you want the signer to be redirected to after the request has been sent. - form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest). + form_fields_per_document (str): The fields that should appear on the document, expressed as a serialized JSON data structure which is a list of lists of the form fields. Please refer to the API reference of HelloSign for more details (https://www.hellosign.com/api/reference#SignatureRequest). - metadata (dict, optional): Metadata to associate with the draft + metadata (dict, optional): Metadata to associate with the draft - use_preexisting_fields (bool): Whether to use preexisting PDF fields + use_preexisting_fields (bool): Whether to use preexisting PDF fields - use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields + use_text_tags (bool, optional): Use text tags in the provided file(s) to create form fields - hide_text_tags (bool, optional): Hide text tag areas + hide_text_tags (bool, optional): Hide text tag areas - skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. + skip_me_now (bool, optional): Disables the "Me (Now)" option for the document's preparer. Defaults to 0. - allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. + allow_reassign (bool, optional): Allows signers to reassign their signature requests to other signers if set to True. Defaults to False. - allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. + allow_decline (bool, optional): Allows signers to decline to sign a document if set to 1. Defaults to 0. - signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. + signing_options (dict, optional): Allows the requester to specify the types allowed for creating a signature. Defaults to account settings. - allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. + allow_ccs (bool, optional): Specifies whether the user is allowed to provide email addresses to CC when sending the request. Defaults to False. Returns: An UnclaimedDraft object @@ -2105,11 +2208,11 @@ def _add_remove_user_template(self, url, template_id, account_id=None, email_add Args: - template_id (str): The id of the template + template_id (str): The id of the template - account_id (str): ID of the account to add/remove access to/from + account_id (str): ID of the account to add/remove access to/from - email_address (str): The email_address of the account to add/remove access to/from + email_address (str): The email_address of the account to add/remove access to/from Raises: HSException: If no email address or account_id specified @@ -2146,9 +2249,9 @@ def _add_remove_team_member(self, url, email_address=None, account_id=None): Args: - email_address (str): Email address of the Account to add/remove + email_address (str): Email address of the Account to add/remove - account_id (str): ID of the Account to add/remove + account_id (str): ID of the Account to add/remove Returns: A Team object @@ -2174,7 +2277,10 @@ def _add_remove_team_member(self, url, email_address=None, account_id=None): return response @api_resource(Template) - def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, files=None, file_urls=None, title=None, subject=None, message=None, cc_roles=None, merge_fields=None, skip_me_now=False, use_preexisting_fields=False, metadata=None, allow_reassign=False, allow_ccs=False): + def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=False, + files=None, file_urls=None, title=None, subject=None, message=None, + cc_roles=None, merge_fields=None, skip_me_now=False, + use_preexisting_fields=False, metadata=None, allow_reassign=False, allow_ccs=False): ''' Helper method for creating embedded template drafts. See public function for params. ''' @@ -2227,7 +2333,13 @@ def _create_embedded_template_draft(self, client_id, signer_roles, test_mode=Fal return response @api_resource(UnclaimedDraft) - def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, client_id=None, is_for_embedded_signing=False, template_id=None, template_ids=None, requester_email_address=None, title=None, subject=None, message=None, signers=None, ccs=None, signing_redirect_url=None, requesting_redirect_url=None, metadata=None, custom_fields=None, files=None, file_urls=None, skip_me_now=False, allow_decline=False, allow_reassign=False, signing_options=None): + def _create_embedded_unclaimed_draft_with_template(self, test_mode=False, + client_id=None, is_for_embedded_signing=False, template_id=None, + template_ids=None, requester_email_address=None, title=None, + subject=None, message=None, signers=None, ccs=None, + signing_redirect_url=None, requesting_redirect_url=None, metadata=None, + custom_fields=None, files=None, file_urls=None, skip_me_now=False, + allow_decline=False, allow_reassign=False, signing_options=None): ''' Helper method for creating unclaimed drafts from templates See public function for params. ''' From a41528b606466b68eda4868e21879ced86b97551 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Mon, 25 Nov 2019 10:59:57 -0800 Subject: [PATCH 17/18] Consolidate file response type to one property --- hellosign_sdk/hsclient.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/hellosign_sdk/hsclient.py b/hellosign_sdk/hsclient.py index bc3af9e..67b85b3 100644 --- a/hellosign_sdk/hsclient.py +++ b/hellosign_sdk/hsclient.py @@ -318,7 +318,7 @@ def get_signature_request_list(self, page=1): return request.get(self.SIGNATURE_REQUEST_LIST_URL, parameters=parameters) - def get_signature_request_file(self, signature_request_id, path_or_file=None, file_type=None, filename=None, get_url=False, get_data_uri=False): + def get_signature_request_file(self, signature_request_id, path_or_file=None, file_type=None, filename=None, response_type=None): ''' Download the PDF copy of the current documents Args: @@ -332,9 +332,8 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. - get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. - - get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. + response_type (str): File type of response to return. Either "url" to return a URL link to the file + or "data_uri" to return the file as a base64 encoded string. Only applicable to the "pdf" file_type. Returns: Returns a PDF file, URL link to file, or base64 encoded file @@ -346,9 +345,9 @@ def get_signature_request_file(self, signature_request_id, path_or_file=None, fi url += '?file_type=%s' % file_type return request.get_file(url, path_or_file or filename) - if get_url: + if response_type == 'url': url += '?get_url=1' - elif get_data_uri: + elif response_type == 'data_uri': url += '?get_data_uri=1' return request.get(url) @@ -901,7 +900,7 @@ def delete_template(self, template_id): return response def get_template_files(self, template_id, path_or_file=None, file_type=None, - filename=None, get_url=False, get_data_uri=False): + filename=None, response_type=None): ''' Downloads a copy of a template's original files Args: @@ -915,9 +914,8 @@ def get_template_files(self, template_id, path_or_file=None, file_type=None, file_type (str): Type of file to return. Either "pdf" for a single merged document or "zip" for a collection of individual documents. Defaults to "pdf" if not specified. - get_url (bool, optional): If True, returns a URL link to the file. Defaults to false. - - get_data_uri (bool, optional): If True, returns the file as base64 encoded string. Defaults to False. + response_type (str): File type of response to return. Either "url" to return a URL link to the file + or "data_uri" to return the file as a base64 encoded string. Only applicable to the "pdf" file_type. Returns: Returns a PDF file, URL link to file, or base64 encoded file @@ -929,9 +927,9 @@ def get_template_files(self, template_id, path_or_file=None, file_type=None, url += '?file_type=%s' % file_type return request.get_file(url, path_or_file or filename) - if get_url: + if response_type == 'url': url += '?get_url=1' - elif get_data_uri: + elif response_type == 'data_uri': url += '?get_data_uri=1' return request.get(url) From 79d6eb48aded0af4303eea5c45e0a64f616228a5 Mon Sep 17 00:00:00 2001 From: Jen Young Date: Mon, 25 Nov 2019 13:42:31 -0800 Subject: [PATCH 18/18] Add more detail to delete function --- hellosign_sdk/utils/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hellosign_sdk/utils/request.py b/hellosign_sdk/utils/request.py index d0c63d7..95fc68e 100644 --- a/hellosign_sdk/utils/request.py +++ b/hellosign_sdk/utils/request.py @@ -170,7 +170,7 @@ def post(self, url, data=None, files=None, headers=None, get_json=True): return json_response if get_json is True else response def delete(self, url, headers=None): - ''' Make POST request to a url + ''' Make POST request to a url to delete an API App or Template Args: url (str): URL to send the request to