2

Here is my code in myclass.py

class Pdf():

    def render_pdf(self,name,html):


        from xhtml2pdf import pisa
        from StringIO import StringIO

        pdf = StringIO()

        pisa.CreatePDF(StringIO(html), pdf)

        return pdf

And I am calling it in api.py like this

@app.route('/invoice/<business_name>/<tin>', methods=['GET'])
def view_invoice(business_name,tin):

   #pdf = StringIO()
  html = render_template('certificate.html', business_name=business_name,tin=tin)
file_class = Pdf()
pdf = file_class.render_pdf(business_name,html)
return pdf

But it throws this error

AttributeError: StringIO instance has no __call__ method

1 Answer 1

6

The following script worked well for me. Note the changes I made:

  • Pdf.render_pdf() now returns pdf.getvalue(), a str.
  • view_invoice() now returns a tuple, so that the Content-Type header can be set.

 

#!/usr/bin/env python

from flask import Flask, render_template
app = Flask(__name__)


class Pdf():

    def render_pdf(self, name, html):

        from xhtml2pdf import pisa
        from StringIO import StringIO

        pdf = StringIO()

        pisa.CreatePDF(StringIO(html), pdf)

        return pdf.getvalue()


@app.route('/invoice/<business_name>/<tin>',  methods=['GET'])
def view_invoice(business_name, tin):

    #pdf = StringIO()
    html = render_template(
        'certificate.html', business_name=business_name, tin=tin)
    file_class = Pdf()
    pdf = file_class.render_pdf(business_name, html)
    headers = {
        'content-type': 'application.pdf',
        'content-disposition': 'attachment; filename=certificate.pdf'}
    return pdf, 200, headers


if __name__ == '__main__':
    app.run(debug=True)
Sign up to request clarification or add additional context in comments.

4 Comments

Man, you just saved my life. Please how can I rate you? And also, the filename that came up is response, how can I change that to View certificate
@OladapoAdebowale You can click the tick mark next to the answer to accept the answer as what worked out for you.
@OladapoAdebowale, it might help to add a content-disposition header. Use either content-disposition: attachment; filename=certificate.pdf or content-disposition: inline; filename=certificate.pdf. See my recent edit.
Unfortunately doesn't work with Python 3.5 or more...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.