К содержимому

Документация

Документы, почта, хранилища и входы на 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 требует связи с платформой; автономный сценарий должен иметь проверенный локальный алгоритм вместо обязательного запроса к модели.