Usage in web APIs¶
Note that FPDF
instance objects are not designed to be reusable: content cannot be added once output()
has been called.
Hence, even if the FPDF
class should be thread-safe, we recommend that you either create an instance for every request, or if you want to use a global / shared object, to only store the bytes returned from output()
.
Django¶
Django is:
a high-level Python web framework that encourages rapid development and clean, pragmatic design
There is how you can return a PDF document from a Django view:
from django.http import HttpResponse
from fpdf import FPDF
def report(request):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=24)
pdf.cell(txt="hello world")
return HttpResponse(bytes(pdf.output()), content_type="application/pdf")
Flask¶
Flask is a micro web framework written in Python.
The following code can be placed in a app.py
file and launched using flask run
:
from flask import Flask, make_response
from fpdf import FPDF
app = Flask(__name__)
@app.route("/")
def hello_world():
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=24)
pdf.cell(txt="hello world")
response = make_response(pdf.output())
response.headers["Content-Type"] = "application/pdf"
return response
AWS lambda¶
The following code demonstrates some minimal AWS lambda handler function that returns a PDF file as binary output:
from base64 import b64encode
from fpdf import FPDF
def handler(event, context):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=24)
pdf.cell(txt="hello world")
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
},
'body': b64encode(pdf.output()).decode('utf-8'),
'isBase64Encoded': True
}
This AWS lambda function can then be linked to a HTTP endpoint using API Gateway, or simply exposed as a Lambda Function URL. More information on those pages:
For reference, the test lambda function was initiated using the following AWS CLI commands:
Creating & uploading a lambda layer
pyv=3.8
pip${pyv} install fpdf2 -t python/lib/python${pyv}/site-packages/
# We use a distinct layer for Pillow:
rm -r python/lib/python${pyv}/site-packages/{PIL,Pillow}*
zip -r fpdf2-deps.zip python > /dev/null
aws lambda publish-layer-version --layer-name fpdf2-deps \
--description "Dependencies for fpdf2 lambda" \
--zip-file fileb://fpdf2-deps.zip --compatible-runtimes python${pyv}
Creating the lambda
AWS_ACCOUNT_ID=...
AWS_REGION=eu-west-3
zip -r fpdf2-test.zip lambda.py
aws lambda create-function --function-name fpdf2-test --runtime python${pyv} \
--zip-file fileb://fpdf2-test.zip --handler lambda.handler \
--role arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-fpdf2-role \
--layers arn:aws:lambda:${AWS_REGION}:770693421928:layer:Klayers-python${pyv/./}-Pillow:15 \
arn:aws:lambda:${AWS_REGION}:${AWS_ACCOUNT_ID}:layer:fpdf2-deps:1
aws lambda create-function-url-config --function-name fpdf2-test --auth-type NONE
Those commands do not cover the creation of the lambda-fpdf2-role
role, nor configuring the lambda access permissions, for example with a FunctionURLAllowPublicAccess
resource-based policy.
streamlit¶
streamlit is:
a Python library that makes it easy to create and share custom web apps for data science
The following code demonstrates how to display a PDF and add a button allowing to download it:
from base64 import b64encode
from fpdf import FPDF
import streamlit as st
st.title("Demo of fpdf2 usage with streamlit")
@st.cache
def gen_pdf():
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=24)
pdf.cell(txt="hello world")
return bytes(pdf.output())
# Embed PDF to display it:
base64_pdf = b64encode(gen_pdf()).decode("utf-8")
pdf_display = f'<embed src="data:application/pdf;base64,{base64_pdf}" width="700" height="400" type="application/pdf">'
st.markdown(pdf_display, unsafe_allow_html=True)
# Add a download button:
st.download_button(
label="Download PDF",
data=gen_pdf(),
file_name="file_name.pdf",
mime="application/pdf",
)
Jupyter¶
Check tutorial/notebook.ipynb
web2py¶
Usage of the original PyFPDF lib with web2py is described here: https://github.com/reingart/pyfpdf/blob/master/docs/Web2Py.md
v1.7.2
of PyFPDF is included in web2py
since release 1.85.2
: https://github.com/web2py/web2py/tree/master/gluon/contrib/fpdf