Зафиксируйте бриф и формат
Для примера нужна иконка для статьи про сайты: окно браузера и один курсор, простой контур, без надписи. Запишите формат 1:1, размер показа в карточке и правило для фона. Текст заголовка храните в HTML карточки. Тогда при смене формулировки не придётся заново генерировать изображение. На первом запуске запросите один вариант. Если композиция читается в размере 64×64, её можно использовать как ориентир для следующих иллюстраций.
Заведите токен API в кабинете Recraft и передайте его процессу в переменной RECRAFT_API_TOKEN. Токен храните в локальном менеджере секретов или в настройках окружения сервера. Ознакомьтесь с описанием API Recraft и проверьте доступность нужной модели и расход кредитов. Для векторной генерации в официальной спецификации есть отдельный маршрут, векторный формат задаёт маршрут, а форму ответа — response_format.
Отправьте запрос и распакуйте ответ
Ниже запрос на стандартной библиотеке Python. Параметр b64_json просит вернуть изображение внутри JSON, поэтому отдельно скачивать файл по URL не нужно. Сохраните код в пробной папке. После запуска проверяется, что полезная нагрузка разбирается как XML и корневой элемент относится к SVG. Это позволяет обнаружить повреждённый или неожиданный ответ до записи файла. Описание и формат легко заменить, но проверку формата стоит оставить в обработчике.
import base64
import json
import os
import urllib.request
import xml.etree.ElementTree as ET
from pathlib import Path
payload = {
"model": "recraftv4_vector",
"prompt": "Simple outline vector of a browser window with one cursor, no text",
"n": 1,
"size": "1:1",
"response_format": "b64_json",
}
request = urllib.request.Request(
"https://external.api.recraft.ai/v1/images/generations/vector",
data=json.dumps(payload).encode(),
headers={
"Authorization": "Bearer " + os.environ["RECRAFT_API_TOKEN"],
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(request, timeout=90) as response:
result = json.load(response)
svg = base64.b64decode(result["data"][0]["b64_json"], validate=True)
root = ET.fromstring(svg)
if root.tag != "{http://www.w3.org/2000/svg}svg":
raise ValueError("Expected an SVG document")
Path("browser-icon.svg").write_bytes(svg)Поля, путь и допустимые значения сверены с опубликованной схемой Recraft. Разбор ответа проверен на локальной заглушке с настоящим SVG в base64. Для проверки качества генерации запустите один запрос со своим токеном и осмотрите результат. Если файл открывается, но в нём трудно различить курсор, сократите описание и задайте более явный силуэт. Сравните его с исходным брифом на том же фоне и размере, которые будут в блоге.
Проверьте результат перед автоматической публикацией
Проверка корневого элемента подтверждает формат. Для веб-публикации дополнительно обработайте SVG инструментом очистки и просмотрите его в изоляции: в SVG могут быть ссылки на внешние ресурсы, а в редакционной иконке они не нужны. Проверьте прозрачность фона, пропорции и читаемость на тёмной и светлой подложке. Если рисунок нужен только в маленьких карточках, можно сохранить дополнительно растровую версию для быстрого предпросмотра.
Если API возвращает ошибку доступа, сначала проверьте токен и доступность модели. При ограничении частоты уменьшите число параллельных задач. Если соединение оборвалось во время платной генерации, сначала проверьте журнал запроса и баланс. Повторная отправка может запустить новую генерацию. Для очереди записывайте имя иллюстрации, параметры и статус. При повторном запуске обрабатывайте только незавершённые строки и сохраняйте уже принятые файлы.