What I’m trying to do:
I have generated a PDF document using Anvil’s very good anvil.pdf.render_form
method.
Now I need to add to the PDF the capabilty to be digitally signed.
To do this, I need to add a PDF-Form with a Digital Signature field.
What I’ve tried and what’s not working:
I tried looking at already installed packages that looked promising like PyPDF2 and fpdf2 but couldn’t sort it out.
Has anyone already done that and can he/she point me to the right tool (pip installable package?) to use?
Thank you
Just to share how I solved it, I installed PyHanko in my app’s virtual environment.
1 Like
Thank you for sharing. Is it possible to link a minimal clone of your solution?
Hi @nickantonaccio
sure! Here it is.
https://anvil.works/build#clone:AQ64KFRHRMKWDFUB=B7WXSWQTHXJOZX6W45VRZXHQ
It’s just a small server funcion.
from pyhanko.sign.fields import SigFieldSpec, append_signature_field
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
import anvil.media
# PARAM 1: uploaded_file: anvil media with input pdf file
# PARAM 2: name: 'signatures'
# type: list of dictionaries
# valore: list of dictionaries representing signature fields to add:
# [
# {
# "sig_name": <string> signature field name,
# "position": {
# "page": <int> page to add the field to. Negative numbers are applied from the end,
# "x1": <int>, "y1": <int>, "x2": <int>, "y2": <int> signature field box in cartesian coordinates (i.e. (0,0) is lower left)
# }
# }
# ]
# EXMAPLE: [{"sig_name":"signature_1","position":{"page":1,"x1":100,"y1":100,"x2":200,"y2":200}},{"sig_name":"signature_2","position":{"page":2,"x1":150,"y1":200,"x2":250,"y2":300}}]
# OUTPUT: anvil.media of the pdf file with the signatures
def add_sig_fields(uploaded_file, signatures):
# write temp file and call pyhanko
if uploaded_file.name[-4:] == ".pdf":
output_filename = f"/tmp/{uploaded_file.name[:-4]}.pdf"
else:
output_filename = f"/tmp/{uploaded_file.name}.pdf"
with open(output_filename, 'wb+') as doc:
doc.write(uploaded_file.get_bytes())
w = IncrementalPdfFileWriter(doc)
for signature in signatures:
append_signature_field(
w,
SigFieldSpec(
sig_field_name = signature['sig_name'],
on_page = signature['position']['page'],
box = (signature['position']['x1'],signature['position']['y1'],signature['position']['x2'],signature['position']['y2'])
)
)
w.write_in_place()
output_media = anvil.media.from_file(output_filename, "application/pdf")
return output_media
3 Likes
Thank you! Now exploring the ‘how to ensure signed pdf documents are legally binding’ Google rabbit hole…