> ## Documentation Index
> Fetch the complete documentation index at: https://anaconda.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ProjectFlow

export const GCell = ({children, className}) => <div className={`grid-table-cell ${className || ""}`} role="cell">
    {children}
  </div>;

export const GTH = ({children, className}) => <div className={`grid-table-th ${className || ""}`} role="columnheader">
    {children}
  </div>;

export const GRow = ({children}) => <div className="grid-table-row" role="row">{children}</div>;

export const GBody = ({children}) => <div className="grid-table-body" role="rowgroup">{children}</div>;

export const GHead = ({children}) => <div className="grid-table-head" role="rowgroup">{children}</div>;

export const GTable = ({children, className, cols}) => <div className={`grid-table not-prose overflow-hidden rounded-2xl ${className || ""}`} style={{
  "--grid-table-cols": cols
}} role="table">
    {children}
  </div>;

Inherit from `ProjectFlow` instead of Metaflow's `FlowSpec`:

```python theme={null}
from obproject import ProjectFlow

class MyFlow(ProjectFlow):
    @step
    def start(self):
        self.prj.register_data("dataset", "data")
        self.next(self.end)
```

### Configuration

ProjectFlow reads configuration from two files:

**`obproject.toml`**: Project identity and settings.

```toml theme={null}
project = "fraud-detection"

[dev-assets]
branch = "main"  # Read assets from main branch during local dev

[dependencies]
include_pyproject_toml = true  # Auto-apply pyproject.toml deps (default: true)
```

<GTable cols="13% 19% 19% 49%">
  <GHead>
    <GRow>
      <GTH>Section</GTH>
      <GTH>Key</GTH>
      <GTH>Default</GTH>
      <GTH>Description</GTH>
    </GRow>
  </GHead>

  <GBody>
    <GRow>
      <GCell>(top-level)</GCell>
      <GCell>`cicd_user`</GCell>
      <GCell>`"${project//_/-}-cicd"`</GCell>
      <GCell>Override the machine-user name CI uses when calling `outerbounds service-principal-configure`. See [CI/CD integration](/docs/platform/guides/deploy/cicd-integration#machine-user-naming-convention) for the convention.</GCell>
    </GRow>

    <GRow>
      <GCell>`[dev-assets]`</GCell>
      <GCell>`branch`</GCell>
      <GCell>—</GCell>
      <GCell>Branch to read assets from during local development</GCell>
    </GRow>

    <GRow>
      <GCell>`[dependencies]`</GCell>
      <GCell>`include_pyproject_toml`</GCell>
      <GCell>`true`</GCell>
      <GCell>Auto-apply `@pypi_base` from pyproject.toml</GCell>
    </GRow>
  </GBody>
</GTable>

**`pyproject.toml`**: Python dependencies applied through `@pypi_base`.

```toml theme={null}
[project]
dependencies = [
    "scikit-learn>=1.3.0",
    "pandas>=2.0.0",
]
```

### prj property

`self.prj` returns a `ProjectContext` with access to all project utilities. It is initialized lazily on first access.

<ResponseField name="prj.project" type="string">
  The project name from the project configuration.
</ResponseField>

<ResponseField name="prj.branch" type="string">
  The current write branch, from Metaflow `@project`.
</ResponseField>

<ResponseField name="prj.read_branch" type="string">
  The branch used for reading assets. Can differ from `prj.write_branch` during local development with `[dev-assets]` configured.
</ResponseField>

<ResponseField name="prj.write_branch" type="string">
  The branch used for writing assets.
</ResponseField>

<ResponseField name="prj.asset" type="string">
  The low-level asset client.
</ResponseField>

<ResponseField name="prj.evals" type="string">
  The evaluation logger.
</ResponseField>
