Python API

The arelle.api module is the supported method for integrating Arelle into other Python applications.

Warning

Arelle uses shared global state (PackageManager, PluginManager) which is NOT thread-safe. Only ONE Session can run at a time across the entire process.

Safe usage:

  • Use one Session at a time per process

  • Use a process pool instead of thread pool for parallelism

Unsafe usage:

  • Running multiple Sessions concurrently in any threads

  • Threading.Thread with Session.run()

Session

The Arelle Python API provides Session to run Arelle and access output. You can import it with:

from arelle.api.Session import Session

From there you can configure the session, run Arelle, and retrieve the generated models and logs (see examples below).

Logging

Arelle’s logging system is accessible through the Session object. The following parameters can be provided when calling the run() method to control logging behavior:

  • logHandler: Provide a custom logging handler to capture logs in a specific way (e.g., writing to a file, sending to an external logging service, etc.)

    • This parameter is higher priority than the logFileName keyword behavior, described below.

  • logFileName: Specify a file path to write log messages to a file. Certain keywords trigger special behavior (note that logHandler takes precedence over these keywords):

    • logToBuffer: log messages will be stored in an internal buffer that can be accessed via the get_logs() method (see LogToBufferHandler).

    • logToPrint: log messages will be printed to standard output (see LogToPrintHandler).

    • logToStdErr: log messages will be printed to standard error (see LogToPrintHandler).

    • logToStructuredMessage: log messages will be stored in an internal buffer as structured data (including log level, message, timestamp, etc.) that can be accessed via the get_logs() method (see StructuredMessageLogHandler).

  • logFilters: A list of log filters to apply to the logs.

If logHandler and logFileName are omitted from the run() method call, Arelle will fall back to RuntimeOptions.logFile (same behavior as logFileName), before finally defaulting to logToPrint.

Examples

Creating an iXBRL Viewer

with open(samples_zip_path, 'rb') as stream:
    options = RuntimeOptions(
        entrypointFile=str(target_path),
        internetConnectivity='offline' if arelle_offline else 'online',
        keepOpen=True,
        logFile="logToStructuredMessage",
        logFormat="[%(messageCode)s] %(message)s - %(file)s",
        logPropagate=False,
        pluginOptions={
            'saveViewerDest': str(viewer_path),
            'viewer_feature_review': True,
        },
        plugins='ixbrl-viewer',
    )
    # Plugin default options haven't been applied yet.
    assert not hasattr(options, 'viewerURL')
    with Session() as session:
        session.run(
            options,
            sourceZipStream=stream,
            logFilters=[log_filter],
        )
        # Plugin default options were applied.
        assert hasattr(options, "viewerURL")
        assert options.viewerURL.endswith("ixbrlviewer.js")
        log_xml = session.get_logs('xml')

Querying a Model

options = RuntimeOptions(
    entrypointFile=str(report_zip_path),
    disclosureSystemName='esef-2024',
    internetConnectivity='offline',
    keepOpen=True,
    logFile=str(arelle_log_file),
    logFormat="[%(messageCode)s] %(message)s - %(file)s",
    packages=package_paths,
    plugins='validate/ESEF',
    validate=True,
)
target_qname = qname('https://xbrl.ifrs.org/taxonomy/2022-03-24/ifrs-full', 'Equity')
with Session() as session:
    session.run(options)
    model_xbrls = session.get_models()
    for model_xbrl in model_xbrls:
        equity_facts: set[ModelFact] = model_xbrl.factsByQname.get(target_qname, set())
        for equity_fact in equity_facts:
            print(f'Found Equity fact with value: {equity_fact.xValue}')
    log_xml = session.get_logs('xml')

Using a Validation Plugin

options = RuntimeOptions(
    entrypointFile=str(report_zip_path),
    disclosureSystemName='esef-2024',
    internetConnectivity='offline',
    logFile=str(arelle_log_file),
    logFormat="[%(messageCode)s] %(message)s - %(file)s",
    packages=package_paths,
    parameters="authority=SE",
    plugins='validate/ESEF',
    validate=True,
)
with Session() as session:
    assert not hasattr(options, "saveTargetInstance"), "validate/ESEF plugin dependency inlineXbrlDocumentSet CLI args should not be loaded yet."
    session.run(options)
    log_xml = session.get_logs('xml')
    assert hasattr(options, "saveTargetInstance"), "validate/ESEF plugin dependency inlineXbrlDocumentSet CLI args were not loaded."