Criando imagens promocionais customizadas com Python, Cairosvg e Django
Python é uma linguagem extremamente versátil e possui bibliotecas que facilitam muito o nosso dia a dia — Uma delas é o cairosvg, que nos possibilita gerar imagens customizadas a partir de templates .svg.
Como o svg é um arquivo de texto que define as características de uma imagem, podemos deixar algumas variáveis dentro do arquivo e substituí-las usando python para criar imagens customizadas 😍
Caso de uso
Nesse exemplo, nosso objetivo será:
- Criar uma imagem customizada para cada cupom/cliente, com um código promocional único.
- Integrar essa criação da imagem com o framework Django
- Escrever testes unitários para o processo.
Pra isso, usaremos as tecnologias: Python, Django e cairosvg.
Dependências e template svg
Primeiro de tudo, precisamos instalar as dependências:
$ pip install cairosvg
Depois disso precisamos de um template svg, onde podemos deixar algumas strings demarcando onde o texto será customizado, como por exemplo as chaves _WIDTH, _HEIGHT, _PROMO_CODE:
<svg xmlns="http://www.w3.org/2000/svg" pointer-events="none" width="_WIDTH" height="_HEIGHT">
<rect width="_WIDTH" height="_HEIGHT"></rect>
<text text-anchor="middle" y="50%" x="50%" dy="0.35em" pointer-events="auto" fill="#ffffff" font-family="arial">
Your promotional code is: _PROMO_CODE
</text>
</svg>
Lendo o arquivo svg e criando um arquivo png a partir dos argumentos passados
Agora que temos um template, podemos definir uma função que irá ler o template .svg, substituir as chaves demarcadas e então gerar um arquivo png:
Esse método irá fazer, em resumo:
- Ler o template svg e remover as quebras de linha (\n)
- Substituir todas as chaves passadas por parâmetro no svg. É aqui que acontece a substituição de _PROMO_CODE para o código real, customizado.
- Chamar a função svg2png do cairo para converter o svg gerado em png.
Usando a função genérica e salvando um arquivo png
Esse exemplo é um pouco mais simples e pode ser customizado para qualquer framework ou processo python, pois vamos apenas usar python puro para gerar uma imagem:
O que nos dará o seguinte resultado 🎉:
Salvando a imagem customizada num modelo do Django
Caso você use o framework Django, é absurdamente simples salvar essa imagem em um campo ImageField. Fica assim:
Pontos de atenção:
- No exemplo anterior, usamos um arquivo real para salvar o png. Nesse exemplo do Django, não queremos criar um arquivo real no sistema de arquivos. Nossa intenção é apenas criar um arquivo em memória e depois passar o arquivo para o Django, onde será feito o upload para o destino correto.
- Esse processo de poder usar um arquivo real ou um arquivo em memória é possível porque no python existem os file-like objects (objetos do tipo arquivo). Esses objetos implementam os protocolos de como um arquivo deve se comportar, e por isso podemos variar o destino real do arquivo gerado.
Testes unitários
“Code without tests is broken as designed.” — Jacob Kaplan-Moss
Agora só falta a peça final: precisamos garantir que nosso código faz o que ele diz que faz e vamos usar testes unitários para garantir isso:
Algumas considerações sobre os testes:
- Estamos fazendo um mock do cairosvg e definindo que o mock é um wrapper para a função real. Isso fará com que o código real do cairosvg seja chamado, mas que possamos “espiar” os valores passados pra poder testar apropriadamente.
- Com isso, no teste da função genérica create_png_from_svg_template, conseguimos espiar se o svg foi gerado corretamente com as chaves passadas.
- O segundo teste verifica se a imagem foi gerada corretamente e salva no banco de dados. Também verifica a URL final da imagem criada.
Considerações finais
Meu objetivo com esse artigo foi mostrar como juntar algumas pecinhas para gerar imagens customizadas em python, com uma abordagem de código limpo e testes unitários para garantir a qualidade do projeto.
Espero que tenha ficado claro e que seja útil pra vocês. Como sempre, estou à disposição para dúvidas e sugestões 🚀