Break large Python files (>500 LOC) into smaller, well-organized modules with proper package structure. Use when a Python file is too large, monolithic, or needs refactoring. Triggered by requests mentioning "too large", "separate", "split", "break up", or "refactor" for Python files.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
npx agent-skills-cli listSkill Instructions
name: separate-monolithic-python description: Break large Python files (>500 LOC) into smaller, well-organized modules with proper package structure. Use when a Python file is too large, monolithic, or needs refactoring. Triggered by requests mentioning "too large", "separate", "split", "break up", or "refactor" for Python files.
Separate Monolithic Python Code
Break large Python files into maintainable modules following Python best practices.
Workflow
Step 1: Analyze
- Read entire file to understand structure
- Identify components (classes, function groups, constants)
- Count lines (>500 LOC needs separation)
- Map dependencies (what depends on what)
Step 2: Plan Structure
Choose a separation pattern:
By Responsibility (Recommended):
mypackage/
├── __init__.py # Public API exports
├── models.py # Data models/classes
├── services.py # Business logic
├── utils.py # Helper functions
└── constants.py # Configuration
By Feature:
mypackage/
├── __init__.py
├── feature_a/
│ ├── __init__.py
│ ├── models.py
│ └── logic.py
└── feature_b/
By Layer (Domain-driven):
mypackage/
├── __init__.py
├── domain/ # Core models
├── application/ # Use cases
└── infrastructure/ # External deps
Present plan to user before proceeding.
Step 3: Create Structure
mkdir mypackage
touch mypackage/__init__.py mypackage/models.py mypackage/services.py
Step 4: Extract Code
Extract in dependency order:
- Constants (no dependencies)
- Models (minimal dependencies)
- Utilities (depend on constants/models)
- Services (depend on everything)
- Main (orchestrate all)
Step 5: Update Imports
In new modules:
# models.py
from .constants import DEFAULT_ROLE
from .utils import validate_email
In __init__.py (public API):
from .models import User, Product
from .services import create_user
__all__ = ['User', 'Product', 'create_user']
In external files:
# Before: from monolith import User
# After: from mypackage import User
Step 6: Validate
ruff check mypackage/
mypy mypackage/
python -c "from mypackage import User"
pytest tests/
Key Principles
High Cohesion: Keep related code together
- Group by purpose, not type
- Example:
user_service.pynotall_services.py
Low Coupling: Minimize dependencies
- Avoid circular imports
- Use dependency injection
Single Responsibility: One clear purpose per module
Clear API: Use __init__.py to expose public interface
Handling Circular Dependencies
Option 1: Move shared code
# Create shared.py for common code
Option 2: TYPE_CHECKING
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .services import UserService # Only for type hints
Option 3: Late import
def process_user():
from .services import create_user # Import inside function
create_user()
File Size Guidelines
- ✅ Ideal: 100-300 lines
- ⚠️ Warning: 300-500 lines (consider splitting)
- ❌ Too large: >500 lines (should split)
Quick Example
Before (monolith.py - 800 lines):
DATABASE_URL = "sqlite:///./test.db"
class User:
def __init__(self, name):
self.name = name
def create_user(name):
return User(name)
app = FastAPI()
@app.get("/users")
def get_users():
return []
After:
api/
├── __init__.py
├── config.py # DATABASE_URL
├── models.py # User class
├── services.py # create_user
└── routes.py # FastAPI routes
Troubleshooting
Import errors: Check __init__.py exports, verify relative imports (.module)
Circular imports: Use TYPE_CHECKING or late imports, or extract shared code
Tests failing: Update test imports to new package structure
For detailed examples, patterns, and troubleshooting, see references/detailed-guide.md.
More by sorryhyun
View allRouter skill for DiPeO code generation pipeline (TypeScript specs → IR → Python/GraphQL). Use when task mentions TypeScript models, IR builders, generated code diagnosis, or codegen workflow. For simple tasks, handle directly; for complex work, escalate to dipeo-codegen-pipeline agent.
Test implementation of thin router skill for DiPeO backend. Provides decision criteria and documentation anchors for FastAPI server, CLI (dipeo run/results/metrics/compile/export), SQLite schema, and MCP integration in apps/server/. Use when task mentions CLI commands, server endpoints, database queries, or MCP tools.
Router skill for DiPeO runtime Python code (execution handlers, service architecture, domain models, LLM infrastructure). Use when task mentions node handlers, EventBus, ServiceRegistry, Envelope pattern, or domain logic. For simple tasks, handle directly; for complex work, escalate to dipeo-package-maintainer agent.
name: dipeo-backend
