Hi community!
Hope you’re doing well
I looked up in this and other forums but couldn’t find a solution for my problem.
I’m creating an app for my company to generate certificates where the user 1) uploads a csv file 2) uploads a certificate template and 3) generates certificates and downloads them.
My app uses Pillow module (version 9.5.0) to write a list of names from the csv file and write in the uploaded certificate template using a specific font.
My problem is that I’m getting an Attribute Error when trying to “write” using Pillow module on the user’s image input. Specifically, when user’s presses the “Generar Certificados” (Create Certificates) button.
This error is unexpected because textsize
is a valid attribute in Pillow’s ImageDraw
module. Also, the code works well locally, but not when deploying the app in the cloud.
AttributeError: 'ImageDraw' object has no attribute 'textsize'
2024-03-30 00:37:18.000 Uncaught app exception
Traceback (most recent call last):
File "/home/adminuser/venv/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 542, in _run_script
exec(code, module.__dict__)
File "/mount/src/creador-certificados/creador_de_certificados/streamlit_nt_app.py", line 85, in <module>
main()
File "/mount/src/creador-certificados/creador_de_certificados/streamlit_nt_app.py", line 51, in main
create_certificate(cleaned_data, cert_template, output_dir)
File "/mount/src/creador-certificados/creador_de_certificados/main.py", line 55, in create_certificate
text_width, _ = draw.textsize(name, font=font)
AttributeError: 'ImageDraw' object has no attribute 'textsize'
I think the problem is related to my “Roboto-Medium.hnn” file in the create_certificate function in main.py:
from PIL import Image, ImageDraw, ImageFont
import pandas as pd
from pathlib import Path
import logging
def clean_data(csv_file):
df = pd.read_csv(csv_file)
df = df.rename(columns={
'Correo electrónico. Por favor, asegurarse de que esté escrito correctamente.': 'mail',
'APELLIDO/S, NOMBRE/S:': 'nombre_apellido'
})
return df
def create_certificate(data, certificate_path: str, output_folder: str):
logging.basicConfig(filename='certificate_creation.log', level=logging.ERROR)
print('Creating your certificates...')
# Extract names from the cleaned data
names = data['nombre_apellido']
for name in names:
# Remove unwanted characters from the name
name = name.replace('.', '').replace(',', '').replace(':', '').strip()
name = name.upper()
text_y_position = 430 # Adjusted position for text
img = Image.open(certificate_path, mode='r')
img_width = img.width
# draw
draw = ImageDraw.Draw(img)
# font
font_size = 110
if len(name) > 30:
font_size = font_size / 2
elif len(name) > 20:
font_size = font_size * 2 / 3
# PROBLEM
font_path = str(Path('data/Roboto-Medium.woff'))
try:
font = ImageFont.truetype(font_path, int(font_size))
except Exception as e:
logging.error(f"Error loading font file: {e}")
print(f"Error loading font file: {e}")
continue # Skip this certificate and continue with the next one
# text width
text_width, _ = draw.textsize(name, font=font)
# draw text for name in orange color
draw.text(((img_width - text_width) / 2, text_y_position), name, font=font, fill='#de5602')
# save certificates in a folder
output_path = f"{output_folder}/{name}.pdf"
img.save(output_path)
print(f"Saved certificate for {name} at {output_path}")
Somehow, the app can’t find and use that font.
I tried using Path from pathlib but I still encountering errors when deploying my app in streamlit cloud.
This is the link for my app: https://creador-certificados-nt.streamlit.app/
This is the link of my repository: https://github.com/axcasas/creador-certificados/tree/master
main.py contains the create_certificate function.
streamlit_app is the app I’m deploying to streamlit.
Thank you!