Skip to content
Back to skills

577 Project Structure A6d861a8

ASecurity

| Pattern | When to Use | | ---------------------------- | --------------------------------------------------------- | | Single code location | Small to medium projects, single team | | Multiple code locations | Large organizations, isolated dependencies | | Components | Standardized, repeatable patterns with declarative config | | Pythonic assets + Components | Mi

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
developmentpythongobashsqltestinggitapidatabasedocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 577-project-structure_a6d861a8 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 577 Project Structure A6d861a8?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 577 Project Structure A6d861a8
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-577-project-structure-a6d861a8/badge)](https://www.skillsdirectory.com/skills/tools-only-577-project-structure-a6d861a8)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Project Structure Reference

## Pattern Summary

| Pattern                      | When to Use                                               |
| ---------------------------- | --------------------------------------------------------- |
| Single code location         | Small to medium projects, single team                     |
| Multiple code locations      | Large organizations, isolated dependencies                |
| Components                   | Standardized, repeatable patterns with declarative config |
| Pythonic assets + Components | Mix custom logic with standardized integrations           |
| Organize by technology       | Team focused on specific tech stacks                      |
| Organize by concept          | Business-context clarity across organization              |
| Module-based organization    | Domain-driven project structure                           |

**Modern Recommendation**: Use `create-dagster` with auto-discovery for new projects. Combine
components with pythonic assets using `Definitions.merge()`.

---

## Recommended Project Layout

### Standard Layout

```
my_project/
├── pyproject.toml              # Dependencies and dg config
├── src/
│   └── my_project/
│       ├── __init__.py
│       ├── definitions.py      # Main Definitions entry point
│       └── defs/
│           ├── __init__.py
│           ├── assets/
│           │   ├── __init__.py
│           │   ├── constants.py
│           │   ├── ingestion.py
│           │   └── analytics.py
│           ├── jobs.py
│           ├── schedules.py
│           ├── sensors.py
│           ├── partitions.py
│           └── resources.py
├── data/
│   ├── source/
│   ├── staging/
│   └── outputs/
└── tests/
    ├── __init__.py
    ├── conftest.py
    └── test_assets.py
```

### With Components

```
my_project/
├── pyproject.toml
├── src/
│   └── my_project/
│       ├── definitions.py
│       └── defs/
│           ├── dashboard/          # Component: Looker integration
│           │   └── defs.yaml
│           ├── ingest_files/       # Component: Sling replication
│           │   ├── defs.yaml
│           │   └── replication.yaml
│           └── transform/          # Component: dbt project
│               └── defs.yaml
└── tests/
```

---

## Definitions Object

The `Definitions` object is the entry point for all Dagster objects.

### Modern Autoloading Pattern (Recommended)

**Simple Auto-Discovery**:

```python
# src/my_project/definitions.py
from dagster import Definitions
from dagster_dg import load_defs

# Automatically discovers all definitions in defs/ folder
defs = Definitions.merge(
    load_defs()
)
```

**Combining Components with Pythonic Assets**:

```python
# src/my_project/definitions.py
from dagster import Definitions
from dagster_dg import load_defs
from my_project.assets import custom_assets

# Load component definitions from defs/
component_defs = load_defs()

# Define pythonic assets separately
pythonic_defs = Definitions(
    assets=custom_assets,
    resources={...}
)

# Merge them together
defs = Definitions.merge(component_defs, pythonic_defs)
```

**Benefits**:

- Automatically loads all components from `defs/` directory
- Zero boilerplate when adding new components
- Clean separation between components and custom assets
- Flexible resource sharing across both patterns

### Explicit Definitions Pattern

```python
# src/my_project/definitions.py
import dagster as dg

from my_project.defs.assets import ingestion, analytics
from my_project.defs.jobs import daily_job, weekly_job
from my_project.defs.schedules import daily_schedule
from my_project.defs.resources import database_resource

defs = dg.Definitions(
    assets=[
        *ingestion.assets,
        *analytics.assets,
    ],
    jobs=[daily_job, weekly_job],
    schedules=[daily_schedule],
    resources={"database": database_resource},
)
```

### Resource Definitions Pattern

```python
# src/my_project/defs/resources.py
import dagster as dg
from dagster_duckdb import DuckDBResource

database_resource = DuckDBResource(
    database=dg.EnvVar("DUCKDB_DATABASE")
)

@dg.definitions
def resources():
    return dg.Definitions(
        resources={
            "database": database_resource,
        }
    )
```

---

## Code Locations

### What is a Code Location?

A code location is:

1. A Python module containing a `Definitions` object
2. A Python environment that can load that module

### When to Use Multiple Code Locations

| Use Case                      | Benefit                                    |
| ----------------------------- | ------------------------------------------ |
| Different teams               | Independent deployments, isolated failures |
| Different Python versions     | Legacy code alongside modern code          |
| Different dependency versions | PyTorch v1 vs v2, pandas versions          |
| Compliance separation         | HIPAA, PCI data isolation                  |
| Functional separation         | ETL vs ML vs BI layers                     |

### Code Location Configuration

```yaml
# workspace.yaml
load_from:
  - python_module: my_project.definitions
  - python_module: ml_project.definitions
  - python_module: etl_project.definitions
```

### Benefits of Code Locations

- **Isolation**: Failures in one location don't affect others
- **Independent deployment**: Teams deploy without coordination
- **Dependency flexibility**: Different packages per location
- **Single pane of glass**: All assets visible in one UI
- **Cross-location dependencies**: Assets can depend across locations

---

## Creating and Scaffolding Projects

Use the `dg` CLI to create projects and scaffold Dagster objects. For detailed scaffolding commands and options, see the [CLI scaffold reference](./cli/scaffold.md).

**Quick reference:**

```bash
# Create new project
uvx create-dagster my_project

# Scaffold objects (see dg skill for full details)
dg scaffold defs dagster.asset assets/new_asset.py

# Validate and run
dg check defs
dg dev
```

---

## Configuration Files

### pyproject.toml (Python Package + dg Config)

```toml
[project]
name = "my_project"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
    "dagster>=1.8.0",
    "dagster-duckdb",
    "dagster-dbt",
    "dagster-sling",
]

[project.optional-dependencies]
dev = [
    "dagster-webserver",
    "pytest",
]

[tool.dg]
directory_type = "project"

[tool.dg.project]
root_module = "my_project"
registry_modules = [
    "dagster.components.*",      # Built-in components (dbt, Sling, etc.)
    "my_project.components.*",   # Custom components
]
```

**Key Settings**:

- `directory_type`: "project" for dg-managed projects
- `root_module`: Python module containing definitions.py
- `registry_modules`: Where to discover components

### dg.toml (Workspace Configuration)

For managing multiple Dagster projects together:

```toml
# dg.toml (at workspace root)
[workspace]
projects = [
    "etl_project",
    "ml_project",
    "analytics_project",
]
```

**Use Cases**:

- Multiple teams with separate projects
- Shared dependencies across projects
- Organization-wide development
- Conflicting dependency requirements

### dagster.yaml (Instance Configuration)

```yaml
# dagster.yaml (at project root or ~/.dagster)
run_launcher:
  module: dagster.core.launcher
  class: DefaultRunLauncher

run_storage:
  module: dagster.core.storage.runs
  class: SqliteRunStorage
  config:
    base_dir: /var/dagster/storage

event_log_storage:
  module: dagster.core.storage.event_log
  class: SqliteEventLogStorage
  config:
    base_dir: /var/dagster/storage

schedule_storage:
  module: dagster.core.storage.schedules
  class: SqliteScheduleStorage
  config:
    base_dir: /var/dagster/storage
```

**Purpose**: Configure Dagster instance behavior (storage, compute, scheduling)

**Common Uses**:

- Storage configuration (SQLite, PostgreSQL)
- Run launcher settings (local, K8s, etc.)
- Compute log storage
- Scheduler configuration

---

## Components

**What are Components?** Reusable, declarative building blocks that generate `Definitions` from
configuration (YAML). Components standardize repetitive patterns and integrations without writing
Python code.

### When to Use Components

| Use Case                   | Example                                 |
| -------------------------- | --------------------------------------- |
| Standardized ETL patterns  | Multiple similar Sling replication jobs |
| External tool integration  | dbt, Sling, Fivetran                    |
| Repeatable patterns        | API ingestion with consistent structure |
| Non-engineer contributions | Analysts defining pipelines via config  |
| Reducing code duplication  | Same pattern repeated across teams      |

**Don't Use Components When**:

- Custom logic is complex and doesn't fit a template
- Pattern is used only once
- You need fine-grained control over execution

### Component Types

**Built-in Components** (from Dagster):

- `dagster_dbt.DbtProjectComponent`: dbt project integration
- `dagster_sling.SlingReplicationComponent`: Database replication
- Additional components for Fivetran, Airbyte, etc.

**Custom Components**: Create organization-specific patterns

### Component Structure

```
defs/
├── ingest_postgres/        # Component instance
│   ├── defs.yaml           # Component configuration
│   └── replication.yaml    # Additional config files
├── transform_dbt/
│   └── defs.yaml
└── shared_resources/       # Optional: shared resources
    └── defs.py
```

### Sling Component Example

```yaml
# defs/ingest_postgres/defs.yaml
component: dagster_sling.SlingReplicationComponent

params:
  replication_config: replication.yaml
  sling:
    connections:
      - name: MY_POSTGRES
        type: postgres
        host: localhost
        port: 5432
        database: source_db
      - name: MY_DUCKDB
        type: duckdb
        connection_string: "duckdb:///data/staging/data.duckdb"
```

```yaml
# defs/ingest_postgres/replication.yaml
source: MY_POSTGRES
target: MY_DUCKDB

defaults:
  mode: full-refresh

streams:
  data.customers:
  data.products:
  data.orders:
```

### dbt Component Example

**Remote Git Repository (Recommended)**:

```yaml
# defs/transform/defs.yaml
type: dagster_dbt.DbtProjectComponent

attributes:
  project:
    repo_url: https://github.com/dagster-io/jaffle-platform.git
    repo_relative_path: jdbt
  dbt:
    target: dev
```

The remote configuration manages the dbt project as component state without requiring you to clone
the repository locally.

**For private repositories**, add token authentication:

```yaml
attributes:
  project:
    repo_url: https://github.com/your-org/dbt-project.git
    repo_relative_path: dbt
    token: "{{ env.GIT_TOKEN }}"
  dbt:
    target: dev
```

**Local Project (Alternative for Development)**:

```yaml
# defs/transform/defs.yaml
type: dagster_dbt.DbtProjectComponent

attributes:
  project:
    project_dir: ../../dbt_project
  dbt:
    target: dev
    profiles_dir: ~/.dbt
```

Use local configuration when actively developing dbt models or when the dbt project is colocated in
your Dagster repository.

### Combining Components with Pythonic Assets

```python
# src/my_project/definitions.py
from dagster import Definitions
from dagster_dg import load_defs

# Load component definitions
component_defs = load_defs()

# Define custom pythonic assets
from my_project.assets import custom_pipeline

pythonic_defs = Definitions(
    assets=[custom_pipeline],
    resources={...}
)

# Merge: components AND custom assets in one project
defs = Definitions.merge(component_defs, pythonic_defs)
```

### Component Best Practices

1. **Single Responsibility**: Each component handles one integration or pattern
2. **Typed Configuration**: Use structured YAML for validation
3. **Documentation**: Document component parameters and examples
4. **Testing**: Validate component configurations before deployment
5. **Versioning**: Pin component versions for stability
6. **Resource Sharing**: Share resources across components and pythonic assets

---

## Module Organization

### Domain-Based Organization

```
defs/
├── assets/
│   ├── ingestion/      # Raw data ingestion
│   │   ├── __init__.py
│   │   ├── files.py
│   │   └── apis.py
│   ├── staging/        # Data cleaning
│   │   ├── __init__.py
│   │   └── transformations.py
│   └── analytics/      # Business metrics
│       ├── __init__.py
│       └── reports.py
├── jobs.py
├── schedules.py
└── resources.py
```

### Layer-Based Organization

```
defs/
├── bronze/            # Raw data layer
│   ├── __init__.py
│   └── ingestion.py
├── silver/            # Cleaned data layer
│   ├── __init__.py
│   └── cleaning.py
├── gold/              # Business layer
│   ├── __init__.py
│   └── metrics.py
└── automation/
    ├── jobs.py
    ├── schedules.py
    └── sensors.py
```

---

## Environment Configuration

### Environment Variables

```bash
# .env (not committed to git)
DUCKDB_DATABASE=data/staging/data.duckdb
SNOWFLAKE_ACCOUNT=myaccount
SNOWFLAKE_USER=myuser
SNOWFLAKE_PASSWORD=secret
```

### Loading in Dagster

```python
import dagster as dg

resource = MyResource(
    database=dg.EnvVar("DUCKDB_DATABASE"),
    api_key=dg.EnvVar("API_KEY"),
)
```

### Environment-Specific Config

```python
import os

if os.getenv("DAGSTER_ENV") == "production":
    database_path = "/data/prod/data.duckdb"
else:
    database_path = "data/staging/data.duckdb"
```

---

## Reloading Definitions

### When to Reload

Reload definitions when:

- Adding new assets, jobs, schedules, or sensors
- Modifying decorator arguments (`@dg.asset(...)`)
- Changing Definitions object

**Not required** when:

- Editing asset function logic (with `-e` install)
- Updating SQL queries inside assets
- Changing resource method implementations

### How to Reload

**UI**: Click "Reload Definitions" button

**CLI**:

```bash
dagster dev  # Restart for full reload
```

---

## Anti-Patterns to Avoid

| Anti-Pattern                 | Better Approach                    |
| ---------------------------- | ---------------------------------- |
| All assets in one file       | Organize by domain/layer           |
| Hardcoded paths              | Use constants or EnvVar            |
| No definitions validation    | Run `dg check defs` in CI          |
| Mixing production/dev config | Use environment variables          |
| Monolithic code location     | Split by team/function as you grow |

---

## References

- [Project Structure](https://docs.dagster.io/guides/build/project-structure)
- [Code Locations](https://docs.dagster.io/guides/deploy/code-locations)
- [Components Guide](https://docs.dagster.io/guides/build/components)
- [dg CLI Reference](https://docs.dagster.io/api/clis/dg-cli/dg-cli-reference)

Files in this skill

  • README.md947 B
  • skill.md14.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.