Skip to content

Commit 732696d

Browse files
committed
Adding Web Forms example
1 parent 9e4756f commit 732696d

File tree

12 files changed

+328
-22
lines changed

12 files changed

+328
-22
lines changed

app/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
app.register_blueprint(connect_views.cneg001)
119119

120120
app.register_blueprint(webforms_views.weg001)
121+
app.register_blueprint(webforms_views.weg002)
121122

122123
app.register_blueprint(notary_views.neg004)
123124

app/ds_config_sample.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# ds_config.py
22
#
3-
# DocuSign configuration settings
3+
# Docusign configuration settings
44

55
DS_CONFIG = {
6-
"ds_client_id": "{INTEGRATION_KEY_AUTH_CODE}", # The app's DocuSign integration key
7-
"ds_client_secret": "{SECRET_KEY}", # The app's DocuSign integration key's secret
6+
"ds_client_id": "{INTEGRATION_KEY_AUTH_CODE}", # The app's Docusign integration key
7+
"ds_client_secret": "{SECRET_KEY}", # The app's Docusign integration key's secret
88
"organization_id": "{ORGANIZATION_ID}", # A GUID value that identifies the organization
99
"signer_email": "{SIGNER_EMAIL}",
1010
"signer_name": "{SIGNER_NAME}",
@@ -16,10 +16,10 @@
1616
"rooms_api_client_host": "https://demo.rooms.docusign.com/restapi",
1717
"monitor_api_client_host": "https://lens-d.docusign.net",
1818
"admin_api_client_host": "https://api-d.docusign.net/management",
19-
"webforms_api_client_host": "https://apps-d.docusign.com/api/webforms/v1.1",
19+
"webforms_api_client_host": "https://apps-d.docusign.com/api/webforms",
2020
"allow_silent_authentication": True, # a user can be silently authenticated if they have an
2121
# active login session on another tab of the same browser
22-
"target_account_id": None, # Set if you want a specific DocuSign AccountId,
22+
"target_account_id": None, # Set if you want a specific Docusign AccountId,
2323
# If None, the user's default account will be used.
2424
"demo_doc_path": "demo_documents",
2525
"doc_salary_docx": "World_Wide_Corp_salary.docx",

app/quick_acg/quick_acg_app/templates/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<body>
1717
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
18-
<a class="navbar-brand" href="/">DocuSign Examples</a>
18+
<a class="navbar-brand" href="/">Docusign Examples</a>
1919
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
2020
<span class="navbar-toggler-icon"></span>
2121
</button>

app/static/demo_documents/web-form-config.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

app/templates/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
<body>
1818
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
19-
<a class="navbar-brand" href="/">DocuSign Examples</a>
19+
<a class="navbar-brand" href="/">Docusign Examples</a>
2020
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
2121
<span class="navbar-toggler-icon"></span>
2222
</button>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- extend base layout --> {% extends "base.html" %} {% block content %}
2+
3+
{% include 'example_info.html' %}
4+
5+
<form class="eg" action="" method="post" data-busy="form">
6+
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
7+
{% include 'continue_button.html' %}
8+
</form>
9+
10+
{% endblock %}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!-- extend base layout --> {% extends "base.html" %} {% block content %}
2+
3+
<h4>{{ title }}</h4>
4+
<p>{{ description | safe }}</p>
5+
6+
<form class="eg" action="" method="post" data-busy="form">
7+
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
8+
{% include 'continue_button.html' %}
9+
</form>
10+
11+
{% endblock %}

app/webforms/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .views import weg001
2+
from .views import weg002
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import base64
2+
3+
from docusign_webforms import ApiClient, FormInstanceManagementApi, FormManagementApi, CreateInstanceRequestBody
4+
from docusign_esign import Document, Signer, SignHere, Tabs, Recipients, TemplatesApi, Checkbox, DateSigned, \
5+
Text, EnvelopeTemplate
6+
7+
from ...docusign import create_api_client
8+
9+
10+
class Eg002CreateRemoteInstance:
11+
@classmethod
12+
def create_web_form_template(cls, args):
13+
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
14+
templates_api = TemplatesApi(api_client)
15+
16+
web_forms_templates = templates_api.list_templates(
17+
account_id=args["account_id"],
18+
search_text=args["template_name"]
19+
)
20+
21+
if int(web_forms_templates.result_set_size) > 0:
22+
template_id = web_forms_templates.envelope_templates[0].template_id
23+
else:
24+
template_req_object = cls.make_web_forms_template(args)
25+
template = templates_api.create_template(
26+
account_id=args["account_id"],
27+
envelope_template=template_req_object
28+
)
29+
template_id = template.template_id
30+
31+
return template_id
32+
33+
@classmethod
34+
def create_web_form_instance(cls, form_id, args):
35+
#ds-snippet-start:WebForms2Step2
36+
api_client = ApiClient()
37+
api_client.host = args["base_path"]
38+
api_client.set_default_header(header_name="Authorization", header_value=f"Bearer {args['access_token']}")
39+
#ds-snippet-end:WebForms2Step2
40+
41+
#ds-snippet-start:WebForms2Step4
42+
web_form_values = {
43+
"PhoneNumber": "555-555-5555",
44+
"Yes": ["Yes"],
45+
"Company": "Tally",
46+
"JobTitle": "Programmer Writer"
47+
}
48+
recipient = {
49+
"roleName": "signer",
50+
"name": args["signer_name"],
51+
"email": args["signer_email"]
52+
}
53+
web_form_req_object = {
54+
"formValues": web_form_values,
55+
"recipients": [recipient],
56+
"sendOption": "now"
57+
}
58+
#ds-snippet-end:WebForms2Step4
59+
60+
#ds-snippet-start:WebForms2Step5
61+
webforms_api = FormInstanceManagementApi(api_client)
62+
web_form = webforms_api.create_instance(args["account_id"], form_id, web_form_req_object)
63+
#ds-snippet-end:WebForms2Step5
64+
65+
return web_form
66+
67+
@classmethod
68+
def list_web_forms(cls, args):
69+
api_client = ApiClient()
70+
api_client.host = args["base_path"]
71+
api_client.set_default_header(header_name="Authorization", header_value=f"Bearer {args['access_token']}")
72+
73+
#ds-snippet-start:WebForms2Step3
74+
webforms_api = FormManagementApi(api_client)
75+
web_forms = webforms_api.list_forms(args["account_id"], search=args["form_name"])
76+
#ds-snippet-end:WebForms2Step3
77+
78+
return web_forms
79+
80+
@classmethod
81+
def make_web_forms_template(cls, args):
82+
with open(args["pdf_file"], "rb") as file:
83+
content_bytes = file.read()
84+
base64_file_content = base64.b64encode(content_bytes).decode("ascii")
85+
86+
# Create the document model
87+
document = Document( # create the DocuSign document object
88+
document_base64=base64_file_content,
89+
name="World_Wide_Web_Form", # can be different from actual file name
90+
file_extension="pdf", # many different document types are accepted
91+
document_id=1 # a label used to reference the doc
92+
)
93+
94+
# Create the signer recipient model
95+
signer = Signer(role_name="signer", recipient_id="1", routing_order="1")
96+
# Create fields using absolute positioning
97+
# Create a sign_here tab (field on the document)
98+
sign_here = SignHere(
99+
document_id="1",
100+
tab_label="Signature",
101+
anchor_string="/SignHere/",
102+
anchor_units="pixels",
103+
anchor_x_offset="0",
104+
anchor_y_offset="0"
105+
)
106+
check = Checkbox(
107+
document_id="1",
108+
tab_label="Yes",
109+
anchor_string="/SMS/",
110+
anchor_units="pixels",
111+
anchor_x_offset="0",
112+
anchor_y_offset="0"
113+
)
114+
text1 = Text(
115+
document_id="1",
116+
tab_label="FullName",
117+
anchor_string="/FullName/",
118+
anchor_units="pixels",
119+
anchor_x_offset="0",
120+
anchor_y_offset="0"
121+
)
122+
text2 = Text(
123+
document_id="1",
124+
tab_label="PhoneNumber",
125+
anchor_string="/PhoneNumber/",
126+
anchor_units="pixels",
127+
anchor_x_offset="0",
128+
anchor_y_offset="0"
129+
)
130+
text3 = Text(
131+
document_id="1",
132+
tab_label="Company",
133+
anchor_string="/Company/",
134+
anchor_units="pixels",
135+
anchor_x_offset="0",
136+
anchor_y_offset="0"
137+
)
138+
text4 = Text(
139+
document_id="1",
140+
tab_label="JobTitle",
141+
anchor_string="/JobTitle/",
142+
anchor_units="pixels",
143+
anchor_x_offset="0",
144+
anchor_y_offset="0"
145+
)
146+
date_signed = DateSigned(
147+
document_id="1",
148+
tab_label="DateSigned",
149+
anchor_string="/Date/",
150+
anchor_units="pixels",
151+
anchor_x_offset="0",
152+
anchor_y_offset="0"
153+
)
154+
# Add the tabs model to the signer
155+
# The Tabs object wants arrays of the different field/tab types
156+
signer.tabs = Tabs(
157+
sign_here_tabs=[sign_here],
158+
checkbox_tabs=[check],
159+
text_tabs=[text1, text2, text3, text4],
160+
date_signed=[date_signed]
161+
)
162+
163+
# Top object:
164+
template_request = EnvelopeTemplate(
165+
documents=[document], email_subject="Please sign this document",
166+
recipients=Recipients(signers=[signer]),
167+
description="Example template created via the API",
168+
name=args["template_name"],
169+
shared="false",
170+
status="created"
171+
)
172+
173+
return template_request

app/webforms/views/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .eg001_create_instance import weg001
2+
from .eg002_create_remote_instance import weg002

0 commit comments

Comments
 (0)