Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add multipart support to the CreateEtchPacket mutation#41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
aalmazan merged 13 commits intomasterfrommultipart-support
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from10 commits
Commits
Show all changes
13 commits
Select commitHold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletionexamples/create_etch_existing_cast.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
# pylint: disable=duplicate-code

import os

from python_anvil.api import Anvil
from python_anvil.api_resources.mutations.create_etch_packet import CreateEtchPacket
from python_anvil.api_resources.payload import EtchCastRef, EtchSigner, SignerField


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
6 changes: 5 additions & 1 deletionexamples/create_etch_markdown.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
# pylint: disable=duplicate-code

import os

from python_anvil.api import Anvil
from python_anvil.api_resources.mutations.create_etch_packet import CreateEtchPacket
from python_anvil.api_resources.payload import (
Expand All@@ -11,7 +13,9 @@
)


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
6 changes: 5 additions & 1 deletionexamples/create_etch_markup.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
# pylint: disable=duplicate-code

import os

from python_anvil.api import Anvil
from python_anvil.api_resources.mutations.create_etch_packet import CreateEtchPacket
from python_anvil.api_resources.payload import (
Expand All@@ -10,7 +12,9 @@
)


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
5 changes: 4 additions & 1 deletionexamples/create_etch_upload_file.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
# pylint: disable=duplicate-code

import base64
import os

from python_anvil.api import Anvil
from python_anvil.api_resources.mutations.create_etch_packet import CreateEtchPacket
Expand All@@ -13,7 +14,9 @@
)


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
148 changes: 148 additions & 0 deletionsexamples/create_etch_upload_file_multipart.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
# pylint: disable=duplicate-code
import os

from python_anvil.api import Anvil
from python_anvil.api_resources.mutations.create_etch_packet import CreateEtchPacket
from python_anvil.api_resources.payload import (
DocumentUpload,
EtchSigner,
SignatureField,
SignerField,
)


API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
anvil = Anvil(api_key=API_KEY)

# Create an instance of the builder
packet = CreateEtchPacket(
name="Etch packet with existing template multipart",
#
# Optional changes to email subject and body content
signature_email_subject="Please sign these forms",
signature_email_body="This form requires information from your driver's "
"license. Please have that available.",
#
# URL where Anvil will send POST requests when server events happen.
# Take a look at https://www.useanvil.com/docs/api/e-signatures#webhook-notifications
# for other details on how to configure webhooks on your account.
# You can also use sites like webhook.site, requestbin.com or ngrok to
# test webhooks.
# webhook_url="https://my.webhook.example.com/etch-events/",
#
# Email overrides for the "reply-to" email header for signer emails.
# If used, both `reply_to_email` and `reply_to_name` are required.
# By default, this will point to your organization support email.
# reply_to_email="my-org-email@example.com",
# reply_to_name="My Name",
#
# Merge all PDFs into one. Use this if you have many PDF templates
# and/or files, but want the final downloaded package to be only
# 1 PDF file.
# merge_pdfs=True,
)

# Get your file(s) ready to sign.
# For this example, the PDF hasn't been uploaded to Anvil yet.
# In the `create_etch_upload_file.py` example, we are base64 encoding our
# file(s) before sending. In this case, we will be providing a file's path
# or file descriptor (from an `open()` call)
filename = "my_local_file.pdf"
file_dir = os.path.dirname(os.path.realpath(__file__))
file_path = os.path.join(file_dir, filename)

# You can check manually if your file exists, however, the validator being
# used in the `GraphqlUpload` below will also check if the file exists.
#
# if not os.path.exists(file_path):
# raise FileNotFoundError('File does not exist. Please check `file_path` '
# 'and ensure it points to an existing file.')

# Upload the file and define signer field locations.
file1 = DocumentUpload(
id="myNewFile",
title="Please sign this important form",
# You can send a callable that returns a file handle and the filename
# you want to use in the Anvil app.
# (IMPORTANT: The data must be read in as _bytes_, not text.)
file=lambda: (
open(file_path, "rb"), # pylint: disable=consider-using-with
filename,
),
# or just the valid path itself
# file=file_path,
fields=[
SignatureField(
id="sign1",
type="signature",
page_num=0,
# The position and size of the field. The coordinates provided here
# (x=100, y=100) is the top-left of the rectangle.
rect=dict(x=183, y=100, width=250, height=50),
)
],
)

# Gather your signer data
signer1 = EtchSigner(
name="Jackie",
email="jackie@example.com",
# Fields where the signer needs to sign.
# Check your cast fields via the CLI (`anvil cast [cast_eid]`) or the
# PDF Templates section on the Anvil app.
# This basically says: "In the 'myNewFile' file (defined in
# `file1` above), assign the signature field with cast id of
# 'sign1' to this signer." You can add multiple signer fields here.
fields=[
SignerField(
# this is the `id` in the `DocumentUpload` object above
file_id="myNewFile",
# This is the signing field id in the `SignatureField` above
field_id="sign1",
)
],
signer_type="embedded",
#
# You can also change how signatures will be collected.
# "draw" will allow the signer to draw their signature
# "text" will insert a text version of the signer's name into the
# signature field.
# signature_mode="draw",
#
# Whether to the signer is required to click each signature
# field manually. If `False`, the PDF will be signed once the signer
# accepts the PDF without making the user go through the PDF.
# accept_each_field=False,
#
# URL of where the signer will be redirected after signing.
# The URL will also have certain URL params added on, so the page
# can be customized based on the signing action.
# redirect_url="https://www.google.com",
)

# Add your signer.
packet.add_signer(signer1)

# Add files to your payload
packet.add_file(file1)

# If needed, you can also override or add additional payload fields this way.
# This is useful if the Anvil API has new features, but `python-anvil` has not
# yet been updated to support it.
# payload = packet.create_payload()
# payload.aNewFeature = True

# Create your packet
# If overriding/adding new fields, use the modified payload from
# `packet.create_payload()`
res = anvil.create_etch_packet(payload=packet, include_headers=True)
print(res)


if __name__ == '__main__':
main()
5 changes: 4 additions & 1 deletionexamples/create_workflow_submission.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
import os
from datetime import datetime

from python_anvil.api import Anvil
from python_anvil.api_resources.payload import ForgeSubmitPayload


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
6 changes: 5 additions & 1 deletionexamples/fill_pdf.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
import os

from python_anvil.api import Anvil


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
6 changes: 5 additions & 1 deletionexamples/generate_pdf.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
import os

from python_anvil.api import Anvil
from python_anvil.api_resources.payload import GeneratePDFPayload


API_KEY = 'my-api-key'
API_KEY = os.environ.get("ANVIL_API_KEY")
# or set your own key here
# API_KEY = 'my-api-key'


def main():
Expand Down
29 changes: 24 additions & 5 deletionspython_anvil/api.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,6 +10,7 @@
)
from .api_resources.requests import GraphqlRequest, PlainRequest, RestRequest
from .http import HTTPClient
from .multipart_helpers import get_multipart_payload


logger = getLogger(__name__)
Expand DownExpand Up@@ -57,6 +58,24 @@ def mutate(self, query: BaseQuery, variables: dict, **kwargs):
gql = GraphqlRequest(client=self.client)
return gql.post(query.get_mutation(), variables, **kwargs)

def mutate_multipart(self, files: Dict, **kwargs):
"""
Multipart version of `mutate`.

This will send a mutation based on the multipart spec defined here:
https://github.com/jaydenseric/graphql-multipart-request-spec

Note that `variables` and `query` have been removed and replaced with
`files`. The entire GraphQL payload should already be prepared as a
`dict` beforehand.

:param files:
:param kwargs:
:return:
"""
gql = GraphqlRequest(client=self.client)
return gql.post_multipart(files=files, **kwargs)

def request_rest(self, options: Optional[dict] = None):
api = RestRequest(self.client, options=options)
return api
Expand DownExpand Up@@ -291,11 +310,11 @@ def create_etch_packet(
raise ValueError(
"`payload` must be a valid CreateEtchPacket instance or dict"
)
return self.mutate(
mutation,
variables=mutation.create_payload().dict(by_alias=True, exclude_none=True),
**kwargs,
)

files = get_multipart_payload(mutation)

res = self.mutate_multipart(files,**kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

A few things:

  • This looks like it will always callmutatate_multipart, even if there are no binary uploads, and therfore no reason to usemulti-part. Is that right? Maybe only usemulti-part when necessary?
  • It feels like this decision to use multipart or not, and the few lines hre of what to do in that case are better abstracted away inside the internals ofself.mutate somehow. That way anything that is uploading binary in a mutation will just have that stuff handled implicitly.

return res

def generate_etch_signing_url(self, signer_eid: str, client_user_id: str, **kwargs):
"""Generate a signing URL for a given user."""
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp