Interactive guide to building your first Flask web application. Learn routing, templates, request handling, and debug workflows using Flask's lightweight Python framework.
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 50/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Master Flask web framework fundamentals through hands-on practice. This skill guides you through building a minimal Flask app, configuring routes, handling requests, rendering templates, and debugging—all based on the official Flask quickstart documentation.
By completing this skill, you'll create a working Flask application with:
Start by creating your first Flask app:
```python
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
```
**Save as `hello.py`** and run:
```bash
flask --app hello run
```
**Key concepts:**
**Expected output:** Server running on `http://127.0.0.1:5000`
Restart with debug mode for auto-reload and interactive debugger:
```bash
flask --app hello run --debug
```
**Warning:** Never use debug mode in production—it allows arbitrary code execution.
Protect against XSS injection by escaping user input:
```python
from flask import request
from markupsafe import escape
@app.route("/hello")
def hello():
name = request.args.get("name", "Flask")
return f"Hello, {escape(name)}!"
```
**Test:** Visit `/hello?name=<script>alert("bad")</script>` and verify the script is rendered as text.
Add URL parameters with type converters:
```python
@app.route('/user/<username>')
def show_user_profile(username):
return f'User {escape(username)}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post {post_id}'
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
return f'Subpath {escape(subpath)}'
```
**Converter types:** `string` (default), `int`, `float`, `path`, `uuid`
Generate URLs programmatically instead of hardcoding:
```python
from flask import url_for
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return f'{username}\'s profile'
with app.test_request_context():
print(url_for('index')) # /
print(url_for('login')) # /login
print(url_for('login', next='/')) # /login?next=/
print(url_for('profile', username='John Doe')) # /user/John%20Doe
```
**Benefits:** Handles escaping, absolute paths, and URL root changes automatically.
Support GET and POST on the same route:
```python
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
```
**Alternative shortcut syntax:**
```python
@app.get('/login')
def login_get():
return show_the_login_form()
@app.post('/login')
def login_post():
return do_the_login()
```
Create a `static/` folder next to your module:
```
/application.py
/static
/style.css
/script.js
```
Reference in templates:
```python
url_for('static', filename='style.css')
```
Flask serves them at `/static/style.css` during development.
Create a `templates/` folder and add `hello.html`:
```html
<!doctype html>
<title>Hello from Flask</title>
{% if person %}
<h1>Hello {{ person }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
```
Render from Python:
```python
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', person=name)
```
**Template auto-escaping:** Jinja escapes variables by default—use `{{ name|safe }}` only for trusted content.
Work with forms, query strings, and cookies:
```python
from flask import request
@app.route('/search')
def search():
query = request.args.get('q', '') # Query string
return f'Search results for: {query}'
@app.post('/submit')
def submit():
username = request.form['username'] # Form data
return f'Submitted: {username}'
@app.route('/cookies')
def cookies():
username = request.cookies.get('username')
return f'Cookie: {username}'
```
**File uploads:**
```python
file = request.files['file']
file.save('/uploads/' + secure_filename(file.filename))
```
Store user data across requests:
```python
from flask import session
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' # Use os.urandom(24) in production
@app.route('/login', methods=['POST'])
def login():
session['username'] = request.form['username']
return redirect(url_for('index'))
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))
```
Abort with HTTP errors and redirect users:
```python
from flask import abort, redirect, url_for
@app.route('/user/<int:user_id>')
def get_user(user_id):
if user_id not in users:
abort(404)
return users[user_id]
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404
@app.route('/old-path')
def old_path():
return redirect(url_for('new_path'))
```
Build REST APIs with `jsonify()`:
```python
from flask import jsonify
@app.route('/api/user/<int:user_id>')
def get_user_json(user_id):
return jsonify(
id=user_id,
username='john',
email='[email protected]'
)
```
Set cookies, headers, and status codes:
```python
from flask import make_response
@app.route('/')
def index():
resp = make_response(render_template('index.html'))
resp.set_cookie('username', 'the username')
resp.headers['X-Custom-Header'] = 'value'
return resp, 200
```
Visit these URLs to verify:
1. **Don't name your file `flask.py`** — conflicts with Flask package
2. **Always escape user input** in HTML responses
3. **Use trailing slashes consistently** — `/projects/` vs `/projects` behave differently
4. **Set `app.secret_key`** before using sessions
5. **Never commit secrets** to version control—use environment variables
Official documentation: https://flask.palletsprojects.com/en/stable/quickstart/
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/flask-web-development-quickstart/raw