-->

DocuSign Python SDK - API Exception 400 - 'Bad

2019-08-29 13:20发布

问题:

I have made a couple of posts regarding the issue of integrating Docusign's Python SDK with my web app for my company. Essentially what I'm doing, is I'm having the user fill out a form, which, after the user clicks the submit button, weasyprint generates a pdf from an html template I've created, with the customer's information placed in the correct spots. I then want DocuSign to send an email to the user with the newly generated PDF, and have them sign the form, and have it sent to an email account for my company. Here is the way I'm trying to integrate Python's SDK into my Django web app:

def Signview(request):
    loa = LOA.objects.filter().order_by('-id')[0] # This is pulling the information about the user from a model in my database
    username = "myusername@docusign.com"
    integrator_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    base_url = "https://demo.docusign.net/restapi"
    oauth_base_url = "account-d.docusign.com"
    redirect_uri = "http://localhost:8000/path/to/redirecturi"
    private_key_filename = "path/to/pKey.txt"
    user_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_user_id = 'Your System ID' # This is the actual string I am using for this variable

    # Add a recipient to sign the document
    signer = docusign.Signer()
    signer.email = loa.email
    signer.name = loa.ainame
    signer.recipient_id = '1'
    signer.client_user_id = client_user_id

    sign_here = docusign.SignHere()
    sign_here.document_id = '1'
    sign_here.recipient_id = '1'
    sign_here.anchor_case_sensitive = 'true'
    sign_here.anchor_horizontal_alignment = 'left'
    sign_here.anchor_ignore_if_not_present = 'false'
    sign_here.anchor_match_whole_word = 'true'

    sign_here.anchor_string = 'Sign Here'
    sign_here.anchor_units = 'cms'
    sign_here.anchor_x_offset = '0'
    sign_here.anchor_y_offset = '0'
    sign_here.tab_label = 'sign_here'
    tabs = docusign.Tabs()
    tabs.sign_here_tabs = [sign_here]

    # Create a signers list, attach tabs to signer, append signer to signers.
    # Attach signers to recipients objects
    signers = []
    tabs = tabs
    signer.tabs = tabs
    signers.append(signer)
    recipients = docusign.Recipients()
    recipients.signers = signers

    # Create an envelope to be signed
    envelope_definition = docusign.EnvelopeDefinition()
    envelope_definition.email_subject = 'My email subject'
    envelope_definition.email_blurb = 'My email blurb'

    # Add a document to the envelope_definition
    pdfpath = "path/to/mypdf.pdf"
    with open(pdfpath, 'rb') as signfile:
        file_data = signfile.read()
        doc = docusign.Document()
        base64_doc = base64.b64encode(file_data).decode('utf-8')
        doc.document_base64 = base64_doc
        doc.name = "MyDoc_Signed.pdf"
        doc.document_id = '1'
        envelope_definition.documents = [doc]
        signfile.close()
    envelope_definition.recipients = recipients
    envelope_definition.status = 'sent'

    api_client = docusign.ApiClient(base_url)

    oauth_login_url = api_client.get_jwt_uri(integrator_key, redirect_uri, oauth_base_url)
    print("oauth_login_url:", oauth_login_url)
    print("oauth_base_url:", oauth_base_url)

    api_client.configure_jwt_authorization_flow(private_key_filename, oauth_base_url, integrator_key, user_id, 3600)
    docusign.configuration.api_client = api_client

    auth_api = AuthenticationApi()
    envelopes_api = EnvelopesApi()

    try: #login here via code
        login_info = auth_api.login()
        login_accounts = login_info.login_accoutns
        base_url, _ = login_accounts[0].base_url.split('/v2')
        api_client.host = base_url
        docusign.configuration.api_client = api_client

        envelope_summary = envelopes_api.create_envelope(login_accounts[0].account_id, envelope_definition = envelope_definition)

        print(envelope_summary)
    except ApiException as e:
        raise Exception("Exception when calling DocuSign API: %s" % e)
    except Exception as e:
        print(e)
    return HttpResponse({'sent'})

However, this is the error that I receive when I run this code:

Environment:


Request Method: GET
Request URL: http://localhost:8000/createquote/genloa/sign/

Django Version: 2.0.6
Python Version: 3.7.0
Installed Applications:
['createquote',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\wkstat\Desktop\Development\LNQuoteTool\createquote\views.py" in Signview
  142.  api_client.configure_jwt_authorization_flow(private_key_filename, oauth_base_url, integrator_key, user_id, 3600)

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\docusign_esign\api_client.py" in configure_jwt_authorization_flow
  126.                                 post_params=self.sanitize_for_serialization({"assertion": assertion, "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"}))

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\docusign_esign\api_client.py" in request
  430.                                          body=body)

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\docusign_esign\rest.py" in POST
  244.                             body=body)

File "C:\users\wkstat\appdata\local\programs\python\python37\lib\site-packages\docusign_esign\rest.py" in request
  200.             raise ApiException(http_resp=r)

Exception Type: ApiException at /createquote/genloa/sign/
Exception Value: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Cache-Control': 'private', 'Content-Type': 'text/html', 'X-AspNetMvc-Version': '5.2', 'X-DocuSign-TraceToken': 'b27fdab1-e157-4f13-968c-f5606e0e90b1', 'X-DocuSign-Node': 'DA2DFE5', 'Date': 'Tue, 31 Jul 2018 22:41:16 GMT', 'Content-Length': '11'})
HTTP response body: b'Bad Request'

I have entered the Redirect URI with my integrator key on my DocuSign admin page, I have gone to the link and hit "accept" so that consent would be given to start signing, however, this is the issue I'm encountering, and I'm not sure what is wrong. I have been told by a fellow user on here, whom supplied me with this solution, that the code should work, and that it is likely something on the DocuSign admin side that I have not done. Is there anything blatantly wrong with this code here?

Thanks in advance!

回答1:

It's hard to define what's wrong in admin panel. You can try complete this steps to define what's wrong:

  1. Check that redirect uri in admin and in code are same;
  2. Check that user_id same as your API username in admin panel(it was issue for me);
  3. Be sure that you private key in path/to/pKey.txt same as you got in admin panel.

I hope it will be helpfull.