Generate flattened PDF with Python

Per the Adobe Docs, you can change the Bit Position of the Editable Form Fields to 1 to make the field ReadOnly. I provided a full solution here, but it uses Django:

https://stackoverflow.com/a/55301804/8382028

Adobe Docs (page 552):

https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf

Use PyPDF2 to fill the fields, then loop through the annotations to change the bit position:

from io import BytesIO

from PyPDF2 import PdfFileReader, PdfFileWriter
from PyPDF2.generic import BooleanObject, NameObject, NumberObject

# open the pdf
input_stream = open("YourPDF.pdf", "rb")
reader = PdfFileReader(input_stream, strict=False)
if "/AcroForm" in reader.trailer["/Root"]:
    reader.trailer["/Root"]["/AcroForm"].update(
        {NameObject("/NeedAppearances"): BooleanObject(True)}
    )

writer = PdfFileWriter()
writer.set_need_appearances_writer()
if "/AcroForm" in writer._root_object:
    # Acro form is form field, set needs appearances to fix printing issues
    writer._root_object["/AcroForm"].update(
        {NameObject("/NeedAppearances"): BooleanObject(True)}
    )

data_dict = dict()  # this is a dict of your form values

writer.addPage(reader.getPage(0))
page = writer.getPage(0)
# update form fields
writer.updatePageFormFieldValues(page, data_dict)
for j in range(0, len(page["/Annots"])):
    writer_annot = page["/Annots"][j].getObject()
    for field in data_dict:
        if writer_annot.get("/T") == field:
            # make ReadOnly:
            writer_annot.update({NameObject("/Ff"): NumberObject(1)})
output_stream = BytesIO()
writer.write(output_stream)

# output_stream is your flattened PDF

A simple but more of a round about way it to covert the pdf to images than to put those image into a pdf.

You'll need pdf2image and PIL

Like So

from pdf2image import convert_from_path 
from PIL import Image

images = convert_from_path('temp.pdf') 
im1 = images[0]
images.pop(0)

pdf1_filename = "flattened.pdf"

im1.save(pdf1_filename, "PDF" ,resolution=100.0, save_all=True, append_images=images)

Edit:

I created a library to do this called fillpdf

pip install fillpdf

from fillpdf import fillpdfs
fillpdfs.flatten_pdf('input.pdf', 'newflat.pdf')

If installing an OS package is an option, then you could use pdftk with its python wrapper pypdftk like this:

import pypdftk
pypdftk.fill_form('filled.pdf', out_file='flattened.pdf', flatten=True)

You would also need to install the pdftk package, which on Ubuntu could be done like this:

sudo apt-get install pdftk

The pypdftk library can by downloaded from PyPI:

pip install pypdftk

Update: pdftk was briefly removed from Ubuntu in version 18.04, but it seems it is back since 20.04.