Automatizando a Impressão de Etiquetas com Scripts de Campo em Python
A etiqueta quase sempre sai certa. A data está desatualizada, o número de série perdeu os zeros à esquerda e o total precisa de um dígito verificador antes que o código de barras possa ser lido. Então alguém abre o modelo de etiqueta no designer, edita três campos, manda imprimir e, na manhã seguinte, faz exatamente a mesma coisa.
Essa edição não pertence a um modelo. Ela pertence ao código que é executado no momento da impressão. O RSJ LPSNG permite anexar um bloco de script Python diretamente a um campo da etiqueta, de modo que a transformação acontece dentro do modelo — sem etapa de pré-processamento, sem o ritual de “corrigir o CSV primeiro” entre o seu ERP e a impressora.
Este artigo trata da automação no nível do campo: o que é um script de campo, como configurá-lo uma única vez, como acioná-lo a partir da API do serviço web e como evitar que ele quebre silenciosamente a sua linha de produção.
Dois tópicos adjacentes são abordados em outros lugares: conteúdo que muda a cada pedido está em Building Order-Specific Labeling on Top of a Label Printing API, e etiquetas orientadas a dados a partir de planilhas estão em How to Create Labels from Excel Data Files and Lookup Tables. Aqui ficamos no campo.
Por que Automatizar a Impressão de Etiquetas com Scripts de Campo em Python?
Os scripts de campo são executados dentro do modelo de etiqueta. O bloco Python é anexado a um campo e tem acesso ao valor atual desse campo, que ele pode modificar antes que a etiqueta seja renderizada. Essa única decisão de design muda o pipeline:
- Sem pré-processamento externo. Você não precisa de um script que reescreva os dados de entrada antes de enviá-los. Os dados entram como estão; a etiqueta corrige o que precisa ser corrigido.
- Consistência entre clientes. O script viaja junto com a etiqueta. Seja o job originado da interface web, da API do serviço web ou do LPSNG Player, o mesmo campo recebe o mesmo tratamento.
- A lógica é revisável. Ela fica ao lado do campo que afeta, não em um cron job no notebook de alguém.
As tarefas que justificam isso são entediantes e repetitivas:
| Tarefa | Abordagem manual | Script de campo |
|---|---|---|
| Carimbo de data/hora de impressão | Digitar a data de hoje no campo | Formatar o valor no momento da renderização |
| Números de série | Preencher à mão, esquecer um, reimprimir | Normalizar para uma largura fixa |
| Dígitos verificadores | Calcular em uma planilha | Calcular a partir do valor do campo |
| Rótulos derivados | Copiar um valor de outro campo | Referenciar o campo de origem |
Nenhuma dessas tarefas é difícil. Esse é o ponto — elas são pequenas demais para merecer um serviço e frequentes demais para continuar fazendo à mão.
Configuração Única: Preparando Sua Etiqueta e Seu Script
A configuração é um trabalho único por campo. Você precisa do label studio, não de um ambiente Python local.
- Abra a etiqueta que deseja automatizar no label studio do LPSNG e selecione o campo. Escolha um campo que mapeie para um elemento de texto ou código de barras.
- Anexe um bloco de script Python a esse campo por meio da API de script de campo. O script é armazenado e gerenciado pela plataforma junto com a etiqueta — não há interpretador para instalar no cliente de impressão.
- Use o contexto do script. O bloco vê o valor atual do campo e retorna um valor modificado antes da impressão. As variáveis de contexto exatas estão definidas na referência da API Python — leia uma vez e depois copie o padrão.
- Salve a etiqueta. A partir daí, todo job que renderizar essa etiqueta executará o script.
Um bloco mínimo que normaliza um número de série:
# Field: serial
# Runs before rendering. Input: the value passed in the print job.
raw = str(value).strip()
if raw.isdigit():
value = f"SN-{int(raw):06d}"
else:
value = raw.upper()
E outro que carimba o horário de impressão em vez de confiar nos dados:
# Field: printed_at
from datetime import datetime
value = datetime.now().strftime("%Y-%m-%d %H:%M")
O valor de fazer isso em uma plataforma gerenciada, em vez de no seu próprio código, é que o script faz parte da etiqueta: ele é versionado junto com ela, reutilizado entre jobs e não pode sair de sincronia com o modelo.
A reutilização é o verdadeiro retorno. Depois que um script está correto, anexe o mesmo bloco a todos os campos que precisam da mesma transformação — entre etiquetas, entre impressoras. Dez modelos de etiqueta que imprimem números de série da mesma forma são dez modelos que falham da mesma forma, e um único lugar para corrigir.
Construindo o Pipeline Automatizado: Dos Dados à Impressão
Com o script anexado, o pipeline é: autenticar, enviar um job de impressão, deixar a etiqueta fazer o trabalho.
Autentique uma vez
A interface de serviço web do LPSNG usa OAuth2 com um protocolo de registro simplificado que conecta um sistema externo usando uma única URL. Faça o registro uma vez, armazene o token no seu cofre de segredos e mantenha-o fora do seu repositório:
export LPSNG_BASE_URL="https://lpsng.rsj.de" # host of your edition
export LPSNG_TOKEN="<token from the OAuth2 registration>"
Envie um job
A API do serviço web aceita jobs de impressão, renderiza etiquetas individuais como PDF ou PNG e oferece suporte à impressão direta. Os caminhos exatos dos endpoints e o esquema do payload vêm da documentação da interface de serviço web — o trecho abaixo mostra o formato da chamada, não um substituto para a referência:
import os
import requests
BASE = os.environ["LPSNG_BASE_URL"]
TOKEN = os.environ["LPSNG_TOKEN"]
job = {
# Payload keys are illustrative — use the schema from the
# web service interface documentation.
"label": "shipping-label",
"printer": "warehouse-zebra-01",
"data": {
"order_id": "A-10442",
"serial": "42", # the field script turns this into SN-000042
"printed_at": "", # left empty on purpose
},
}
resp = requests.post(
f"{BASE}/<print-endpoint-from-the-docs>",
headers={"Authorization": f"Bearer {TOKEN}"},
json=job,
timeout=30,
)
resp.raise_for_status()
print(resp.json()) # the response gives you the reference to poll
Observe o que o chamador não faz: ele não formata o número de série e não preenche printed_at. Essas agora são tarefas da etiqueta.
O caso interessante: calcular um valor
A transformação que se paga mais rápido é um dígito verificador, porque um dígito errado significa que um scanner rejeita a etiqueta na estação de embalagem. O script o calcula a partir do valor que o job passou:
# Field: ean
# Compute the mod-10 check digit for a 12-digit payload.
digits = [int(c) for c in str(value) if c.isdigit()]
if len(digits) == 12:
checksum = (10 - (sum(digits[::2]) + 3 * sum(digits[1::2])) % 10) % 10
value = "".join(map(str, digits)) + str(checksum)
else:
# Defensive: don't render an invalid barcode silently.
value = "INVALID"
Como o script modifica o valor do campo antes de o código de barras ser renderizado, o conteúdo do código de barras reflete o resultado calculado. Você não precisa de uma etapa separada de geração de código de barras.
O caminho difícil, para contraste
A alternativa é calcular esses valores a montante: um pré-processador que lê os dados do pedido, reescreve cada campo e só então chama a API. Funciona, até que o pré-processador e o modelo de etiqueta discordem — um preenche com seis dígitos, o outro com oito — e ninguém percebe até que um pallet seja enviado com números de série ilegíveis. Manter a lógica dentro do modelo significa que existe exatamente uma definição de “correto” por campo.
Se você precisar executar a mesma lógica de etiqueta em algum lugar sem um navegador, o LPSNG Player é um mecanismo de impressão de linha de comando autônomo que recebe um pacote mais dados e produz PDF, PNG, JSON, uma impressão direta ou uma atualização de ESL. Mesma etiqueta, mesmos scripts, contexto de execução diferente.
Monitoramento e Tratamento de Falhas na Impressão Automatizada
Um pipeline automatizado que falha silenciosamente é pior que um manual, porque ninguém está olhando para a etiqueta.
Observe a fila. A interface web tem uma fila de jobs, e a API do serviço web permite verificar o status do job. Faça polling da referência que você recebeu no envio, com backoff, e dispare um alerta quando um job permanecer no mesmo estado por tempo demais:
import time
def wait_for_job(session, base, job_ref, timeout=120, interval=5):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
status = session.get(
f"{base}/<job-status-endpoint-from-the-docs>/{job_ref}",
timeout=15,
).json()
if status.get("state") in ("done", "failed"):
return status
time.sleep(interval)
raise TimeoutError(f"job {job_ref} did not finish in {timeout}s")
A interface publicada documenta o envio de jobs, a renderização de etiquetas individuais, a impressão direta e o status — ela não descreve webhooks, então o polling é o padrão sobre o qual construir. Se você precisar de notificações push, trate isso como uma lacuna a resolver do seu lado.
Falhe de forma defensiva dentro do script. Decida o que uma entrada inválida deve fazer antes que isso aconteça. Um script que renderiza INVALID em um campo de código de barras está lhe fazendo um favor em comparação com um que lança uma exceção e derruba o job inteiro — ou um que lança uma exceção, é engolido e imprime o valor não formatado. Consulte a documentação da API de script de campo para saber como a plataforma relata um bloco com falha e escreva seus scripts de modo que o modo de falha seja o que você escolheu.
Faça um dry-run com a saída renderizada. A API do serviço web pode renderizar uma etiqueta individual como PDF ou PNG. Renderize antes de imprimir. É o teste de fumaça mais barato que você tem: alimente o script com uma entrada conhecida, olhe a saída e só então aponte o pipeline para a impressora.
Boas Práticas para Scripts de Campo em Python
- Uma transformação por script. Um bloco que formata uma data e busca o nome de um cliente e recalcula um total é um bloco que ninguém vai depurar às 2 da manhã.
- Seja idempotente. Reimpressões acontecem — uma etiqueta atolada, uma caixa rejeitada, um operador que aperta imprimir duas vezes. Se
SN-000042passar pelo script novamente, deve sair comoSN-000042, não comoSN-SN-000042. Verifique se o valor já tem o formato esperado antes de transformá-lo. - Versione os scripts fora do LPSNG. Mantenha as definições de etiqueta e seus blocos de script no Git com uma breve nota sobre por que cada um existe. A plataforma os armazena e executa; ela não substitui a revisão de código.
- Nunca codifique dados diretamente. Sem números de cliente fixos, sem datas fixas, sem lógica de ramificação específica de impressora. Tudo deve vir do valor do campo ou dos dados passados no job de impressão.
- Mantenha leve. Evite operações de longa duração. Os scripts de campo são executados no caminho de impressão, e um script lento é uma etiqueta lenta.
- Teste com anomalias reais. Strings vazias, zeros à esquerda, valores que já estão formatados, valores muito longos. É aí que os scripts de campo quebram.
FAQ
Os scripts de campo em Python podem acessar APIs externas ou bancos de dados?
A API de script de campo foi projetada para acessar e modificar valores de campo dentro do contexto da etiqueta. Para dados externos, você normalmente os passaria nos dados do job de impressão. Consulte a documentação do LPSNG para quaisquer limitações sobre chamadas externas.
Qual versão do Python e quais bibliotecas estão disponíveis nos scripts de campo?
O ambiente Python exato está especificado na documentação da API de script de campo do LPSNG. Recomenda-se usar recursos da biblioteca padrão e manter os scripts leves.
Como os scripts de campo funcionam com códigos de barras?
Os scripts podem modificar o valor do campo antes que o código de barras seja renderizado, permitindo calcular dígitos verificadores, formatar dados ou aplicar transformações que afetam o conteúdo do código de barras.
Há um limite de tempo de execução do script?
Os scripts de campo devem ser eficientes. Embora limites específicos não estejam detalhados nas informações fornecidas, é uma boa prática evitar operações de longa duração. Consulte a documentação do LPSNG para quaisquer restrições.
Conclusão
O padrão é simples, e é por isso que ele se sustenta: anexe a transformação ao campo uma vez, autentique uma vez, envie jobs para sempre. A edição manual desaparece, e a definição de uma etiqueta correta vive em exatamente um lugar — o modelo — em vez de ficar com quem por acaso estava na impressora nesta manhã.
Comece com um campo. Escolha aquele que sua equipe edita com mais frequência, escreva dez linhas de Python, renderize um PDF e compare com uma etiqueta sabidamente correta. Depois faça o próximo.
O Next Generation Label Printing System é a plataforma gerenciada que executa esses scripts — o label studio, a interface de serviço web OAuth2, a fila de jobs e o Player — sem um ambiente Python local para manter. Você pode ver o quadro completo em lpsng.rsj.de.
Posts relacionados
- Zebra Label Software Alternative: A Browser-Based Approach
- Building Order-Specific Labeling on Top of a Label Printing API
- How to Create Labels from Excel Data Files and Lookup Tables
