---
title: "What's in the Artifact"
description: "What an Artifact bundle contains, which objects can produce one, and how to run it outside Corridor."
---

<div style="padding: 14px 16px; border: 0.5px solid #AFA9EC; border-radius: 12px; background: #EEEDFE; margin-bottom: 1.5rem;">
  <div style="display: flex; align-items: center; gap: 7px; margin-bottom: 8px;">
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
      <path d="M9 2L4 9h4l-1 5 5-7H8l1-5z" stroke="#7f77dd" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
    <span style="font-size: 11px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: #534AB7;">TL;DR</span>
  </div>
  <div style="font-size: 13px; color: #3C3489; line-height: 1.65;">
    An <strong>Artifact</strong> is a self-contained bundle that Corridor generates for a registered object. It packs the object's full logic together with every dependency it needs, so you can run it in your own environment without connecting back to Corridor. Available for a <strong>Data Element</strong>, <strong>Feature</strong>, <strong>Model</strong>, or <strong>Policy</strong>.
  </div>
</div>

## What is it?

An Artifact is a bundle of documents and ready-to-run scripts that Corridor builds for a registered object. Any object you register - a Data Element, Feature, Model, or Policy - can be exported as an Artifact and run somewhere else entirely.

The idea is simple: the Artifact takes the logic you built inside Corridor and hands it to you as a standalone package. It runs on its own, in an isolated test environment or in production, with no live connection to Corridor.

An Artifact is built to:

- **Carry the full logic** - so the object you registered in Corridor can run outside it.
- **Be self-sufficient** - everything the object needs is packed inside the bundle.
- **Stay lightweight** - it leans on the runtime environment as little as possible.

## Which objects can produce an Artifact?

You can export an Artifact for any of these four objects:

- Data Element
- Feature
- Model
- Policy

An Artifact can be exported at any stage - draft, pending approval, approved, or rejected. When the object is still in progress, Corridor builds the bundle on the spot at export time. Once the object is **Approved**, Corridor keeps a finalized bundle ready, and that is the one you download.

## What's inside an Artifact

At its heart, an Artifact exposes a Python function you can call to run the whole object end to end - starting from your input tables and producing the final result. Alongside that logic, the bundle carries the metadata and version details needed to reproduce the object's behavior exactly.

A bundle broadly contains:

<table class="attr-table">
  <thead>
    <tr><th>File</th><th>What it holds</th></tr>
  </thead>
  <tbody>
    <tr>
      <td class="field-cell"><code>metadata.json</code></td>
      <td>Information about the object in the bundle - its inputs, version, group, permissible purpose, and other registered details.</td>
    </tr>
    <tr>
      <td class="field-cell"><code>input_info.json</code></td>
      <td>The input tables and columns the object expects, so you know exactly what to feed the <code>main()</code> function.</td>
    </tr>
    <tr>
      <td class="field-cell"><code>python_dict/</code></td>
      <td>The Python-dictionary version of the logic, for low-latency runs. Contains the runnable code (<code>__init__.py</code>) and a <code>versions.json</code> listing the library versions used.</td>
    </tr>
    <tr>
      <td class="field-cell"><code>pyspark_dataframe/</code></td>
      <td>The PySpark version of the same logic, for running on large data. Also contains <code>__init__.py</code> and its own <code>versions.json</code>.</td>
    </tr>
  </tbody>
</table>

Because the Artifact pins the exact versions of every dependency it was built with, a production run stays reproducible - what you approved is exactly what runs.

## How to run an Artifact

The Artifact ships with two ways to run the same logic. Both expose a `main()` function - you pick the one that fits your data and environment:

- **`python_dict`** - for low-latency runs. You send data as a Python dictionary. Best for scoring one record or a small batch quickly.
- **`pyspark_dataframe`** - for large data. You send data as a Spark DataFrame. Best for running over big tables at scale.

Whichever you use, the call is the same. You pass your input tables to `main()`, and it returns two things: the output data and an errors callback.

```python
out_data, out_errs = main(in_data, runtime_params={})
errors = out_errs()          # call the callback to get any runtime errors
result = out_data['final_data']
```

:::note[Two ways to import]
After you unpack the bundle, you can either run from inside the engine folder (`cd` into `python_dict/`, then `from __init__ import main`), or add the bundle folder to your path and import the folder as a package (`from python_dict import main`). The examples below use the second style.
:::

The keys in `in_data` are the input table references (for example, `data_table_8`). You will find the exact references your object expects in the bundle's `input_info.json`.

### Running with a Python dictionary

Send each input table as a dictionary of columns, where every column carries its `type` and `values`.

```python
import sys
sys.path.insert(0, 'policy_2.15/')      # the bundle folder, named <object>_<id>.<bundle_id>

from python_dict import main

in_data = {
    'data_table_8': {
        'id': {'type': 'str', 'values': ['1750036']},
        'annual_income': {'type': 'float', 'values': [50000.0]},
        'fico': {'type': 'float', 'values': [676.0]},
        'requested_amount': {'type': 'float', 'values': [30000.0]},
        'create_time': {'type': 'str', 'values': ['2019-06-29 04:34:00']},
        'state': {'type': 'str', 'values': ['TX']},
        # ...
    }
}

out_data, out_errs = main(in_data, runtime_params={})
errors = out_errs()
if len(dict(errors).get('errors', [])) > 0:
    print("Runtime error occurred while running policy:")
    print(str(errors))
else:
    print("Policy Output:")
    print(out_data['final_data'])
```

### Running with a Spark DataFrame

Send each input table as a Spark DataFrame. This is the option to use when the data is too large to hold in memory.

```python
import sys
sys.path.insert(0, 'policy_2.15/')      # the bundle folder, named <object>_<id>.<bundle_id>

from pyspark_dataframe import main

in_data = {
    'data_table_8': spark.read.parquet("/data/application_jan2020.parquet")
}

out_data, out_errs = main(in_data, runtime_params={})
errors = out_errs()
if len(dict(errors).get('errors', [])) > 0:
    print("Runtime error occurred while running policy:")
    print(str(errors))
else:
    print("Policy Output:")
    print(out_data['final_data'])          # a Spark DataFrame
```

## How to export an Artifact

<details open class="step">
<summary>

#### Open the Object

</summary>

1. Open the module the object lives in - **Underwriting**, for example.
2. Open the object you want to export (a Policy, Model, Feature, or Data Element).

</details>

<details open class="step">
<summary>

#### Choose an Export Option

</summary>

1. Open the object's actions menu and click **Export Artifact**.
2. A dialog opens with a card for each export option available in your environment.
3. Pick the option you want, then click **Export** to download the bundle.

The list of options depends on how your Corridor environment is set up. Common ones include:

- **Python Artifact** - the standard bundle with the `python_dict` and `pyspark_dataframe` code, ready to run in your own Python environment.
- **Bureau packages** (for example, **TransUnion**, **Experian**, **Equifax**) - packaged for submission to that credit bureau.
- **Cloud deployment** (for example, **GCP Cloud Run**, **AWS Lambda**) - packaged to deploy the object as a cloud service.

:::note[Not seeing an option?]
The available options are configured per Corridor environment. If an option you expect is missing, check with your administrator.
:::

</details>

Each option shows its own next steps after the download, guiding you through unpacking and running or deploying the bundle.

:::note[Approved objects]
Once an object is **Approved**, Corridor keeps a finalized Artifact ready. Exporting an approved object downloads that stored bundle rather than building a new one.
:::

## What's Next

- [Approve an Object](/user-guide/how-tos/approve-an-object/): approving an object finalizes the Artifact that ships to production.
- [Monitor your Model or Policy](/user-guide/how-tos/monitor-model-policy/) once the Artifact is running in production.
