myfy-patterns
SKILL.md
myfy Framework Patterns
You are assisting a developer building an application with the myfy Python framework.
Core Principles
- Opinionated, not rigid - Strong defaults, full configurability
- Modular by design - Features are modules (web, data, tasks, frontend)
- Type-safe DI - Constructor injection with compile-time validation
- Async-native - Built on ASGI and AnyIO with contextvars
- Zero-config defaults - Convention over configuration
Imports
Always import from the public API:
# Core
from myfy.core import Application, provider, SINGLETON, REQUEST, TASK
from myfy.core import BaseSettings, BaseModule
# Web
from myfy.web import WebModule, route, Query, abort, errors
from myfy.web import Authenticated, Anonymous, AuthModule
from myfy.web.ratelimit import RateLimitModule, rate_limit
# Data
from myfy.data import DataModule, AsyncSession
# Tasks
from myfy.tasks import TasksModule, task, TaskContext
# Frontend
from myfy.frontend import FrontendModule, render_template
# User
from myfy.user import UserModule
# CLI Commands
from myfy.commands import CliModule, cli
Application Structure
from myfy.core import Application
from myfy.web import WebModule, route
from myfy.data import DataModule
app = Application(
settings_class=AppSettings, # Optional custom settings
auto_discover=False, # Disable auto-discovery for explicit control
)
# Add modules in dependency order
app.add_module(DataModule())
app.add_module(WebModule())
Module Categories
| Module | Package | Purpose |
|---|---|---|
| WebModule | myfy-web | HTTP routing, ASGI, FastAPI-like decorators |
| DataModule | myfy-data | SQLAlchemy async, migrations, sessions |
| FrontendModule | myfy-frontend | Jinja2, Tailwind 4, DaisyUI 5, Vite |
| TasksModule | myfy-tasks | Background jobs, SQL-based task queue |
| UserModule | myfy-user | Auth, OAuth, user management |
| CliModule | myfy-commands | Custom CLI commands |
| AuthModule | myfy-web.auth | Type-based authentication, protected routes |
| RateLimitModule | myfy-web.ratelimit | Rate limiting per IP or user |
Key Conventions
- File naming:
app.py,main.py, orapplication.pyfor entry point - Settings: Extend
BaseSettingsfrommyfy.core - Routes: Use global
routedecorator frommyfy.web - Providers: Use
@provider(scope=...)decorator frommyfy.core - Tasks: Use
@taskdecorator for background jobs
Common Patterns
Creating a Route with DI
from myfy.web import route
from myfy.data import AsyncSession
@route.get("/users/{user_id}")
async def get_user(user_id: int, session: AsyncSession) -> dict:
# session is auto-injected (REQUEST scope)
result = await session.execute(select(User).where(User.id == user_id))
return {"user": result.scalar_one_or_none()}
Creating a Provider
from myfy.core import provider, SINGLETON
@provider(scope=SINGLETON)
def email_service(settings: AppSettings) -> EmailService:
return EmailService(api_key=settings.email_api_key)
Settings Class
from pydantic import Field
from pydantic_settings import SettingsConfigDict
from myfy.core import BaseSettings
class AppSettings(BaseSettings):
app_name: str = Field(default="my-app")
debug: bool = Field(default=False)
database_url: str = Field(default="sqlite+aiosqlite:///./app.db")
model_config = SettingsConfigDict(
env_prefix="MYFY_",
env_file=".env",
)
Error Handling
from myfy.web import abort, errors
# Quick abort
abort(404, "User not found")
# Typed errors
raise errors.NotFound("User not found")
raise errors.BadRequest("Invalid email", field="email")
When Generating Code
Always:
- Use type hints for all function parameters and return types
- Use async/await for all handlers
- Import from
myfy.*not internal modules - Follow existing project structure
- Use Pydantic models for request/response bodies
Weekly Installs
2
Repository
psincraian/myfyGitHub Stars
86
First Seen
Feb 28, 2026
Security Audits
Installed on
opencode2
gemini-cli2
codebuddy2
github-copilot2
codex2
kimi-cli2