← Python Menu · ← Prev: Django
# venv နဲ့ Flask install
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install flask
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return '<h1>Hello Flask!</h1>'
@app.route('/about')
def about():
return '<p>About page</p>'
if __name__ == '__main__':
app.run(debug=True)
# Run
python app.py
# http://127.0.0.1:5000
from flask import Flask, request
app = Flask(__name__)
# Static route
@app.route('/hello')
def hello():
return 'Hello!'
# URL variable (path parameter)
@app.route('/user/<username>')
def show_user(username):
return f'User: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post ID: {post_id}'
# Query string: /search?q=python&page=2
@app.route('/search')
def search():
q = request.args.get('q', '')
page = request.args.get('page', 1, type=int)
return f'Search: {q}, Page: {page}'
# HTTP methods
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
return f'Logged in as {username}'
return '''
<form method="post">
<input name="username" placeholder="Username">
<input type="password" name="password">
<button type="submit">Login</button>
</form>
'''
# app.py
from flask import render_template
@app.route('/posts')
def posts():
items = [
{'title': 'Flask Intro', 'author': 'Mg Mg'},
{'title': 'Python Tips', 'author': 'Aye Aye'},
]
return render_template('posts.html', posts=items, count=len(items))
# templates/base.html
<!DOCTYPE html>
<html>
<head><title>{% block title %}Site{% endblock %}</title></head>
<body>
<nav><a href="/">Home</a> | <a href="/posts">Posts</a></nav>
{% block content %}{% endblock %}
</body>
</html>
# templates/posts.html
{% extends "base.html" %}
{% block title %}Posts ({{ count }}){% endblock %}
{% block content %}
<h1>{{ count }} Posts</h1>
{% for post in posts %}
<div>
<h2>{{ post.title }}</h2>
<p>by {{ post.author }}</p>
</div>
{% endfor %}
{% endblock %}
{{ text | upper }} → UPPERCASE
{{ text | lower }} → lowercase
{{ text | truncate(50) }} → shorten
{{ date | strftime('%Y-%m-%d') }}
{{ price | round(2) }}
{{ list | length }}
{{ value | default('N/A') }}
{% if user.is_admin %}Admin{% endif %}
from flask import Flask, jsonify, request
app = Flask(__name__)
# In-memory store (real app: database)
posts = [
{'id': 1, 'title': 'Flask Basics', 'content': 'Hello!'},
{'id': 2, 'title': 'REST APIs', 'content': 'JSON!'},
]
@app.route('/api/posts', methods=['GET'])
def get_posts():
return jsonify({'posts': posts, 'total': len(posts)})
@app.route('/api/posts/<int:post_id>', methods=['GET'])
def get_post(post_id):
post = next((p for p in posts if p['id'] == post_id), None)
if not post:
return jsonify({'error': 'Not found'}), 404
return jsonify(post)
@app.route('/api/posts', methods=['POST'])
def create_post():
data = request.get_json()
if not data or 'title' not in data:
return jsonify({'error': 'title required'}), 400
new_post = {
'id': len(posts) + 1,
'title': data['title'],
'content': data.get('content', ''),
}
posts.append(new_post)
return jsonify(new_post), 201
@app.route('/api/posts/<int:post_id>', methods=['PUT'])
def update_post(post_id):
post = next((p for p in posts if p['id'] == post_id), None)
if not post:
return jsonify({'error': 'Not found'}), 404
data = request.get_json()
post.update(data)
return jsonify(post)
@app.route('/api/posts/<int:post_id>', methods=['DELETE'])
def delete_post(post_id):
global posts
posts = [p for p in posts if p['id'] != post_id]
return jsonify({'message': 'Deleted'})
pip install flask-sqlalchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
# PostgreSQL: 'postgresql://user:pass@localhost/dbname'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Model
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text)
created = db.Column(db.DateTime, default=datetime.utcnow)
def to_dict(self):
return {'id': self.id, 'title': self.title,
'content': self.content,
'created': self.created.isoformat()}
# DB init (run once)
with app.app_context():
db.create_all()
# Queries
@app.route('/api/posts')
def get_all():
posts = Post.query.order_by(Post.created.desc()).all()
return jsonify([p.to_dict() for p in posts])
@app.route('/api/posts', methods=['POST'])
def create():
data = request.get_json()
p = Post(title=data['title'], content=data.get('content'))
db.session.add(p)
db.session.commit()
return jsonify(p.to_dict()), 201
@app.route('/api/posts/<int:id>', methods=['DELETE'])
def delete(id):
p = Post.query.get_or_404(id)
db.session.delete(p)
db.session.commit()
return jsonify({'message': 'Deleted'})
# Large apps မှာ routes တွေကို blueprint (module) ခွဲပါ
# auth/routes.py
from flask import Blueprint
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login')
def login():
return 'Login page'
@auth_bp.route('/logout')
def logout():
return 'Logged out'
# posts/routes.py
from flask import Blueprint
posts_bp = Blueprint('posts', __name__, url_prefix='/posts')
@posts_bp.route('/')
def list():
return 'All posts'
@posts_bp.route('/<int:id>')
def detail(id):
return f'Post {id}'
# app.py (register blueprints)
from auth.routes import auth_bp
from posts.routes import posts_bp
app.register_blueprint(auth_bp)
app.register_blueprint(posts_bp)
# Structure
myapp/
├── app.py
├── auth/
│ └── routes.py
├── posts/
│ ├── routes.py
│ └── models.py
└── templates/
from flask import jsonify
# Custom error handlers
@app.errorhandler(404)
def not_found(e):
return jsonify({'error': 'Not found'}), 404
@app.errorhandler(500)
def server_error(e):
return jsonify({'error': 'Server error'}), 500
# CORS (frontend request allow)
pip install flask-cors
from flask_cors import CORS
CORS(app) # all routes allow
# or
CORS(app, resources={r"/api/*": {"origins": "http://localhost:3000"}})
# Environment config
import os
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-secret')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///dev.db')
app.config['DEBUG'] = os.environ.get('DEBUG', 'True') == 'True'
| Situation | Use Flask | Use Django |
|---|---|---|
| Project size | Small to medium | Medium to large |
| Need admin panel | ❌ Build yourself | ✅ Auto-generated |
| API only (no HTML) | ✅ Great | ⚠️ DRF adds overhead |
| Microservice | ✅ Ideal | ❌ Too heavy |
| Full CRUD web app | ⚠️ More code | ✅ Batteries included |
| Learning curve | Low (simple) | Medium (many concepts) |
| Flexibility | ✅ Choose own libs | ⚠️ Django-way |
| Auth built-in | ❌ Flask-Login | ✅ Full auth system |
Flask → Micro-framework, REST APIs, microservices, lightweight apps