- Notifications
You must be signed in to change notification settings - Fork11
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
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes from10 commits
Commits
Show all changes
13 commits Select commitHold shift + click to select a range
5d85c73 Multipart helpers
aalmazan77927d1 Update payload types
aalmazan79a839f Update HTTP client to support multipart
aalmazan981b3ef Add multipart process to createEtchPacket
aalmazan83859cd Add multipart example
aalmazanae12c46 Update multipart process to accept non-serializable things
aalmazan91f6cb9 Linting, update documentation
aalmazan39cafc5 Update tests
aalmazanf63fb9c Lint fixes
aalmazanf289c0b Less annoying example usage with envvars
aalmazan4630df2 Minor package updates, remove operationName
aalmazan13346a2 Update changelog
aalmazan4340aba Bump version
aalmazanFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
6 changes: 5 additions & 1 deletionexamples/create_etch_existing_cast.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletionexamples/create_etch_markdown.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletionexamples/create_etch_markup.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletionexamples/create_etch_upload_file.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletionsexamples/create_etch_upload_file_multipart.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletionexamples/fill_pdf.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletionexamples/generate_pdf.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
29 changes: 24 additions & 5 deletionspython_anvil/api.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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__) | ||
| @@ -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 | ||
| @@ -291,11 +310,11 @@ def create_etch_packet( | ||
| raise ValueError( | ||
| "`payload` must be a valid CreateEtchPacket instance or dict" | ||
| ) | ||
| files = get_multipart_payload(mutation) | ||
| res = self.mutate_multipart(files,**kwargs) | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. A few things:
| ||
| return res | ||
| def generate_etch_signing_url(self, signer_eid: str, client_user_id: str, **kwargs): | ||
| """Generate a signing URL for a given user.""" | ||
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.