claude-code-templates 1.16.1 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/bin/create-claude-config.js +17 -8
- package/package.json +2 -3
- package/src/analytics/core/AgentAnalyzer.js +17 -3
- package/src/analytics/core/ProcessDetector.js +23 -7
- package/src/analytics/core/StateCalculator.js +102 -33
- package/src/analytics/data/DataCache.js +7 -7
- package/src/analytics-web/chats_mobile.html +2590 -0
- package/src/analytics-web/components/App.js +10 -10
- package/src/analytics-web/components/SessionTimer.js +1 -1
- package/src/analytics-web/components/Sidebar.js +5 -14
- package/src/analytics-web/index.html +932 -78
- package/src/analytics.js +263 -5
- package/src/chats-mobile.js +682 -0
- package/src/claude-api-proxy.js +460 -0
- package/src/file-operations.js +239 -36
- package/src/health-check.js +310 -0
- package/src/index.js +1245 -36
- package/src/tracking-service.js +31 -34
- package/components/agents/api-security-audit.md +0 -92
- package/components/agents/database-optimization.md +0 -94
- package/components/agents/react-performance-optimization.md +0 -64
- package/components/commands/check-file.md +0 -53
- package/components/commands/generate-tests.md +0 -68
- package/components/mcps/deepgraph-nextjs.json +0 -12
- package/components/mcps/deepgraph-react.json +0 -12
- package/components/mcps/deepgraph-typescript.json +0 -12
- package/components/mcps/deepgraph-vue.json +0 -12
- package/components/mcps/filesystem-access.json +0 -12
- package/components/mcps/github-integration.json +0 -11
- package/components/mcps/memory-integration.json +0 -8
- package/components/mcps/mysql-integration.json +0 -11
- package/components/mcps/postgresql-integration.json +0 -11
- package/components/mcps/web-fetch.json +0 -8
- package/src/analytics-web/components/AgentsPage.js +0 -4761
- package/templates/common/.claude/commands/git-workflow.md +0 -239
- package/templates/common/.claude/commands/project-setup.md +0 -316
- package/templates/common/.mcp.json +0 -41
- package/templates/common/CLAUDE.md +0 -109
- package/templates/common/README.md +0 -96
- package/templates/go/.mcp.json +0 -78
- package/templates/go/README.md +0 -25
- package/templates/javascript-typescript/.claude/commands/api-endpoint.md +0 -51
- package/templates/javascript-typescript/.claude/commands/debug.md +0 -52
- package/templates/javascript-typescript/.claude/commands/lint.md +0 -48
- package/templates/javascript-typescript/.claude/commands/npm-scripts.md +0 -48
- package/templates/javascript-typescript/.claude/commands/refactor.md +0 -55
- package/templates/javascript-typescript/.claude/commands/test.md +0 -61
- package/templates/javascript-typescript/.claude/commands/typescript-migrate.md +0 -51
- package/templates/javascript-typescript/.claude/settings.json +0 -142
- package/templates/javascript-typescript/.mcp.json +0 -80
- package/templates/javascript-typescript/CLAUDE.md +0 -185
- package/templates/javascript-typescript/README.md +0 -259
- package/templates/javascript-typescript/examples/angular-app/.claude/commands/components.md +0 -63
- package/templates/javascript-typescript/examples/angular-app/.claude/commands/services.md +0 -62
- package/templates/javascript-typescript/examples/node-api/.claude/commands/api-endpoint.md +0 -46
- package/templates/javascript-typescript/examples/node-api/.claude/commands/database.md +0 -56
- package/templates/javascript-typescript/examples/node-api/.claude/commands/middleware.md +0 -61
- package/templates/javascript-typescript/examples/node-api/.claude/commands/route.md +0 -57
- package/templates/javascript-typescript/examples/node-api/CLAUDE.md +0 -102
- package/templates/javascript-typescript/examples/react-app/.claude/commands/component.md +0 -29
- package/templates/javascript-typescript/examples/react-app/.claude/commands/hooks.md +0 -44
- package/templates/javascript-typescript/examples/react-app/.claude/commands/state-management.md +0 -45
- package/templates/javascript-typescript/examples/react-app/CLAUDE.md +0 -81
- package/templates/javascript-typescript/examples/react-app/agents/react-performance-optimization.md +0 -530
- package/templates/javascript-typescript/examples/react-app/agents/react-state-management.md +0 -295
- package/templates/javascript-typescript/examples/vue-app/.claude/commands/components.md +0 -46
- package/templates/javascript-typescript/examples/vue-app/.claude/commands/composables.md +0 -51
- package/templates/python/.claude/commands/lint.md +0 -111
- package/templates/python/.claude/commands/test.md +0 -73
- package/templates/python/.claude/settings.json +0 -153
- package/templates/python/.mcp.json +0 -78
- package/templates/python/CLAUDE.md +0 -276
- package/templates/python/examples/django-app/.claude/commands/admin.md +0 -264
- package/templates/python/examples/django-app/.claude/commands/django-model.md +0 -124
- package/templates/python/examples/django-app/.claude/commands/views.md +0 -222
- package/templates/python/examples/django-app/CLAUDE.md +0 -313
- package/templates/python/examples/django-app/agents/django-api-security.md +0 -642
- package/templates/python/examples/django-app/agents/django-database-optimization.md +0 -752
- package/templates/python/examples/fastapi-app/.claude/commands/api-endpoints.md +0 -513
- package/templates/python/examples/fastapi-app/.claude/commands/auth.md +0 -775
- package/templates/python/examples/fastapi-app/.claude/commands/database.md +0 -657
- package/templates/python/examples/fastapi-app/.claude/commands/deployment.md +0 -160
- package/templates/python/examples/fastapi-app/.claude/commands/testing.md +0 -927
- package/templates/python/examples/fastapi-app/CLAUDE.md +0 -229
- package/templates/python/examples/flask-app/.claude/commands/app-factory.md +0 -384
- package/templates/python/examples/flask-app/.claude/commands/blueprint.md +0 -243
- package/templates/python/examples/flask-app/.claude/commands/database.md +0 -410
- package/templates/python/examples/flask-app/.claude/commands/deployment.md +0 -620
- package/templates/python/examples/flask-app/.claude/commands/flask-route.md +0 -217
- package/templates/python/examples/flask-app/.claude/commands/testing.md +0 -559
- package/templates/python/examples/flask-app/CLAUDE.md +0 -391
- package/templates/ruby/.claude/commands/model.md +0 -360
- package/templates/ruby/.claude/commands/test.md +0 -480
- package/templates/ruby/.claude/settings.json +0 -146
- package/templates/ruby/.mcp.json +0 -83
- package/templates/ruby/CLAUDE.md +0 -284
- package/templates/ruby/examples/rails-app/.claude/commands/authentication.md +0 -490
- package/templates/ruby/examples/rails-app/CLAUDE.md +0 -376
- package/templates/rust/.mcp.json +0 -78
- package/templates/rust/README.md +0 -26
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
# FastAPI Project Configuration
|
|
2
|
-
|
|
3
|
-
This file provides specific guidance for FastAPI web application development using Claude Code.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
This is a FastAPI application project optimized for modern API development with automatic documentation, type hints, and async support.
|
|
8
|
-
|
|
9
|
-
## FastAPI-Specific Development Commands
|
|
10
|
-
|
|
11
|
-
### Project Management
|
|
12
|
-
- `uvicorn app.main:app --reload` - Start development server with auto-reload
|
|
13
|
-
- `uvicorn app.main:app --host 0.0.0.0 --port 8000` - Start server on all interfaces
|
|
14
|
-
- `uvicorn app.main:app --workers 4` - Start with multiple workers
|
|
15
|
-
|
|
16
|
-
### Database Management
|
|
17
|
-
- `alembic init alembic` - Initialize Alembic migrations
|
|
18
|
-
- `alembic revision --autogenerate -m "message"` - Create migration
|
|
19
|
-
- `alembic upgrade head` - Apply migrations
|
|
20
|
-
- `alembic downgrade -1` - Rollback one migration
|
|
21
|
-
|
|
22
|
-
### Development Tools
|
|
23
|
-
- `python -m pytest` - Run tests
|
|
24
|
-
- `python -m pytest --cov=app` - Run tests with coverage
|
|
25
|
-
- `mypy app/` - Type checking
|
|
26
|
-
- `black app/` - Code formatting
|
|
27
|
-
|
|
28
|
-
## FastAPI Project Structure
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
myproject/
|
|
32
|
-
├── app/ # Application package
|
|
33
|
-
│ ├── __init__.py
|
|
34
|
-
│ ├── main.py # FastAPI application
|
|
35
|
-
│ ├── core/ # Core configuration
|
|
36
|
-
│ │ ├── __init__.py
|
|
37
|
-
│ │ ├── config.py # Settings
|
|
38
|
-
│ │ └── security.py # Authentication
|
|
39
|
-
│ ├── api/ # API routes
|
|
40
|
-
│ │ ├── __init__.py
|
|
41
|
-
│ │ ├── deps.py # Dependencies
|
|
42
|
-
│ │ └── v1/
|
|
43
|
-
│ │ ├── __init__.py
|
|
44
|
-
│ │ ├── api.py # API router
|
|
45
|
-
│ │ └── endpoints/
|
|
46
|
-
│ ├── models/ # Database models
|
|
47
|
-
│ │ ├── __init__.py
|
|
48
|
-
│ │ ├── base.py
|
|
49
|
-
│ │ └── user.py
|
|
50
|
-
│ ├── schemas/ # Pydantic schemas
|
|
51
|
-
│ │ ├── __init__.py
|
|
52
|
-
│ │ └── user.py
|
|
53
|
-
│ ├── repositories/ # Data access layer
|
|
54
|
-
│ │ ├── __init__.py
|
|
55
|
-
│ │ └── user.py
|
|
56
|
-
│ ├── services/ # Business logic
|
|
57
|
-
│ │ ├── __init__.py
|
|
58
|
-
│ │ └── auth.py
|
|
59
|
-
│ └── db/ # Database configuration
|
|
60
|
-
│ ├── __init__.py
|
|
61
|
-
│ └── database.py
|
|
62
|
-
├── alembic/ # Database migrations
|
|
63
|
-
├── tests/ # Test files
|
|
64
|
-
├── requirements.txt # Dependencies
|
|
65
|
-
└── docker-compose.yml # Docker configuration
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## FastAPI Application Setup
|
|
69
|
-
|
|
70
|
-
```python
|
|
71
|
-
# app/main.py
|
|
72
|
-
from fastapi import FastAPI
|
|
73
|
-
from app.core.config import settings
|
|
74
|
-
from app.api.v1.api import api_router
|
|
75
|
-
|
|
76
|
-
app = FastAPI(
|
|
77
|
-
title=settings.PROJECT_NAME,
|
|
78
|
-
version=settings.VERSION,
|
|
79
|
-
openapi_url=f"/api/v1/openapi.json"
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
# Include routers
|
|
83
|
-
app.include_router(api_router, prefix="/api/v1")
|
|
84
|
-
|
|
85
|
-
@app.get("/")
|
|
86
|
-
async def root():
|
|
87
|
-
return {"message": "Welcome to FastAPI"}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Configuration Management
|
|
91
|
-
|
|
92
|
-
```python
|
|
93
|
-
# app/core/config.py
|
|
94
|
-
from pydantic import BaseSettings
|
|
95
|
-
|
|
96
|
-
class Settings(BaseSettings):
|
|
97
|
-
PROJECT_NAME: str = "FastAPI App"
|
|
98
|
-
VERSION: str = "1.0.0"
|
|
99
|
-
SECRET_KEY: str
|
|
100
|
-
DATABASE_URL: str
|
|
101
|
-
|
|
102
|
-
class Config:
|
|
103
|
-
env_file = ".env"
|
|
104
|
-
|
|
105
|
-
settings = Settings()
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## FastAPI Best Practices
|
|
109
|
-
|
|
110
|
-
### API Design
|
|
111
|
-
- Use Pydantic models for request/response validation
|
|
112
|
-
- Implement proper HTTP status codes
|
|
113
|
-
- Add comprehensive API documentation
|
|
114
|
-
- Use dependency injection for common functionality
|
|
115
|
-
- Implement proper error handling
|
|
116
|
-
|
|
117
|
-
### Database Integration
|
|
118
|
-
- Use SQLAlchemy with async support
|
|
119
|
-
- Implement repository pattern for data access
|
|
120
|
-
- Use Alembic for database migrations
|
|
121
|
-
- Add proper database connection pooling
|
|
122
|
-
- Implement database health checks
|
|
123
|
-
|
|
124
|
-
### Authentication & Security
|
|
125
|
-
- Use JWT tokens for authentication
|
|
126
|
-
- Implement OAuth2 with scopes
|
|
127
|
-
- Add rate limiting for API endpoints
|
|
128
|
-
- Use HTTPS in production
|
|
129
|
-
- Implement proper CORS configuration
|
|
130
|
-
|
|
131
|
-
### Performance Optimization
|
|
132
|
-
- Use async/await for I/O operations
|
|
133
|
-
- Implement response caching
|
|
134
|
-
- Add database query optimization
|
|
135
|
-
- Use connection pooling
|
|
136
|
-
- Monitor application performance
|
|
137
|
-
|
|
138
|
-
## Testing Strategy
|
|
139
|
-
|
|
140
|
-
### Test Organization
|
|
141
|
-
```python
|
|
142
|
-
# tests/conftest.py
|
|
143
|
-
import pytest
|
|
144
|
-
from fastapi.testclient import TestClient
|
|
145
|
-
from app.main import app
|
|
146
|
-
|
|
147
|
-
@pytest.fixture
|
|
148
|
-
def client():
|
|
149
|
-
return TestClient(app)
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Test Types
|
|
153
|
-
- **Unit tests** for business logic
|
|
154
|
-
- **Integration tests** for API endpoints
|
|
155
|
-
- **Database tests** with test fixtures
|
|
156
|
-
- **Authentication tests** for security
|
|
157
|
-
|
|
158
|
-
## Deployment Considerations
|
|
159
|
-
|
|
160
|
-
### Production Setup
|
|
161
|
-
- Use Uvicorn with multiple workers
|
|
162
|
-
- Implement proper logging and monitoring
|
|
163
|
-
- Set up reverse proxy (Nginx)
|
|
164
|
-
- Use environment variables for configuration
|
|
165
|
-
- Implement health checks
|
|
166
|
-
|
|
167
|
-
### Docker Configuration
|
|
168
|
-
```dockerfile
|
|
169
|
-
FROM python:3.11-slim
|
|
170
|
-
WORKDIR /app
|
|
171
|
-
COPY requirements.txt .
|
|
172
|
-
RUN pip install -r requirements.txt
|
|
173
|
-
COPY . .
|
|
174
|
-
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Environment Variables
|
|
178
|
-
```bash
|
|
179
|
-
SECRET_KEY=your-secret-key
|
|
180
|
-
DATABASE_URL=postgresql://user:pass@host/db
|
|
181
|
-
REDIS_URL=redis://localhost:6379
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Common FastAPI Patterns
|
|
185
|
-
|
|
186
|
-
### Dependency Injection
|
|
187
|
-
```python
|
|
188
|
-
from fastapi import Depends
|
|
189
|
-
from app.db.database import get_db
|
|
190
|
-
|
|
191
|
-
@app.get("/users/")
|
|
192
|
-
async def get_users(db: Session = Depends(get_db)):
|
|
193
|
-
return users
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Background Tasks
|
|
197
|
-
```python
|
|
198
|
-
from fastapi import BackgroundTasks
|
|
199
|
-
|
|
200
|
-
@app.post("/send-email/")
|
|
201
|
-
async def send_email(background_tasks: BackgroundTasks):
|
|
202
|
-
background_tasks.add_task(send_email_task)
|
|
203
|
-
return {"message": "Email sent"}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Middleware
|
|
207
|
-
```python
|
|
208
|
-
@app.middleware("http")
|
|
209
|
-
async def add_process_time_header(request, call_next):
|
|
210
|
-
response = await call_next(request)
|
|
211
|
-
return response
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Development Workflow
|
|
215
|
-
|
|
216
|
-
### Getting Started
|
|
217
|
-
1. Clone repository
|
|
218
|
-
2. Create virtual environment: `python -m venv venv`
|
|
219
|
-
3. Install dependencies: `pip install -r requirements.txt`
|
|
220
|
-
4. Set environment variables
|
|
221
|
-
5. Run migrations: `alembic upgrade head`
|
|
222
|
-
6. Start server: `uvicorn app.main:app --reload`
|
|
223
|
-
|
|
224
|
-
### Code Quality
|
|
225
|
-
- **Black** - Code formatting
|
|
226
|
-
- **isort** - Import sorting
|
|
227
|
-
- **mypy** - Type checking
|
|
228
|
-
- **pytest** - Testing framework
|
|
229
|
-
- **flake8** - Linting
|
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
# Flask Application Factory Pattern
|
|
2
|
-
|
|
3
|
-
Create a scalable Flask application using the factory pattern with blueprints and configuration management.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
This command helps you set up a Flask application using the application factory pattern, which is the recommended approach for larger Flask applications.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/app-factory
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## What this command does
|
|
16
|
-
|
|
17
|
-
1. **Creates application factory** with proper structure
|
|
18
|
-
2. **Sets up configuration management** for different environments
|
|
19
|
-
3. **Implements blueprints** for modular design
|
|
20
|
-
4. **Configures extensions** (database, auth, etc.)
|
|
21
|
-
5. **Adds error handling** and logging
|
|
22
|
-
|
|
23
|
-
## Example Output
|
|
24
|
-
|
|
25
|
-
```python
|
|
26
|
-
# app/__init__.py
|
|
27
|
-
from flask import Flask
|
|
28
|
-
from flask_sqlalchemy import SQLAlchemy
|
|
29
|
-
from flask_migrate import Migrate
|
|
30
|
-
from flask_login import LoginManager
|
|
31
|
-
from flask_mail import Mail
|
|
32
|
-
from flask_wtf.csrf import CSRFProtect
|
|
33
|
-
from flask_cors import CORS
|
|
34
|
-
import logging
|
|
35
|
-
from logging.handlers import RotatingFileHandler
|
|
36
|
-
import os
|
|
37
|
-
|
|
38
|
-
# Initialize extensions
|
|
39
|
-
db = SQLAlchemy()
|
|
40
|
-
migrate = Migrate()
|
|
41
|
-
login = LoginManager()
|
|
42
|
-
mail = Mail()
|
|
43
|
-
csrf = CSRFProtect()
|
|
44
|
-
cors = CORS()
|
|
45
|
-
|
|
46
|
-
def create_app(config_class=None):
|
|
47
|
-
"""Application factory function."""
|
|
48
|
-
app = Flask(__name__)
|
|
49
|
-
|
|
50
|
-
# Load configuration
|
|
51
|
-
if config_class is None:
|
|
52
|
-
config_class = os.environ.get('FLASK_CONFIG', 'development')
|
|
53
|
-
|
|
54
|
-
if isinstance(config_class, str):
|
|
55
|
-
from app.config import config
|
|
56
|
-
app.config.from_object(config[config_class])
|
|
57
|
-
else:
|
|
58
|
-
app.config.from_object(config_class)
|
|
59
|
-
|
|
60
|
-
# Initialize extensions
|
|
61
|
-
db.init_app(app)
|
|
62
|
-
migrate.init_app(app, db)
|
|
63
|
-
login.init_app(app)
|
|
64
|
-
mail.init_app(app)
|
|
65
|
-
csrf.init_app(app)
|
|
66
|
-
cors.init_app(app)
|
|
67
|
-
|
|
68
|
-
# Configure login manager
|
|
69
|
-
login.login_view = 'auth.login'
|
|
70
|
-
login.login_message = 'Please log in to access this page.'
|
|
71
|
-
login.login_message_category = 'info'
|
|
72
|
-
|
|
73
|
-
# Register blueprints
|
|
74
|
-
from app.main import bp as main_bp
|
|
75
|
-
app.register_blueprint(main_bp)
|
|
76
|
-
|
|
77
|
-
from app.auth import bp as auth_bp
|
|
78
|
-
app.register_blueprint(auth_bp, url_prefix='/auth')
|
|
79
|
-
|
|
80
|
-
from app.api import bp as api_bp
|
|
81
|
-
app.register_blueprint(api_bp, url_prefix='/api')
|
|
82
|
-
|
|
83
|
-
from app.admin import bp as admin_bp
|
|
84
|
-
app.register_blueprint(admin_bp, url_prefix='/admin')
|
|
85
|
-
|
|
86
|
-
# Error handlers
|
|
87
|
-
from app.errors import bp as errors_bp
|
|
88
|
-
app.register_blueprint(errors_bp)
|
|
89
|
-
|
|
90
|
-
# Configure logging
|
|
91
|
-
if not app.debug and not app.testing:
|
|
92
|
-
if not os.path.exists('logs'):
|
|
93
|
-
os.mkdir('logs')
|
|
94
|
-
|
|
95
|
-
file_handler = RotatingFileHandler(
|
|
96
|
-
'logs/app.log',
|
|
97
|
-
maxBytes=10240,
|
|
98
|
-
backupCount=10
|
|
99
|
-
)
|
|
100
|
-
file_handler.setFormatter(logging.Formatter(
|
|
101
|
-
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
|
|
102
|
-
))
|
|
103
|
-
file_handler.setLevel(logging.INFO)
|
|
104
|
-
app.logger.addHandler(file_handler)
|
|
105
|
-
|
|
106
|
-
app.logger.setLevel(logging.INFO)
|
|
107
|
-
app.logger.info('Flask application startup')
|
|
108
|
-
|
|
109
|
-
return app
|
|
110
|
-
|
|
111
|
-
# Import models (avoid circular imports)
|
|
112
|
-
from app import models
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
```python
|
|
116
|
-
# app/config.py
|
|
117
|
-
import os
|
|
118
|
-
from dotenv import load_dotenv
|
|
119
|
-
|
|
120
|
-
basedir = os.path.abspath(os.path.dirname(__file__))
|
|
121
|
-
load_dotenv(os.path.join(basedir, '.env'))
|
|
122
|
-
|
|
123
|
-
class Config:
|
|
124
|
-
"""Base configuration class."""
|
|
125
|
-
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key'
|
|
126
|
-
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
|
|
127
|
-
'sqlite:///' + os.path.join(basedir, 'app.db')
|
|
128
|
-
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
129
|
-
|
|
130
|
-
# Mail configuration
|
|
131
|
-
MAIL_SERVER = os.environ.get('MAIL_SERVER')
|
|
132
|
-
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 587)
|
|
133
|
-
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1']
|
|
134
|
-
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
|
|
135
|
-
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
|
|
136
|
-
ADMIN_EMAIL = os.environ.get('ADMIN_EMAIL')
|
|
137
|
-
|
|
138
|
-
# Pagination
|
|
139
|
-
POSTS_PER_PAGE = 10
|
|
140
|
-
USERS_PER_PAGE = 50
|
|
141
|
-
|
|
142
|
-
# Upload configuration
|
|
143
|
-
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB
|
|
144
|
-
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
|
|
145
|
-
|
|
146
|
-
@staticmethod
|
|
147
|
-
def init_app(app):
|
|
148
|
-
pass
|
|
149
|
-
|
|
150
|
-
class DevelopmentConfig(Config):
|
|
151
|
-
"""Development configuration."""
|
|
152
|
-
DEBUG = True
|
|
153
|
-
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
|
|
154
|
-
'sqlite:///' + os.path.join(basedir, 'app-dev.db')
|
|
155
|
-
|
|
156
|
-
class TestingConfig(Config):
|
|
157
|
-
"""Testing configuration."""
|
|
158
|
-
TESTING = True
|
|
159
|
-
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or 'sqlite://'
|
|
160
|
-
WTF_CSRF_ENABLED = False
|
|
161
|
-
|
|
162
|
-
class ProductionConfig(Config):
|
|
163
|
-
"""Production configuration."""
|
|
164
|
-
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
|
|
165
|
-
'sqlite:///' + os.path.join(basedir, 'app.db')
|
|
166
|
-
|
|
167
|
-
@classmethod
|
|
168
|
-
def init_app(cls, app):
|
|
169
|
-
Config.init_app(app)
|
|
170
|
-
|
|
171
|
-
# Log to stderr
|
|
172
|
-
import logging
|
|
173
|
-
from logging import StreamHandler
|
|
174
|
-
file_handler = StreamHandler()
|
|
175
|
-
file_handler.setLevel(logging.INFO)
|
|
176
|
-
app.logger.addHandler(file_handler)
|
|
177
|
-
|
|
178
|
-
config = {
|
|
179
|
-
'development': DevelopmentConfig,
|
|
180
|
-
'testing': TestingConfig,
|
|
181
|
-
'production': ProductionConfig,
|
|
182
|
-
'default': DevelopmentConfig
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
```python
|
|
187
|
-
# app/main/__init__.py
|
|
188
|
-
from flask import Blueprint
|
|
189
|
-
|
|
190
|
-
bp = Blueprint('main', __name__)
|
|
191
|
-
|
|
192
|
-
from app.main import routes
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
```python
|
|
196
|
-
# app/main/routes.py
|
|
197
|
-
from flask import render_template, request, current_app
|
|
198
|
-
from app.main import bp
|
|
199
|
-
from app.models import Post
|
|
200
|
-
|
|
201
|
-
@bp.route('/')
|
|
202
|
-
@bp.route('/index')
|
|
203
|
-
def index():
|
|
204
|
-
"""Home page."""
|
|
205
|
-
page = request.args.get('page', 1, type=int)
|
|
206
|
-
posts = Post.query.filter_by(published=True).order_by(
|
|
207
|
-
Post.created_at.desc()
|
|
208
|
-
).paginate(
|
|
209
|
-
page=page,
|
|
210
|
-
per_page=current_app.config['POSTS_PER_PAGE'],
|
|
211
|
-
error_out=False
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
return render_template('index.html', posts=posts)
|
|
215
|
-
|
|
216
|
-
@bp.route('/about')
|
|
217
|
-
def about():
|
|
218
|
-
"""About page."""
|
|
219
|
-
return render_template('about.html')
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
```python
|
|
223
|
-
# app/auth/__init__.py
|
|
224
|
-
from flask import Blueprint
|
|
225
|
-
|
|
226
|
-
bp = Blueprint('auth', __name__)
|
|
227
|
-
|
|
228
|
-
from app.auth import routes
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
```python
|
|
232
|
-
# app/auth/routes.py
|
|
233
|
-
from flask import render_template, redirect, url_for, flash, request
|
|
234
|
-
from flask_login import login_user, logout_user, login_required, current_user
|
|
235
|
-
from werkzeug.urls import url_parse
|
|
236
|
-
from app import db
|
|
237
|
-
from app.auth import bp
|
|
238
|
-
from app.auth.forms import LoginForm, RegistrationForm
|
|
239
|
-
from app.models import User
|
|
240
|
-
|
|
241
|
-
@bp.route('/login', methods=['GET', 'POST'])
|
|
242
|
-
def login():
|
|
243
|
-
"""User login."""
|
|
244
|
-
if current_user.is_authenticated:
|
|
245
|
-
return redirect(url_for('main.index'))
|
|
246
|
-
|
|
247
|
-
form = LoginForm()
|
|
248
|
-
if form.validate_on_submit():
|
|
249
|
-
user = User.query.filter_by(username=form.username.data).first()
|
|
250
|
-
if user is None or not user.check_password(form.password.data):
|
|
251
|
-
flash('Invalid username or password', 'error')
|
|
252
|
-
return redirect(url_for('auth.login'))
|
|
253
|
-
|
|
254
|
-
login_user(user, remember=form.remember_me.data)
|
|
255
|
-
|
|
256
|
-
next_page = request.args.get('next')
|
|
257
|
-
if not next_page or url_parse(next_page).netloc != '':
|
|
258
|
-
next_page = url_for('main.index')
|
|
259
|
-
|
|
260
|
-
return redirect(next_page)
|
|
261
|
-
|
|
262
|
-
return render_template('auth/login.html', form=form)
|
|
263
|
-
|
|
264
|
-
@bp.route('/logout')
|
|
265
|
-
@login_required
|
|
266
|
-
def logout():
|
|
267
|
-
"""User logout."""
|
|
268
|
-
logout_user()
|
|
269
|
-
flash('You have been logged out.', 'info')
|
|
270
|
-
return redirect(url_for('main.index'))
|
|
271
|
-
|
|
272
|
-
@bp.route('/register', methods=['GET', 'POST'])
|
|
273
|
-
def register():
|
|
274
|
-
"""User registration."""
|
|
275
|
-
if current_user.is_authenticated:
|
|
276
|
-
return redirect(url_for('main.index'))
|
|
277
|
-
|
|
278
|
-
form = RegistrationForm()
|
|
279
|
-
if form.validate_on_submit():
|
|
280
|
-
user = User(username=form.username.data, email=form.email.data)
|
|
281
|
-
user.set_password(form.password.data)
|
|
282
|
-
db.session.add(user)
|
|
283
|
-
db.session.commit()
|
|
284
|
-
|
|
285
|
-
flash('Registration successful!', 'success')
|
|
286
|
-
return redirect(url_for('auth.login'))
|
|
287
|
-
|
|
288
|
-
return render_template('auth/register.html', form=form)
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
```python
|
|
292
|
-
# app/models.py
|
|
293
|
-
from app import db, login
|
|
294
|
-
from werkzeug.security import generate_password_hash, check_password_hash
|
|
295
|
-
from flask_login import UserMixin
|
|
296
|
-
from datetime import datetime
|
|
297
|
-
|
|
298
|
-
class User(UserMixin, db.Model):
|
|
299
|
-
"""User model."""
|
|
300
|
-
id = db.Column(db.Integer, primary_key=True)
|
|
301
|
-
username = db.Column(db.String(64), index=True, unique=True)
|
|
302
|
-
email = db.Column(db.String(120), index=True, unique=True)
|
|
303
|
-
password_hash = db.Column(db.String(128))
|
|
304
|
-
created_at = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
|
305
|
-
|
|
306
|
-
posts = db.relationship('Post', backref='author', lazy='dynamic')
|
|
307
|
-
|
|
308
|
-
def set_password(self, password):
|
|
309
|
-
self.password_hash = generate_password_hash(password)
|
|
310
|
-
|
|
311
|
-
def check_password(self, password):
|
|
312
|
-
return check_password_hash(self.password_hash, password)
|
|
313
|
-
|
|
314
|
-
def __repr__(self):
|
|
315
|
-
return f'<User {self.username}>'
|
|
316
|
-
|
|
317
|
-
@login.user_loader
|
|
318
|
-
def load_user(id):
|
|
319
|
-
return User.query.get(int(id))
|
|
320
|
-
|
|
321
|
-
class Post(db.Model):
|
|
322
|
-
"""Post model."""
|
|
323
|
-
id = db.Column(db.Integer, primary_key=True)
|
|
324
|
-
title = db.Column(db.String(100), nullable=False)
|
|
325
|
-
content = db.Column(db.Text, nullable=False)
|
|
326
|
-
published = db.Column(db.Boolean, default=False)
|
|
327
|
-
created_at = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
|
328
|
-
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
329
|
-
|
|
330
|
-
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
|
331
|
-
|
|
332
|
-
def __repr__(self):
|
|
333
|
-
return f'<Post {self.title}>'
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
```python
|
|
337
|
-
# app.py (main application entry point)
|
|
338
|
-
from app import create_app, db
|
|
339
|
-
from app.models import User, Post
|
|
340
|
-
|
|
341
|
-
app = create_app()
|
|
342
|
-
|
|
343
|
-
@app.shell_context_processor
|
|
344
|
-
def make_shell_context():
|
|
345
|
-
"""Add models to shell context."""
|
|
346
|
-
return {'db': db, 'User': User, 'Post': Post}
|
|
347
|
-
|
|
348
|
-
if __name__ == '__main__':
|
|
349
|
-
app.run(debug=True)
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
## Project Structure
|
|
353
|
-
|
|
354
|
-
```
|
|
355
|
-
project/
|
|
356
|
-
├── app/
|
|
357
|
-
│ ├── __init__.py # Application factory
|
|
358
|
-
│ ├── config.py # Configuration classes
|
|
359
|
-
│ ├── models.py # Database models
|
|
360
|
-
│ ├── main/
|
|
361
|
-
│ │ ├── __init__.py # Main blueprint
|
|
362
|
-
│ │ └── routes.py # Main routes
|
|
363
|
-
│ ├── auth/
|
|
364
|
-
│ │ ├── __init__.py # Auth blueprint
|
|
365
|
-
│ │ ├── routes.py # Auth routes
|
|
366
|
-
│ │ └── forms.py # Auth forms
|
|
367
|
-
│ ├── api/
|
|
368
|
-
│ │ ├── __init__.py # API blueprint
|
|
369
|
-
│ │ └── routes.py # API routes
|
|
370
|
-
│ └── templates/ # Jinja2 templates
|
|
371
|
-
├── migrations/ # Database migrations
|
|
372
|
-
├── logs/ # Application logs
|
|
373
|
-
├── app.py # Application entry point
|
|
374
|
-
├── requirements.txt # Dependencies
|
|
375
|
-
└── .env # Environment variables
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
## Benefits of Application Factory
|
|
379
|
-
|
|
380
|
-
- **Testing**: Easy to create app instances with different configs
|
|
381
|
-
- **Scalability**: Modular design with blueprints
|
|
382
|
-
- **Configuration**: Environment-specific settings
|
|
383
|
-
- **Extensions**: Proper initialization order
|
|
384
|
-
- **Maintainability**: Clear separation of concerns
|