Skip to content

Commit a3ba77c

Browse files
committed
initial commit
1 parent 9cc6944 commit a3ba77c

27 files changed

Lines changed: 907 additions & 0 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*/.DS_Store
22
.DS_Store
3+
.idea/*
34

45
# App's temp files
56
app/static/files/*

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2018 DocuSign, Inc. (https://www.docusign.com)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: ./procfile.sh

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Multiple DocuSign Signature REST API recipes in Python
2+
3+
Repo: esignature-recipes-python
4+
5+
This is a **beta** release. Comments are welcomed.
6+
7+
This repo contains a Python Flask application that demonstrates several of the
8+
DocuSign Signature REST API recipes:
9+
10+
* Embedded signing. See app/py_001_embedded_signing
11+
* Sending a signature request via email. See app/py_004_email_send
12+
* Sending a signature request using a template. See app/py_002_email_send_template
13+
* Get envelopes’ statuses. See app/py_005_envelope_list_status
14+
* Get an envelope’s status. See app/py_006_envelope_status
15+
* Get an envelope’s recipient statuses. See app/py_007_envelope_recipient_status
16+
* Using a webhook to receive status changes. See app/lib_master_python/ds_webhook.py
17+
* Authenticating with the Signature REST API. See app/lib_master_python/ds_authentication.py
18+
* Embedded tagging and sending of an envelope. See app/py_012_embedded_tagging
19+
20+
## API Logging Feature
21+
The application also enables you to easily view your account’s API logs. It shows all API requests to your
22+
demo account, from this application, and from others including the DocuSign web tool.
23+
24+
## Try it on Heroku
25+
Use the deploy button to immediately try this app on Heroku. You can use Heroku’s free service tier, no credit card is needed.
26+
27+
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
28+
29+
### Integration Key and Secret
30+
**Do not use** the DS_OAUTH_CLIENT_ID or DS_OAUTH_SECRET config variables.
31+
32+
Instead, enter your Integration Key (Client ID) and Secret after you have started the software on Heroku.
33+
34+
Details: the config variables should only be used if the new server's name is already known and has been
35+
registered as a redirect URI with the DocuSign authentication service.
36+
37+
### Build delays
38+
Note: during the Heroku *build* process, the setup.py step for **lxml** takes several minutes since it includes a compilation.
39+
40+
## Run the app locally
41+
42+
1. Install a recent version of Python 2.x, eg 2.7.11 or later.
43+
1. Install pip
44+
1. Clone this repo to your computer
45+
1. `cd` to the repo’s directory
46+
1. `pip install -r requirements.txt` # installs the application’s requirements
47+
1. `python run.py` # starts the application on port 5000
48+
1. Use a browser to load [http://127.0.0.1:5000/](http://127.0.0.1:5000/)
49+
50+
## Have a question? Pull request?
51+
If you have a question about the Signature REST API, please use StackOverflow and tag your question with `docusignapi`
52+
53+
For bug reports and pull requests, please use this repo’s issues page.

app/static/assets/css.css

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
body {
2+
padding-top: 5rem;
3+
}
4+
5+
/* See https://css-tricks.com/hash-tag-links-padding/ */
6+
#index-page h4 {
7+
z-index: -100;
8+
}
9+
#index-page h4::before {
10+
z-index: -100;
11+
display: block;
12+
content: " ";
13+
margin-top: -4rem;
14+
height: 4rem;
15+
visibility: hidden;
16+
pointer-events: none;
17+
}
18+
19+
.jumbotron {
20+
background: #888888;
21+
padding: 3em;
22+
color: white;
23+
margin: 1em auto 1.5em; }
24+
25+
.jumbotron p {
26+
margin-top: 1em;
27+
font-size: 1.45em;
28+
}
29+
30+
hr.styled {
31+
overflow: visible; /* For IE */
32+
padding: 0;
33+
border: none;
34+
border-top: medium double #333;
35+
color: #333;
36+
text-align: center;
37+
}
38+
hr.styled:after {
39+
content: "§";
40+
display: inline-block;
41+
position: relative;
42+
top: -0.7em;
43+
font-size: 1.5em;
44+
padding: 0 0.25em;
45+
background: white;
46+
}
47+
48+
.feedback, .hidden {display: none;}
49+
span.feedback {margin-left:2em;}
50+
51+
form.eg {max-width: 30em;}
52+
form.eg label {font-weight: 550;}
53+
54+
pre.json-display {
55+
background-color: ghostwhite;
56+
border: 1px solid silver;
57+
padding: 10px 20px;
58+
}
59+
.json-key {
60+
color: brown;
61+
}
62+
.json-value {
63+
color: navy;
64+
}
65+
.json-string {
66+
color: olive;
67+
}
68+
69+
70+
71+
72+
/* From http://tobiasahlin.com/spinkit/ */
73+
.spinner {
74+
margin: 100px auto;
75+
width: 150px;
76+
height: 140px;
77+
text-align: center;
78+
font-size: 10px;
79+
}
80+
81+
.spinner > div {
82+
background-color: blueviolet;
83+
height: 100%;
84+
width: 6px;
85+
display: inline-block;
86+
87+
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
88+
animation: sk-stretchdelay 1.2s infinite ease-in-out;
89+
}
90+
91+
.spinner .rect2 {
92+
-webkit-animation-delay: -1.1s;
93+
animation-delay: -1.1s;
94+
}
95+
96+
.spinner .rect3 {
97+
-webkit-animation-delay: -1.0s;
98+
animation-delay: -1.0s;
99+
}
100+
101+
.spinner .rect4 {
102+
-webkit-animation-delay: -0.9s;
103+
animation-delay: -0.9s;
104+
}
105+
106+
.spinner .rect5 {
107+
-webkit-animation-delay: -0.8s;
108+
animation-delay: -0.8s;
109+
}
110+
111+
@-webkit-keyframes sk-stretchdelay {
112+
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
113+
20% { -webkit-transform: scaleY(1.0) }
114+
}
115+
116+
@keyframes sk-stretchdelay {
117+
0%, 40%, 100% {
118+
transform: scaleY(0.4);
119+
-webkit-transform: scaleY(0.4);
120+
} 20% {
121+
transform: scaleY(1.0);
122+
-webkit-transform: scaleY(1.0);
123+
}
124+
}

app/static/assets/eg_03.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
2+
// This JavaScript is entended to work with all supported
3+
// browsers. Some polyfills may be needed.
4+
//
5+
// See https://getbootstrap.com/docs/4.0/getting-started/browsers-devices/
6+
// for the supported browser list
7+
8+
let DS_EG = (function(){
9+
// globals
10+
//
11+
// NotifyJS -- see https://notifyjs.jpillora.com/
12+
const notify_info_t = { className:"info", globalPosition: "top center" }
13+
, notify_warning_t = { className:"warn", globalPosition: "top center" }
14+
;
15+
let library = {};
16+
17+
// See http://jsfiddle.net/unLSJ/
18+
// USAGE: $(el).html(library.json.prettyPrint(json_obj));
19+
// where el is <pre><code> el
20+
// or
21+
// $(el).html(library.json.prettyPrint2(json_obj));
22+
// where el is any el (<pre><code> will be added)
23+
library.json = {
24+
replacer: function(match, pIndent, pKey, pVal, pEnd) {
25+
var key = '<span class=json-key>';
26+
var val = '<span class=json-value>';
27+
var str = '<span class=json-string>';
28+
var r = pIndent || '';
29+
if (pKey)
30+
r = r + key + pKey.replace(/[": ]/g, '') + '</span>: ';
31+
if (pVal)
32+
r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
33+
return r + (pEnd || '');
34+
},
35+
prettyPrint: function(obj) {
36+
var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{]|\[],|\{},|\[]|\{})?$/mg;
37+
return JSON.stringify(obj, null, 3)
38+
.replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
39+
.replace(/</g, '&lt;').replace(/>/g, '&gt;')
40+
.replace(jsonLine, library.json.replacer);
41+
},
42+
prettyPrint2: function(obj) {
43+
var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg
44+
, out = JSON.stringify(obj, null, 3)
45+
.replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
46+
.replace(/</g, '&lt;').replace(/>/g, '&gt;')
47+
.replace(jsonLine, library.json.replacer);
48+
return '<pre><code>' + out + '</code></pre>';
49+
}
50+
};
51+
52+
53+
54+
// Add on_click handlers to elements with data-busy attribute
55+
function augment_busy(){
56+
$('a[data-busy="href"]').click(busy_href);
57+
$('form[data-busy="form"]').submit(busy_form);
58+
$('form[data-busy="form-download"]').submit(busy_form_download);
59+
}
60+
61+
// Process flash messages from the server
62+
function process_server_flash_msgs(){
63+
let flash_msg_raw = $("#server_data").attr("data-server-data")
64+
, flash_msg_json = flash_msg_raw ? JSON.parse(flash_msg_raw) : false
65+
, flash_msg_info = (flash_msg_json && flash_msg_json.flash &&
66+
flash_msg_json.flash.info)
67+
;
68+
_.forEach(flash_msg_info, function (msg){
69+
$.notify(msg, notify_info_t);
70+
})
71+
}
72+
73+
// process json display
74+
function process_json_display() {
75+
let json_raw = $("#server_json_data").attr("data-server-json-data")
76+
, json_raw2 = json_raw ? JSON.parse(json_raw) : false
77+
, json_raw3 = json_raw2 && json_raw2.json
78+
, json = JSON.parse(json_raw3)
79+
;
80+
81+
if (json) {
82+
$('#json-display').html(library.json.prettyPrint(json))
83+
}
84+
}
85+
86+
// Handles clicks for elements with attribute data-busy="href"
87+
// 1. Make global feedback and busy indicators visible
88+
// 2. Change location to the element's href value
89+
let busy_href = function _busy_href(e){
90+
e.preventDefault();
91+
$("#feedback,#busy").show();
92+
$("#content").hide();
93+
const href = $(e.target).attr("href");
94+
window.location = href;
95+
}
96+
97+
let countdownInfo = { // using an object since it's a pointer
98+
countdown: null, // Should countdown continue?
99+
intervalId: null // id of the count down interval
100+
}
101+
// When starting a download request, how long should the spinner display?
102+
, downloadSpinnerMS = 3000;
103+
104+
let busy_form = function _busy_form(e){
105+
e.preventDefault();
106+
$("#feedback,#busy").show();
107+
$("#content").hide();
108+
const form = $(e.target);
109+
form.get(0).submit();
110+
countdownInfo.countdown = true;
111+
doCountdown();
112+
}
113+
114+
let busy_form_download = function _busy_form_download(e){
115+
e.preventDefault();
116+
$("#feedback,#busy").show();
117+
$("#content").hide();
118+
const form = $(e.target);
119+
form.get(0).submit();
120+
countdownInfo.countdown = true;
121+
doCountdown();
122+
let stopCount = info => {
123+
info.countdown = false;
124+
clearInterval(info.intervalId);
125+
$('#feedback h3 span').text("your download will start soon.");
126+
$("#busy").hide();
127+
$("#download-continue").show();
128+
}
129+
setTimeout(stopCount, downloadSpinnerMS, countdownInfo);
130+
}
131+
132+
function doCountdown() {
133+
let value = 200
134+
, timerMS = 300
135+
, el = $('#feedback h3 span')
136+
, show = () => {if (countdownInfo.countdown) {el.text(value)} value -= 1}
137+
;
138+
139+
show();
140+
countdownInfo.intervalId = setInterval( show, timerMS );
141+
}
142+
143+
let start_up = function(){
144+
augment_busy();
145+
process_server_flash_msgs();
146+
process_json_display();
147+
}
148+
149+
function notify_info (msg) {
150+
$.notify(msg, notify_info_t);
151+
}
152+
function notify_warning (msg) {
153+
$.notify(msg, notify_warning_t);
154+
}
155+
156+
////////////////////////////////////////////////////////////////////////////
157+
////////////////////////////////////////////////////////////////////////////
158+
////////////////////////////////////////////////////////////////////////////
159+
160+
// Return the publicly exposed items
161+
return {
162+
start_up: start_up
163+
}
164+
})();
165+
166+
167+
// Main stem
168+
$( document ).ready(function() {
169+
DS_EG.start_up();
170+
});

app/static/assets/favicon.ico

7.23 KB
Binary file not shown.

0 commit comments

Comments
 (0)