| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ba37db7 commit 7add73e
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ | |||
| 13 | 13 | from .admin import views as admin_views | |
| 14 | 14 | from .connect import views as connect_views | |
| 15 | 15 | from .webforms import views as webforms_views | |
| 16 | + from .notary import views as notary_views | ||
| 16 | 17 | from .views import core | |
| 17 | 18 | ||
| 18 | 19 | session_path = "/tmp/python_recipe_sessions" | |
@@ -117,6 +118,8 @@ | |||
| 117 | 118 | ||
| 118 | 119 | app.register_blueprint(webforms_views.weg001) | |
| 119 | 120 | ||
| 121 | + app.register_blueprint(notary_views.neg004) | ||
| 122 | + | ||
| 120 | 123 | if "DYNO" in os.environ: # On Heroku? | |
| 121 | 124 | import logging | |
| 122 | 125 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1 +1 @@ | |||
| 1 | - EXAMPLES_API_TYPE ={'Rooms': False, 'ESignature': True, 'Click': False, 'Monitor': False, 'Admin': False} | ||
| 1 | + EXAMPLES_API_TYPE ={'Rooms': False, 'ESignature': True, 'Click': False, 'Monitor': False, 'Admin': False, 'Notary': False} | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,5 +116,6 @@ | |||
| 116 | 116 | "ROOMS": "Rooms", | |
| 117 | 117 | "ADMIN": "Admin", | |
| 118 | 118 | "CONNECT": "Connect", | |
| 119 | - "WEBFORMS": "WebForms" | ||
| 119 | + "WEBFORMS": "WebForms", | ||
| 120 | + "NOTARY": "Notary" | ||
| 120 | 121 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,6 +42,10 @@ | |||
| 42 | 42 | "signature", "webforms_read", "webforms_instance_read", "webforms_instance_write" | |
| 43 | 43 | ] | |
| 44 | 44 | ||
| 45 | + NOTARY_SCOPES = [ | ||
| 46 | + "signature", "organization_read", "notary_read", "notary_write" | ||
| 47 | + ] | ||
| 48 | + | ||
| 45 | 49 | ||
| 46 | 50 | class DSClient: | |
| 47 | 51 | ds_app = None | |
@@ -71,6 +75,8 @@ def _auth_code_grant(cls, api): | |||
| 71 | 75 | use_scopes.extend(ADMIN_SCOPES) | |
| 72 | 76 | elif api == "WebForms": | |
| 73 | 77 | use_scopes.extend(WEBFORMS_SCOPES) | |
| 78 | + elif api == "Notary": | ||
| 79 | + use_scopes.extend(NOTARY_SCOPES) | ||
| 74 | 80 | else: | |
| 75 | 81 | use_scopes.extend(SCOPES) | |
| 76 | 82 | # remove duplicate scopes | |
@@ -107,6 +113,8 @@ def _pkce_auth(cls, api): | |||
| 107 | 113 | use_scopes.extend(ADMIN_SCOPES) | |
| 108 | 114 | elif api == "WebForms": | |
| 109 | 115 | use_scopes.extend(WEBFORMS_SCOPES) | |
| 116 | + elif api == "Notary": | ||
| 117 | + use_scopes.extend(NOTARY_SCOPES) | ||
| 110 | 118 | else: | |
| 111 | 119 | use_scopes.extend(SCOPES) | |
| 112 | 120 | # remove duplicate scopes | |
@@ -130,6 +138,8 @@ def _jwt_auth(cls, api): | |||
| 130 | 138 | use_scopes.extend(ADMIN_SCOPES) | |
| 131 | 139 | elif api == "WebForms": | |
| 132 | 140 | use_scopes.extend(WEBFORMS_SCOPES) | |
| 141 | + elif api == "Notary": | ||
| 142 | + use_scopes.extend(NOTARY_SCOPES) | ||
| 133 | 143 | else: | |
| 134 | 144 | use_scopes.extend(SCOPES) | |
| 135 | 145 | # remove duplicate scopes | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,184 @@ | |||
| 1 | + import base64 | ||
| 2 | + from os import path | ||
| 3 | + | ||
| 4 | + from docusign_esign import EnvelopesApi, EnvelopeDefinition, Document, Signer, Notary, SignHere, Tabs, Recipients, \ | ||
| 5 | + NotarySeal, NotaryRecipient, RecipientSignatureProvider, RecipientSignatureProviderOptions | ||
| 6 | + | ||
| 7 | + from ...consts import demo_docs_path, pattern | ||
| 8 | + from ...jwt_helpers import create_api_client | ||
| 9 | + | ||
| 10 | + | ||
| 11 | + class Eg004SendWithThirdPartyNotary: | ||
| 12 | + | ||
| 13 | + @classmethod | ||
| 14 | + def worker(cls, args): | ||
| 15 | + """ | ||
| 16 | + 1. Create the envelope request object | ||
| 17 | + 2. Send the envelope | ||
| 18 | + """ | ||
| 19 | + | ||
| 20 | + envelope_args = args["envelope_args"] | ||
| 21 | + # Create the envelope request object | ||
| 22 | + envelope_definition = cls.make_envelope(envelope_args) | ||
| 23 | + #ds-snippet-start:Notary4Step2 | ||
| 24 | + api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"]) | ||
| 25 | + envelopes_api = EnvelopesApi(api_client) | ||
| 26 | + #ds-snippet-end:Notary4Step2 | ||
| 27 | + | ||
| 28 | + #ds-snippet-start:Notary4Step4 | ||
| 29 | + results = envelopes_api.create_envelope(account_id=args["account_id"], envelope_definition=envelope_definition) | ||
| 30 | + #ds-snippet-end:Notary4Step4 | ||
| 31 | + | ||
| 32 | + envelope_id = results.envelope_id | ||
| 33 | + | ||
| 34 | + return {"envelope_id": envelope_id} | ||
| 35 | + | ||
| 36 | + #ds-snippet-start:Notary4Step3 | ||
| 37 | + @classmethod | ||
| 38 | + def make_envelope(cls, args): | ||
| 39 | + """ | ||
| 40 | + Creates envelope | ||
| 41 | + Document 1: An HTML document. | ||
| 42 | + DocuSign will convert all of the documents to the PDF format. | ||
| 43 | + The recipients" field tags are placed using <b>anchor</b> strings. | ||
| 44 | + """ | ||
| 45 | + | ||
| 46 | + # document 1 (html) has sign here anchor tag **signature_1** | ||
| 47 | + # | ||
| 48 | + # The envelope has two recipients. | ||
| 49 | + # recipient 1 - signer | ||
| 50 | + # The envelope will be sent first to the signer. | ||
| 51 | + | ||
| 52 | + # create the envelope definition | ||
| 53 | + env = EnvelopeDefinition( | ||
| 54 | + email_subject="Please sign this document set" | ||
| 55 | + ) | ||
| 56 | + doc1_b64 = base64.b64encode(bytes(cls.create_document1(args), "utf-8")).decode("ascii") | ||
| 57 | + | ||
| 58 | + # Create the document models | ||
| 59 | + document1 = Document( # create the DocuSign document object | ||
| 60 | + document_base64=doc1_b64, | ||
| 61 | + name="Order acknowledgement", # can be different from actual file name | ||
| 62 | + file_extension="html", # many different document types are accepted | ||
| 63 | + document_id="1" # a label used to reference the doc | ||
| 64 | + ) | ||
| 65 | + # The order in the docs array determines the order in the envelope | ||
| 66 | + env.documents = [document1] | ||
| 67 | + | ||
| 68 | + # Create the signer recipient model | ||
| 69 | + signer1 = Signer( | ||
| 70 | + email=args["signer_email"], | ||
| 71 | + name=args["signer_name"], | ||
| 72 | + recipient_id="2", | ||
| 73 | + routing_order="1", | ||
| 74 | + client_user_id="1000", | ||
| 75 | + notary_id="1" | ||
| 76 | + ) | ||
| 77 | + # routingOrder (lower means earlier) determines the order of deliveries | ||
| 78 | + # to the recipients. Parallel routing order is supported by using the | ||
| 79 | + # same integer as the order for two or more recipients. | ||
| 80 | + | ||
| 81 | + # Create signHere fields (also known as tabs) on the documents, | ||
| 82 | + # We"re using anchor (autoPlace) positioning | ||
| 83 | + # | ||
| 84 | + # The DocuSign platform searches throughout your envelope"s | ||
| 85 | + # documents for matching anchor strings. So the | ||
| 86 | + # signHere2 tab will be used in both document 2 and 3 since they | ||
| 87 | + # use the same anchor string for their "signer 1" tabs. | ||
| 88 | + sign_here1 = SignHere( | ||
| 89 | + document_id="1", | ||
| 90 | + x_position="200", | ||
| 91 | + y_position="235", | ||
| 92 | + page_number="1" | ||
| 93 | + ) | ||
| 94 | + | ||
| 95 | + sign_here2 = SignHere( | ||
| 96 | + stamp_type="stamp", | ||
| 97 | + document_id="1", | ||
| 98 | + x_position="200", | ||
| 99 | + y_position="150", | ||
| 100 | + page_number="1" | ||
| 101 | + | ||
| 102 | + ) | ||
| 103 | + | ||
| 104 | + # Add the tabs model (including the sign_here tabs) to the signer | ||
| 105 | + # The Tabs object wants arrays of the different field/tab types | ||
| 106 | + signer1.tabs = Tabs(sign_here_tabs=[sign_here1, sign_here2]) | ||
| 107 | + | ||
| 108 | + notary_seal_tab = NotarySeal( | ||
| 109 | + x_position = "300", | ||
| 110 | + y_position = "235", | ||
| 111 | + document_id = "1", | ||
| 112 | + page_number = "1", | ||
| 113 | + ) | ||
| 114 | + | ||
| 115 | + notary_sign_here = SignHere( | ||
| 116 | + x_position = "300", | ||
| 117 | + y_position = "150", | ||
| 118 | + document_id = "1", | ||
| 119 | + page_number = "1", | ||
| 120 | + ) | ||
| 121 | + | ||
| 122 | + notary_tabs = Tabs( | ||
| 123 | + sign_here_tabs = [notary_sign_here], | ||
| 124 | + notary_seal_tabs = [ notary_seal_tab ], | ||
| 125 | + ) | ||
| 126 | + | ||
| 127 | + recipient_signature_provider = RecipientSignatureProvider( | ||
| 128 | + seal_documents_with_tabs_only = "false", | ||
| 129 | + signature_provider_name = "ds_authority_idv", | ||
| 130 | + signature_provider_options = RecipientSignatureProviderOptions() | ||
| 131 | + ) | ||
| 132 | + | ||
| 133 | + notary_recipient = NotaryRecipient( | ||
| 134 | + name = "Notary", | ||
| 135 | + recipient_id = "1", | ||
| 136 | + routing_order = "1", | ||
| 137 | + tabs = notary_tabs, | ||
| 138 | + notary_type = "remote", | ||
| 139 | + notary_source_type = "thirdparty", | ||
| 140 | + notary_third_party_partner = "onenotary", | ||
| 141 | + recipient_signature_providers = [recipient_signature_provider] | ||
| 142 | + ) | ||
| 143 | + | ||
| 144 | + # Add the recipients to the envelope object | ||
| 145 | + recipients = Recipients(signers=[signer1], notaries= [notary_recipient]) | ||
| 146 | + env.recipients = recipients | ||
| 147 | + | ||
| 148 | + # Request that the envelope be sent by setting |status| to "sent". | ||
| 149 | + # To request that the envelope be created as a draft, set to "created" | ||
| 150 | + env.status = args["status"] | ||
| 151 | + | ||
| 152 | + return env | ||
| 153 | + | ||
| 154 | + @classmethod | ||
| 155 | + def create_document1(cls, args): | ||
| 156 | + """ Creates document 1 -- an html document""" | ||
| 157 | + | ||
| 158 | + return f""" | ||
| 159 | + <!DOCTYPE html> | ||
| 160 | + <html> | ||
| 161 | + <head> | ||
| 162 | + <meta charset="UTF-8"> | ||
| 163 | + </head> | ||
| 164 | + <body style="font-family:sans-serif;margin-left:2em;"> | ||
| 165 | + <h1 style="font-family: "Trebuchet MS", Helvetica, sans-serif; | ||
| 166 | + color: darkblue;margin-bottom: 0;">World Wide Corp</h1> | ||
| 167 | + <h2 style="font-family: "Trebuchet MS", Helvetica, sans-serif; | ||
| 168 | + margin-top: 0px;margin-bottom: 3.5em;font-size: 1em; | ||
| 169 | + color: darkblue;">Order Processing Division</h2> | ||
| 170 | + <h4>Ordered by {args["signer_name"]}</h4> | ||
| 171 | + <p style="margin-top:0em; margin-bottom:0em;">Email: {args["signer_email"]}</p> | ||
| 172 | + <p style="margin-top:3em;"> | ||
| 173 | + Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. | ||
| 174 | + Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. | ||
| 175 | + Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. | ||
| 176 | + Donut jujubes oat cake jelly-o. | ||
| 177 | + Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake. | ||
| 178 | + </p> | ||
| 179 | + <!-- Note the anchor tag for the signature field is in white. --> | ||
| 180 | + <h3 style="margin-top:3em;">Agreed: <span style="color:white;">**signature_1**/</span></h3> | ||
| 181 | + </body> | ||
| 182 | + </html> | ||
| 183 | + """ | ||
| 184 | + #ds-snippet-end:Notary4Step3 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + from .eg004_send_with_third_party_notary import neg004 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,86 @@ | |||
| 1 | + """ Example 004: Send envelope with third party Notary """ | ||
| 2 | + | ||
| 3 | + from os import path | ||
| 4 | + | ||
| 5 | + from docusign_esign.client.api_exception import ApiException | ||
| 6 | + from flask import render_template, session, Blueprint, request | ||
| 7 | + | ||
| 8 | + from ..examples.eg004_send_with_third_party_notary import Eg004SendWithThirdPartyNotary | ||
| 9 | + from ...docusign import authenticate, ensure_manifest, get_example_by_number | ||
| 10 | + from ...ds_config import DS_CONFIG | ||
| 11 | + from ...error_handlers import process_error | ||
| 12 | + from ...consts import pattern, API_TYPE | ||
| 13 | + | ||
| 14 | + example_number = 4 | ||
| 15 | + api = API_TYPE["NOTARY"] | ||
| 16 | + eg = f"neg00{example_number}" # reference (and url) for this example | ||
| 17 | + neg004 = Blueprint(eg, __name__) | ||
| 18 | + | ||
| 19 | + def get_args(): | ||
| 20 | + """Get request and session arguments""" | ||
| 21 | + | ||
| 22 | + # More data validation would be a good idea here | ||
| 23 | + # Strip anything other than characters listed | ||
| 24 | + signer_email = pattern.sub("", request.form.get("signer_email")) | ||
| 25 | + signer_name = pattern.sub("", request.form.get("signer_name")) | ||
| 26 | + | ||
| 27 | + envelope_args = { | ||
| 28 | + "signer_email": signer_email, | ||
| 29 | + "signer_name": signer_name, | ||
| 30 | + "status": "sent", | ||
| 31 | + } | ||
| 32 | + args = { | ||
| 33 | + "account_id": session["ds_account_id"], | ||
| 34 | + "base_path": session["ds_base_path"], | ||
| 35 | + "access_token": session["ds_access_token"], | ||
| 36 | + "envelope_args": envelope_args | ||
| 37 | + } | ||
| 38 | + return args | ||
| 39 | + | ||
| 40 | + @neg004.route(f"/{eg}", methods=["POST"]) | ||
| 41 | + @authenticate(eg=eg, api=api) | ||
| 42 | + @ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"]) | ||
| 43 | + def sign_by_email(): | ||
| 44 | + """ | ||
| 45 | + 1. Get required arguments | ||
| 46 | + 2. Call the worker method | ||
| 47 | + 3. Render success response with envelopeId | ||
| 48 | + """ | ||
| 49 | + | ||
| 50 | + # 1. Get required arguments | ||
| 51 | + #args = Eg002SigningViaEmailController.get_args() | ||
| 52 | + args = get_args() | ||
| 53 | + try: | ||
| 54 | + # 1. Call the worker method | ||
| 55 | + results = Eg004SendWithThirdPartyNotary.worker(args) | ||
| 56 | + except ApiException as err: | ||
| 57 | + return process_error(err) | ||
| 58 | + | ||
| 59 | + session["envelope_id"] = results["envelope_id"] # Save for use by other examples which need an envelopeId | ||
| 60 | + | ||
| 61 | + # 2. Render success response with envelopeId | ||
| 62 | + example = get_example_by_number(session["manifest"], example_number, api) | ||
| 63 | + return render_template( | ||
| 64 | + "example_done.html", | ||
| 65 | + title=example["ExampleName"], | ||
| 66 | + message=example["ResultsPageText"].format(results['envelope_id']) | ||
| 67 | + ) | ||
| 68 | + | ||
| 69 | + @neg004.route(f"/{eg}", methods=["GET"]) | ||
| 70 | + @ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"]) | ||
| 71 | + @authenticate(eg=eg, api=api) | ||
| 72 | + def get_view(): | ||
| 73 | + """responds with the form for the example""" | ||
| 74 | + example = get_example_by_number(session["manifest"], example_number, api) | ||
| 75 | + | ||
| 76 | + return render_template( | ||
| 77 | + "notary/eg004_send_with_third_party_notary.html", | ||
| 78 | + title=example["ExampleName"], | ||
| 79 | + example=example, | ||
| 80 | + source_file="eg004_send_with_third_party_notary.py", | ||
| 81 | + source_url=DS_CONFIG["github_example_url"] + "eg004_send_with_third_party_notary.py", | ||
| 82 | + documentation=DS_CONFIG["documentation"] + eg, | ||
| 83 | + show_doc=DS_CONFIG["documentation"], | ||
| 84 | + signer_name=DS_CONFIG["signer_name"], | ||
| 85 | + signer_email=DS_CONFIG["signer_email"] | ||
| 86 | + ) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,7 +6,8 @@ const DS_SEARCH = (function () { | |||
| 6 | 6 | ROOMS: "rooms", | |
| 7 | 7 | ADMIN: "admin", | |
| 8 | 8 | CONNECT: "connect", | |
| 9 | - WEBFORMS: "webforms" | ||
| 9 | + WEBFORMS: "webforms", | ||
| 10 | + NOTARY: "notary" | ||
| 10 | 11 | } | |
| 11 | 12 | ||
| 12 | 13 | const processJSONData = function () { | |
@@ -145,6 +146,8 @@ const DS_SEARCH = (function () { | |||
| 145 | 146 | return "cneg"; | |
| 146 | 147 | case API_TYPES.WEBFORMS: | |
| 147 | 148 | return "weg"; | |
| 149 | + case API_TYPES.NOTARY: | ||
| 150 | + return "neg"; | ||
| 148 | 151 | } | |
| 149 | 152 | } | |
| 150 | 153 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -45,7 +45,7 @@ <h2>{{ group["Name"] }}</h2> | |||
| 45 | 45 | {% for example in group["Examples"] -%} | |
| 46 | 46 | {% if not example["SkipForLanguages"] or "python" not in example["SkipForLanguages"] %} | |
| 47 | 47 | {% if example.CFREnabled == "AllAccounts" or example.CFREnabled == "CFROnly" %} | |
| 48 | - {% set api_prefix = "a" if api["Name"] == "Admin" else "c" if api["Name"] == "Click" else "r" if api["Name"] == "Rooms" else "m" if api["Name"] == "Monitor" else "w" if api["Name"] == "WebForms" else "" %} | ||
| 48 | + {% set api_prefix = "a" if api["Name"] == "Admin" else "c" if api["Name"] == "Click" else "r" if api["Name"] == "Rooms" else "m" if api["Name"] == "Monitor" else "w" if api["Name"] == "WebForms" else "n" if api["Name"] == "Notary" else "" %} | ||
| 49 | 49 | <h4 | |
| 50 | 50 | id="{{ api_prefix + 'example' + '0' * (3 - example['ExampleNumber'] | string() | length ) + example['ExampleNumber'] | string() }}" | |
| 51 | 51 | > | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,7 +43,7 @@ <h2>{{ group["Name"] }}</h2> | |||
| 43 | 43 | {% for example in group["Examples"] -%} | |
| 44 | 44 | {% if not example["SkipForLanguages"] or "python" not in example["SkipForLanguages"] %} | |
| 45 | 45 | {% if example.CFREnabled != "CFROnly" %} | |
| 46 | - {% set api_prefix = "a" if api["Name"] == "Admin" else "c" if api["Name"] == "Click" else "r" if api["Name"] == "Rooms" else "m" if api["Name"] == "Monitor" else "cn" if api["Name"] == "Connect" else "ms" if api["Name"] == "WebForms" else "" %} | ||
| 46 | + {% set api_prefix = "a" if api["Name"] == "Admin" else "c" if api["Name"] == "Click" else "r" if api["Name"] == "Rooms" else "m" if api["Name"] == "Monitor" else "cn" if api["Name"] == "Connect" else "ms" if api["Name"] == "WebForms" else "n" if api["Name"] == "Notary" else "" %} | ||
| 47 | 47 | <h4 | |
| 48 | 48 | id="{{ api_prefix + 'example' + '0' * (3 - example['ExampleNumber'] | string() | length ) + example['ExampleNumber'] | string() }}" | |
| 49 | 49 | > | |
| Back | FazBrowse Home | New Git URL |
0 commit comments