pathstruct 0.1.0
Static definition of directory and file structure to avoid hard-coding file paths
License: MIT
Requires Python: >=3.8
Keywords: file, path, directory, tree, structure, static

# PathStruct

A Python library for statically defining and managing file path structures. Define file and directory structures using type annotations, and visualize them as trees or manage paths.

## Features

- 📁 **Type-based structure definition**: Define file/directory structures using class annotations
- 🌳 **Tree visualization**: Visualize defined structures as trees
- ✅ **Existence checking**: Display file/directory existence with colors
- 🔗 **Path management**: Convenient path access through `pathlib.Path` objects

## Why PathStruct?

When working with complex file structures, hardcoding paths throughout your codebase leads to maintenance nightmares. PathStruct solves this by allowing you to define your file structure once, statically, and reuse it everywhere.

### Benefits

- **🛡️ Type Safety**: Get autocomplete and type checking for all your paths. No more typos or runtime errors from incorrect path strings.
- **📝 Single Source of Truth**: Define your file structure once in a class definition, and reference it consistently across your entire project.
- **🔍 Better Developer Experience**: IDE autocomplete works perfectly with your path structure, making development faster and less error-prone.
- **🧹 Cleaner Code**: Replace scattered string literals like `"data/config/settings.yaml"` with structured access like `root.data.config.settings_yaml.path`.

### Example: Before vs After

**Before (hardcoded paths):**
```python
config_path = os.path.join(base_dir, "config", "settings.yaml")
log_path = os.path.join(base_dir, "logs", "app.log")
# Easy to make mistakes, no autocomplete, hard to refactor
```

**After (with PathStruct):**
```python
class Project(Root):
    config: Config
    logs: Dir

root = Project(name=base_dir)
config_path = root.config.settings_yaml.path  # Autocomplete works!
log_path = root.logs.app_log.path  # Type-safe and refactor-friendly
```

## Installation

### Development mode installation

```bash
pip install -e .
```

### Build distribution package

```bash
pip install build
python -m build
```

### Deploy to PyPI

```bash
pip install twine
python -m build
twine upload dist/*
```

## Usage

### Basic usage example

```python
from pathstruct import Root, Dir, File

# Define structure
class Config(Dir):
    """Configuration directory."""
    config_yaml: File

class Dataset(Dir):
    """Dataset directory."""
    log_json: File
    images: Dir

class Resource(Root):
    """Resource root directory."""
    config: Config
    dataset: Dataset
    readme_txt: File

# Create instance
root = Resource(name="/path/to/resource")

# Access paths
print(root.config.config_yaml.path)
# Output: /path/to/resource/config/config.yaml

# Print tree (with existence check)
root.print_tree(check_exist=True)

# Print tree (without colors)
root.print_tree(check_exist=False)
```

### File extension naming convention

File fields must be named in the `filename_extension` format:

- ✅ `config_yaml` → `config.yaml`
- ✅ `readme_txt` → `readme.txt`
- ✅ `log_json` → `log.json`
- ❌ `config` (warning will be issued)

### Tree output example

```
/path/to/resource/
├── config/
│   └── config.yaml
├── dataset/
│   ├── log.json
│   └── images/
└── readme.txt
```

Existing files/directories are displayed in green, non-existing ones in red.

## API Documentation

### Classes

#### `Element`
Base class for all file/directory elements.

#### `Dir`
Class representing a directory.

#### `Root`
Class representing a root directory. Inherits from `Dir`.

#### `File`
Class representing a file. Includes extension support.

### Key Methods

#### `Element.print_tree(prefix="", is_last=True, check_exist=True)`
Print directory/file structure in tree format.

**Parameters:**
- `prefix`: Prefix for tree output (for indentation)
- `is_last`: Whether this is the last child node
- `check_exist`: Whether to check file/directory existence and display with colors

#### `Element.path`
Returns the full path of the element as a `pathlib.Path` object.

## Running Examples

```bash
python -m pathstruct.examples.example
```

## Requirements

- Python 3.8 or higher
- Uses only standard library (no external dependencies)

## License

MIT License

## Contributing

Issues and pull requests are welcome!