Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the Base URI for Weasyprint in Python

I'm using the Weasyprint library for Python in an attempt to print out an html file to pdf. I am attempting to embed an image into the background of my page. Here is the code:

HTML(string='''
    <h1>The title</h1>
    <p>Content goes here
''', base_url=os.path.dirname(os.path.realpath(__file__))).write_pdf("hello.pdf",  stylesheets=[CSS(string='body{background-image: url("example_image.png")}')])

The output I get to this code is the following:

Ignored `background-image: url("example_image.png")` at 1:6, Relative URI reference without a base URI: 'example_image.png'.
blah@blah:~/Dropbox/Terraverde/annual_reports$ python3 test_excel.py

I have tried to search Stackoverflow for solutions to this problem, and have read the documentation, but the closest thing I could find to an answer is the following post regarding an identical problem but for Django: Django WeasyPrint CSS integration warning: Relative URI reference without a base URI: <link href="/static/css/bootstrap.min.css"> at line None

I also tried using document.baseURI in my code:

base_url=os.path.dirname(os.path.realpath(__file__))).write_pdf("hello.pdf",  stylesheets=[CSS(string='body{background-image: url(document.baseURI + "example_image.png")}')])

but this still yielded an error:

Parse error at 1:24, unexpected BAD_URI token in property value

Any suggestions on how to handle a problem, or perhaps a command similar to Django's request.build_absolute_uri() for either regular Python or for Flask?

like image 470
user3787027 Avatar asked Jul 23 '15 00:07

user3787027


2 Answers

I had the same error I had this tag, on OSX, in a template that I rendered with pystache:

<img src="/Users/my_username/my_project/my_image.png" />

So I tried this instead and it worked:

<img src="file:///Users/my_username/my_project/my_image.png" />

Just add file:// before the /Users/... path. (Note that it's 3 slashes).

like image 108
hendrixski Avatar answered Sep 22 '22 06:09

hendrixski


I figured out that base_url had to be given as an arg to the weasyprint.CSS function and not to the weasyprint.HTML one:

from weasyprint import HTML, CSS

html_content = '''<h1>The title</h1><p>Content goes here'''

base_url = os.path.dirname(os.path.realpath(__file__))
css = CSS(string='body{background-image: url("example_image.png")}', base_url=base_url)

HTML(string=html_content).write_pdf("hello.pdf", stylesheets=[css])

As a bonus, the same with loading local fonts located in a fonts folder placed aside this script:

# for debugging
import logging
logger = logging.getLogger('weasyprint')
logger.addHandler(logging.StreamHandler())

import os

from weasyprint import HTML, CSS
from weasyprint.fonts import FontConfiguration


html_content = '''<h1>The title</h1><p>Content goes here</p>'''

font_config = FontConfiguration()

THIS_FILE_DIR = os.path.dirname(os.path.abspath(__file__)) + os.sep
base_url = 'file://' + THIS_FILE_DIR

# fonts downloaded from
# https://fonts.google.com/specimen/Poppins?preview.text_type=custom&sidebar.open=true&selection.family=Poppins:wght@400;500;600;700
css = CSS(string='''
        @font-face {
          font-family: 'Poppins';
          src: url('./fonts/Poppins-Regular.ttf') format('truetype');
          font-weight: 400;
          font-style: normal;
        }
        
        @font-face {
          font-family: 'Poppins';
          src: url('./fonts/Poppins-Medium.ttf') format('truetype');
          font-weight: 500;
          font-style: normal;
        }
        
        @font-face {
          font-family: 'Poppins';
          src: url('./fonts/Poppins-SemiBold.ttf') format('truetype');
          font-weight: 600;
          font-style: normal;
        }
        
        @font-face {
          font-family: 'Poppins';
          src: url('../base/fonts/Poppins-Bold.ttf') format('truetype');
          font-weight: 700;
          font-style: normal;
        }
        ''', font_config=font_config, base_url=base_url)

HTML(string=html_content).write_pdf("hello.pdf", stylesheets=[css])
like image 34
fallino Avatar answered Sep 22 '22 06:09

fallino