Search code examples
pythonreportlab

Place image in PDF from API call in python?


Is there any way to place an image to pdf from an url in python? The idea is to generate a pdf with its related image from an API call. I tried with reportlab and its class ImageReader. After I run this code it crashes the program since io_url is too large.

img = 'url_path'
io_url = urllib.request.urlopen(img).read()
image = ImageReader(io_url)

EDIT --- Trying with Flask:

class PostDogQR(Resource):

def get(self, usermail, dog_name ):

  client = pymongo.MongoClient('credentials')
  filter={'UserMail':usermail,'title':dog_name}

  result = client['dbname']['collection'].find(
    filter=filter
  )
  json_response = json.dumps(list(result), default=json_util.default)
  dog = json.loads(json_response)

  df = pd.DataFrame(dog).to_dict()
  title = df['title'][0]
  breed =df['Breed'][0]
  img_url = 'image_url'
  dog_img = df['DogImg'][0]
  dog_age = df['DogAge'][0]
  dog_desc = df['DogDescription'][0]

  pdf = FPDF(unit='mm')
  pdf.set_font('Arial', 'B', 12)
  pdf.add_page()
  pdf.multi_cell(120.0,4.0,f'Hello! My name is {title}.\nI am a {breed} and I am {dog_age} years old.\n\nThis is my story: {dog_desc}',border=0)
  pdf.image(img_url,150,10,50,60)
  #pdf.output("yourfile.pdf", "F")
  response = make_response(pdf.output(dest='S').encode('latin-1'))
  response.headers.set('Content-Disposition', 'attachment', filename= dog_name + '_' + usermail + '.pdf')
  response.headers.set('Content-Type', 'application/pdf')
  return response

I get:

RuntimeError: FPDF error: Missing or incorrect image file: "here it comes my url image address"

Solution

  • Based on the fact that your requirement is to use a dynamic image url...this will work for you:

    (Take it that "c" is your canvas variable)

    import urllib.request
    
    urllib.request.urlretrieve('https://source.unsplash.com/random/200x200?sig=1',"image_context.png")
    imgSize = 200      
    c.drawImage("image_context.png", width=imgSize, x=100, y=100, preserveAspectRatio=True)
    

    Flask example:

    import urllib.request
    import io
    from reportlab.lib.units import inch, mm, cm
    from reportlab.lib.pagesizes import A4
    from reportlab.pdfgen import canvas
    
    def pdf():
    
        # Create Bytestream buffer
        buf = io.BytesIO()
        
        # Create a canvas
        c = canvas.Canvas(buf, pagesize=A4, bottomup=0)
    
        urllib.request.urlretrieve('https://source.unsplash.com/random/200x200?sig=1',"image_context.png")
    
        imgSize = 200      
        c.drawImage("image_context.png", width=imgSize, x=100, y=100, preserveAspectRatio=True)
    
        c.showPage() #show the page
        
        #Save the canvas with the data
        c.save()
        buf.seek(0)
    
        response = make_response(buf)
        response.headers['Content-Disposition'] = "attachment; filename=" + "report" + ".pdf"
        response.headers['Content-Type'] = 'application/pdf'
        return response