Документы, почта, хранилища и входы на Python
Python использует те же платформенные подключения и права, что остальные языки. Самостоятельный импорт клиента базы, S3 или IMAP не нужен. Для входных данных используйте закреплённые входы процесса, а не идентификатор чужого письма или прогона.
CSV, Excel, Word и PDF
def run(ctx):
document = ctx.documents().from_url(ctx.param('file_url'), 'prices.csv')
if not document.complete():
ctx.fail('Документ прочитан не полностью')
if 'formulas_partly_calculated' in document.warnings():
ctx.fail('Уточните диапазон и проверьте формулы')
sheet = document.sheet(0)
for row in sheet.records(1):
sku = str(row.get('sku') or '')
if sku:
ctx.emit({'sku': sku, 'price': ctx.text().money(row.get('price'))}, sku)
В примере первая строка CSV содержит sku,price. Для другого заголовка задайте явное сопоставление. Порядок листов начинается с нуля, номера строк и ячеек начинаются с единицы. CSV нужно разбирать как документ, а не split(','): кавычки, разделители и переносы внутри ячеек требуют правильного парсера.
Обработка документов выполняется изолированным сервисом платформы. Python получает данные, не путь к файлу. Макросы и внешние ссылки не исполняются; формулы и OCR имеют ограничения. Перед полной выгрузкой проверьте complete(), warnings() и ошибки нужных ячеек. Подробности: Document, Worksheet.
Входящее письмо
def run(ctx):
mail = ctx.mail()
if not mail.available():
ctx.abort('Для этого запуска нет входящего письма')
for attachment in mail.attachments():
if not attachment.get('name', '').lower().endswith('.csv'):
continue
document = mail.document(attachment['id'])
if not document.complete():
ctx.fail('Вложение прочитано не полностью')
for record in document.sheet(0).records(1):
sku = str(record.get('sku') or '')
if sku:
ctx.emit(record, sku)
Ручная проба без почтового события не имеет письмо автоматически. Вложение должно принадлежать разрешённому событию и ещё храниться. Не выбирайте письмо по произвольному глобальному идентификатору. attachment() возвращает сырые байты bytes; структурный документ читайте через document() по контракту Mail.
Закреплённые источники и цены
ctx.sources().input('catalog') читает заранее настроенный вход. Для записей проверьте records, run_id, collected_at. sources().document('supplier', id) разбирает вложение закреплённого почтового входа. compare_prices выполняется локально для 2–10 источников, без AI и без пересчёта валют. У каждого предложения должны быть sku, числовая price и одинаковая currency; дубликат артикула внутри источника считается ошибкой.
Сохранить файл в S3
def run(ctx):
storage = ctx.storage('media')
stored = storage.put('reports/summary.txt', 'Ready', 'text/plain')
ctx.log('Файл сохранён', {'key': stored.key, 'dry_run': stored.dry_run})
Подключение должно быть заранее разрешено. Итоговый key берите из свойства StoredFile.key, а не предполагайте, что он точно совпадает с предложенным. Временную ссылку получайте через storage.url(key, ttl_seconds). В пробном режиме запись может быть сухой; проверьте поведение подключения до использования в рабочем процессе. Storage.
AI и автономный агент
analyze, transform, find, repair, document_rows и extract доступны через Ai. Данные внешней модели передавайте только по разрешённой политике. Документный план работает по обезличенной структуре, но обычные analyze/transform получают переданное содержимое. AI требует связи с платформой; автономный сценарий должен иметь проверенный локальный алгоритм вместо обязательного запроса к модели.