here is the full template for a flask app
This commit is contained in:
parent
8fddbed915
commit
d97d90c0ea
11 changed files with 250 additions and 0 deletions
4
.env.example
Normal file
4
.env.example
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
FLASK_APP=main.py
|
||||
FLASK_ENV=development
|
||||
SECRET_KEY=change-this-to-a-random-secret-key
|
||||
DATABASE_URL=sqlite:///app.db
|
||||
65
README.md
Normal file
65
README.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Flask Base Application
|
||||
|
||||
A basic Flask application with user configuration and database support.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
├── app/
|
||||
│ ├── __init__.py # Application factory and extensions
|
||||
│ ├── routes.py # Route definitions
|
||||
│ ├── models.py # Database models
|
||||
│ └── utils.py # Utility functions
|
||||
├── tests/
|
||||
│ ├── __init__.py
|
||||
│ └── test_app.py # Unit tests
|
||||
├── config.py # Configuration classes
|
||||
├── main.py # Application entry point
|
||||
├── requirements.txt # Python dependencies
|
||||
├── .env.example # Environment variables template
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Install dependencies:**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **Configure environment:**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your own settings
|
||||
```
|
||||
|
||||
3. **Run the application:**
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
Or using Flask CLI:
|
||||
```bash
|
||||
flask run
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The app supports multiple environments via configuration classes in `config.py`:
|
||||
|
||||
- **Development** (`FLASK_ENV=development`) - Default, with debug enabled
|
||||
- **Testing** (`FLASK_ENV=testing`) - In-memory database, CSRF disabled
|
||||
- **Production** (`FLASK_ENV=production`) - Debug disabled
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
python -m pytest tests/
|
||||
# or
|
||||
python -m unittest discover tests
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
- `GET /` - Home page
|
||||
- `GET /health` - Health check endpoint
|
||||
31
app/__init__.py
Normal file
31
app/__init__.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from config import config
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
|
||||
def create_app(config_name="default"):
|
||||
"""Application factory function.
|
||||
|
||||
Args:
|
||||
config_name: Configuration name (development, testing, production).
|
||||
|
||||
Returns:
|
||||
Configured Flask application instance.
|
||||
"""
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(config[config_name])
|
||||
|
||||
# Initialize extensions
|
||||
db.init_app(app)
|
||||
|
||||
# Register blueprints
|
||||
from app.routes import main as main_blueprint
|
||||
app.register_blueprint(main_blueprint)
|
||||
|
||||
# Create database tables
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
|
||||
return app
|
||||
19
app/models.py
Normal file
19
app/models.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from app import db
|
||||
|
||||
|
||||
class User(db.Model):
|
||||
"""User model for the application."""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
email = db.Column(db.String(120), unique=True, nullable=False)
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert user object to dictionary."""
|
||||
return {
|
||||
"id": self.id,
|
||||
"username": self.username,
|
||||
"email": self.email,
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User {self.username}>"
|
||||
15
app/routes.py
Normal file
15
app/routes.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from flask import Blueprint, jsonify, request
|
||||
|
||||
main = Blueprint("main", __name__)
|
||||
|
||||
|
||||
@main.route("/")
|
||||
def index():
|
||||
"""Home page route."""
|
||||
return jsonify({"message": "Flask App is running"})
|
||||
|
||||
|
||||
@main.route("/health")
|
||||
def health():
|
||||
"""Health check endpoint."""
|
||||
return jsonify({"status": "healthy"})
|
||||
16
app/utils.py
Normal file
16
app/utils.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
def format_response(data=None, message="Success", status="ok"):
|
||||
"""Format a standard API response.
|
||||
|
||||
Args:
|
||||
data: Response data payload.
|
||||
message: Status message.
|
||||
status: Status string (ok, error, etc.).
|
||||
|
||||
Returns:
|
||||
Dictionary with standardized response format.
|
||||
"""
|
||||
return {
|
||||
"status": status,
|
||||
"message": message,
|
||||
"data": data,
|
||||
}
|
||||
39
config.py
Normal file
39
config.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
class Config:
|
||||
"""Base configuration."""
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", "default-secret-key")
|
||||
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
||||
"DATABASE_URL", "sqlite:///app.db"
|
||||
)
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
"""Development configuration."""
|
||||
DEBUG = True
|
||||
|
||||
|
||||
class TestingConfig(Config):
|
||||
"""Testing configuration."""
|
||||
TESTING = True
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
|
||||
WTF_CSRFS_ENABLED = False
|
||||
|
||||
|
||||
class ProductionConfig(Config):
|
||||
"""Production configuration."""
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
|
||||
|
||||
config = {
|
||||
"development": DevelopmentConfig,
|
||||
"testing": TestingConfig,
|
||||
"production": ProductionConfig,
|
||||
"default": DevelopmentConfig,
|
||||
}
|
||||
9
main.py
Normal file
9
main.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import os
|
||||
from app import create_app
|
||||
from config import config
|
||||
|
||||
config_name = os.environ.get("FLASK_ENV", "development")
|
||||
app = create_app(config[config_name])
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000, debug=True)
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Flask>=3.0.0
|
||||
python-dotenv>=1.0.0
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
50
tests/test_app.py
Normal file
50
tests/test_app.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import unittest
|
||||
import os
|
||||
import tempfile
|
||||
from app import create_app, db
|
||||
from app.models import User
|
||||
|
||||
|
||||
class BasicTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test client and database."""
|
||||
self.app = create_app("testing")
|
||||
self.client = self.app.test_client()
|
||||
with self.app.app_context():
|
||||
db.create_all()
|
||||
|
||||
def tearDown(self):
|
||||
"""Clean up database after tests."""
|
||||
with self.app.app_context():
|
||||
db.session.remove()
|
||||
db.drop_all()
|
||||
|
||||
def test_index_route(self):
|
||||
"""Test home page route."""
|
||||
response = self.client.get("/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.get_json()
|
||||
self.assertEqual(data["message"], "Flask App is running")
|
||||
|
||||
def test_health_route(self):
|
||||
"""Test health check endpoint."""
|
||||
response = self.client.get("/health")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.get_json()
|
||||
self.assertEqual(data["status"], "healthy")
|
||||
|
||||
def test_create_user(self):
|
||||
"""Test creating a new user."""
|
||||
with self.app.app_context():
|
||||
user = User(username="testuser", email="test@example.com")
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
# Verify user was created
|
||||
found_user = User.query.first()
|
||||
self.assertIsNotNone(found_user)
|
||||
self.assertEqual(found_user.username, "testuser")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Reference in a new issue