> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# Linux Deployment Code Examples

> Prepare the AdventureWorks sample data and build its graph for local modeling examples

Prepare AdventureWorks data to explore Kumo's local modeling workflow on Linux.
It contains customers, products, order headers, and order details.

The [Train a Classification Model](/kumo-engine/1.0.0/user-code-guide/code-examples/linux-deployment/train-a-classification-model) tab uses
IBM's synthetic AML transaction data instead. Its instructions name the three
LI-Medium source files and prepare them separately; the AdventureWorks bundle
below applies to the other Linux examples.

## Prepare the Input Files

Complete [Linux Machine Deployment Setup](/kumo-engine/1.0.0/get-started-with-kumo-engine/installation/linux-machine-deployment) and activate the same Python environment.
Keep `KUMO_SCRATCH` set to your writable directory on local storage.

Download the Linux examples bundle, containing the data preparation scripts, task scripts, checksums, and a README.
The bundle contains no Kumo packages, datasets, models, or credentials.

Download Linux examples

From the directory where you saved the ZIP, extract it and verify its files:

```bash
python -m zipfile -e linux-local-examples.zip .
cd linux-local-examples
sha256sum -c SHA256SUMS
```

Every file should report `OK`. The checksums detect changed files; they do not authenticate the publisher.

The downloader reads the official AdventureWorks OLTP extracts from Microsoft's
`sql-server-samples` repository and verifies their pinned SHA-256 hashes.
It uses the Python standard library and does not configure a Kumo connector.

Choose two new, separate directories. Replace the paths with your source-download and prepared-input locations:

```bash
export ADVENTUREWORKS_SOURCE=/path/to/adventureworks-source
export ADVENTUREWORKS_DATA=/path/to/adventureworks-inputs
python download_adventureworks.py "$ADVENTUREWORKS_SOURCE"
python prepare_adventureworks.py \
  "$ADVENTUREWORKS_SOURCE" "$ADVENTUREWORKS_DATA"
```

The downloader verifies the four files against fixed SHA-256 checksums before accepting the download.
It refuses an existing destination and reports access, network, or checksum failures without replacing prior files.
The preparation script checks schemas and relationships, then creates independent copies.
The graph example below reads those local copies.

The prepared directory contains these files:

| File                   | Required Columns                                                                                                      |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Customer.csv`         | `CustomerID`, `StoreID`, `TerritoryID`                                                                                |
| `Product.csv`          | `ProductID`, `Name`, `Color`, `ProductLine`, `Class`, `StandardCost`, `ListPrice`                                     |
| `SalesOrderHeader.csv` | `SalesOrderID`, `CustomerID`, `OrderDate`, `OnlineOrderFlag`, `TerritoryID`, `SubTotal`, `TotalDue`                   |
| `SalesOrderDetail.csv` | `SalesOrderDetailID`, `SalesOrderID`, `CustomerID`, `ProductID`, `ModifiedDate`, `OrderQty`, `UnitPrice`, `LineTotal` |

Customer, product, order, and order-detail primary keys must be nonempty and unique.
Order headers reference customers.
The preparation script copies the validated header customer identifier onto each order detail.
Order details reference customers, order headers, and products.
Dates are timezone-free values.

Keep `ADVENTUREWORKS_DATA` set to the prepared directory for the graph and task examples.

Keep the source files unchanged while running the example.
The procedure below builds a snapshot from their current contents.

## Build the AdventureWorks Graph

Run the following Python blocks in order in one process after setting `ADVENTUREWORKS_DATA` and `KUMO_SCRATCH`.
Keep input and scratch directories separate.
For the API concepts, see [Tables](/kumo-engine/1.0.0/user-code-guide/set-up-a-graph/tables) and [Graphs](/kumo-engine/1.0.0/user-code-guide/set-up-a-graph/graphs).

The two order tables use explicit date types. The walkthrough treats
`SalesOrderDetail.ModifiedDate` as the detail availability time.

```python
import os
from pathlib import Path

from kumo.engine import FileConnector, Graph, Table, configure
from kumoapi.graph import Edge
from kumoapi.typing import Dtype, Stype

input_dir = Path(os.environ["ADVENTUREWORKS_DATA"]).expanduser().resolve()
scratch_dir = Path(os.environ["KUMO_SCRATCH"]).expanduser().resolve()
configure(scratch_dir=scratch_dir)
connector = FileConnector(root_dir=str(input_dir))

customer = Table.from_source_table(
    connector["Customer"], ["CustomerID", "StoreID", "TerritoryID"],
    primary_key="CustomerID",
)
customer = customer.with_column("StoreID", stype=Stype.categorical)
customer = customer.with_column("TerritoryID", stype=Stype.categorical)
product = Table.from_source_table(
    connector["Product"],
    ["ProductID", "Name", "Color", "ProductLine", "Class", "StandardCost", "ListPrice"],
    primary_key="ProductID",
)
product = product.with_column("Name", stype=Stype.text)
for column in ["Color", "ProductLine", "Class"]:
    product = product.with_column(column, stype=Stype.categorical)
for column in ["StandardCost", "ListPrice"]:
    product = product.with_column(column, stype=Stype.numerical)
sales_order_header = Table.from_source_table(
    connector["SalesOrderHeader"],
    ["SalesOrderID", "CustomerID", "OrderDate", "OnlineOrderFlag", "TerritoryID", "SubTotal", "TotalDue"],
    primary_key="SalesOrderID", time_column="OrderDate",
)
sales_order_header = sales_order_header.with_column("CustomerID", stype=Stype.ID)
sales_order_header = sales_order_header.with_column("OrderDate", dtype=Dtype.date)
sales_order_header = sales_order_header.with_column("OnlineOrderFlag", stype=Stype.categorical)
sales_order_header = sales_order_header.with_column("TerritoryID", stype=Stype.categorical)
sales_order_header = sales_order_header.with_column("SubTotal", stype=Stype.numerical)
sales_order_header = sales_order_header.with_column("TotalDue", stype=Stype.numerical)
sales_order_detail = Table.from_source_table(
    connector["SalesOrderDetail"],
    ["SalesOrderDetailID", "SalesOrderID", "CustomerID", "ProductID", "ModifiedDate", "OrderQty", "UnitPrice", "LineTotal"],
    primary_key="SalesOrderDetailID", time_column="ModifiedDate",
)
sales_order_detail = sales_order_detail.with_column("SalesOrderID", stype=Stype.ID)
sales_order_detail = sales_order_detail.with_column("CustomerID", stype=Stype.ID)
sales_order_detail = sales_order_detail.with_column("ProductID", stype=Stype.ID)
sales_order_detail = sales_order_detail.with_column("ModifiedDate", dtype=Dtype.date)
sales_order_detail = sales_order_detail.with_column("OrderQty", stype=Stype.numerical)
sales_order_detail = sales_order_detail.with_column("UnitPrice", stype=Stype.numerical)
sales_order_detail = sales_order_detail.with_column("LineTotal", stype=Stype.numerical)
```

Connect the four tables and materialize the snapshot:

```python
graph = Graph(
    tables=[customer, product, sales_order_header, sales_order_detail],
    edges=[
        Edge(
            src_table="SalesOrderHeader", fkey="CustomerID", dst_table="Customer"
        ),
        Edge(
            src_table="SalesOrderDetail",
            fkey="SalesOrderID",
            dst_table="SalesOrderHeader",
        ),
        Edge(
            src_table="SalesOrderDetail", fkey="CustomerID", dst_table="Customer"
        ),
        Edge(
            src_table="SalesOrderDetail", fkey="ProductID", dst_table="Product"
        ),
    ],
)
graph.validate()
snapshot = graph.snapshot()

print("Tables:", [table.table_name for table in graph.tables])
print("Snapshot:", snapshot.id)
print("Index directory:", snapshot.index_path)
```

Expect `Customer`, `Product`, `SalesOrderHeader`, and `SalesOrderDetail` in the table list.
The completed call returns a snapshot ID and local index directory.
Keep `graph`, `snapshot`, and `input_dir` available when continuing in the same Python process.
For unchanged files, a repeated snapshot request should reuse the same index:

```python
repeated = graph.snapshot()
assert repeated.id == snapshot.id
assert repeated.index_path == snapshot.index_path
```

## Resolve Data Preparation Problems

| Symptom                                          | Action                                                                                                                       |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| Download reports an access failure               | Check network access to the Microsoft `sql-server-samples` repository.                                                       |
| Checksum mismatch                                | Obtain the matching sample version; do not bypass the checksum check.                                                        |
| Download destination exists                      | Choose a new directory so previous files remain intact.                                                                      |
| Preparation rejects the schema or a relationship | Check the expected columns, unique keys, and referenced IDs before retrying. Do not construct a relationship from row order. |
| Local source file is missing or unreadable       | Check `ADVENTUREWORKS_DATA`, filename casing, file permissions, and directory access.                                        |
| Date ingestion fails                             | Keep the original date values and explicit `Dtype.date` declarations.                                                        |

## Continue to Modeling

Use [Predictive Queries](/kumo-engine/1.0.0/user-code-guide/train-a-model/predictive-queries) to choose a target and generate training rows, then [Training](/kumo-engine/1.0.0/user-code-guide/train-a-model/training) to fit a model.
This example focuses on the workflow. Evaluate model quality on data and metrics that represent your use case.

Use [Making Predictions](/kumo-engine/1.0.0/user-code-guide/making-predictions) and [Publish and Retrieve Models](/kumo-engine/1.0.0/user-code-guide/train-a-model/publish-and-retrieve-models) to inspect and save outputs, retain model bundles, and load them in another process.