Python scenario lifecycle
Creation and versions
Choose a site and Python when creating a scenario manually. The scenario owns the language; each version owns its source text. To port PHP or JavaScript code, create a Python scenario and adapt both syntax and SDK calls. Python is not transpiled into JavaScript and has no JavaScript globals.
def title_from_card(card):
node = card.q('.title')
return node.text() if node is not None else ''
def run(ctx):
url = ctx.param('catalog_url', '')
if not url:
ctx.abort('Enter a catalog URL')
response = ctx.http().get(url)
if not response.ok():
ctx.fail('HTTP ' + str(response.status))
for card in response.dom().qa('.product-card'):
sku = card.attr('data-sku')
if sku:
ctx.emit({'sku': sku, 'name': title_from_card(card)}, sku)
Helper functions are supported. The entry point receives one ctx and does not return a list of output records. Export transformations have a dedicated entry point.
Validation and trial
The isolated Python validator checks syntax, imports, entry point structure, and prohibited constructs. It does not execute HTTP requests, verify selectors, or establish source data correctness.
A trial executes the draft with the real Python SDK and platform handlers. Output goes to a preview instead of replacing the live catalog. Check an empty response, a complete record, a missing optional element, an HTTP failure, and stable keys. A small successful trial does not establish completeness of a large catalog.
Publication and schedules
Publish the tested version. Manual live runs and schedules use published code; publication itself does not start collection. Drafts remain available for trials, and a previous version can be published again. Schedules use the shared Akmelo scheduler, time zone, concurrency rules, limits, and run log. Do not build an endless scheduler inside a Python function.
Emitted records enter the common schema, quality checks, record history, and export pipeline. The run page shows execution and HTTP logs. An unhandled Python exception produces a failed run rather than silent success.
Language and packages
The runtime is CPython 3.13. Write synchronous def, ordinary loops, try/finally, dictionaries, and lists. Asynchronous functions, await, custom classes, and accessing private internals are unsupported. Do not use __import__, eval, exec, compile, open, reflection, or loading custom modules.
The allowed standard-library modules are listed in environment. User code cannot install requests, pandas, BeautifulSoup, or Playwright. Use ctx.http() for HTTP, ctx.dom() for HTML, ctx.browser() for interaction, and ctx.documents() for documents. Libraries used internally by the SDK do not become available to scenario imports.
Limits, time, and completion
The runner enforces source, memory, CPU, and wall-clock limits. Actual limits depend on execution mode and platform settings; code cannot raise them. Infinite loops and excess memory stop the sandbox with an error. The platform separately checks request count, allowed addresses, redirects, robots.txt, proxy policy, and source rate limits. The Python process has no direct network access.
Use ctx.sleep(ms) for a controlled pause in milliseconds. Pauses count toward execution time and respect cancellation. Do not create threads or subprocesses to bypass limits. Bound page counts and stable record keys provide safer retries.
def run(ctx):
for page in range(1, 11):
if ctx.cancelled():
ctx.abort('Stopped by the user')
ctx.log('Page', {'page': page})
ctx.progress(page, 10, 'Catalog')
abort() is an intentional stop, fail() is a failure, and an unhandled exception is also a failure. Do not swallow all errors with an empty except. Explain expected exceptions safely and explicitly decide whether continuing can produce correct data.
emit batches records; flush() sends the pending batch. A sent batch does not prove the entire run has committed successfully. See progress and retry.
Agent and offline behavior
Choose an agent with Python; browser support is enabled separately. Agents apply signed cloud definitions, display local status, and store local results. While cloud connectivity is absent, only available local capabilities and previously received configuration can work. Mirroring controls whether records appear in the cloud; disabling it does not erase local records.
Avoid mandatory cloud AI calls in an offline scenario. Save a tested local processing rule in the Python source, then test actual offline operation without affecting other users.