Skip to main content

Flask

Flask is a lightweight and flexible Python Web framework with simplicity and extensibility as its core design philosophy. It does not enforce dependencies on specific libraries or architectures, providing only core features (such as routing and template rendering). Developers can freely choose components like databases and form validation. This "micro-framework" characteristic results in an extremely low learning curve while enabling the easy construction of complex applications through extensions, making it particularly suitable for rapid development of small projects or as a foundation for microservices.

This guide describes how to deploy a Flask application on CloudBase HTTP cloud functions.

Prerequisites

Before you begin, make sure you have:

  • Have Python 3.10 or later versions installed
  • Have a Tencent Cloud account with CloudBase service activated
  • Have basic knowledge of Python and Flask development

Step 1: Create a Flask Application

💡 Tip: If you already have a Flask application, you can skip this step.

Create a Project Directory

mkdir flask-cloudbase
cd flask-cloudbase

Set Up a Virtual Environment

# Create a Virtual Environment
python -m venv env

# Activate the Virtual Environment
# Linux/macOS
source env/bin/activate

# Windows
# env\Scripts\activate

Install Flask

pip install flask

Step 2: Write Application Code

Create the app.py file as the application entry file:

⚠️ Important Notice: CloudBase HTTP cloud function requires the application to listen on port 9000.

import os
from flask import Flask, jsonify, request

app = Flask(__name__)

# Configure Application
app.config['DEBUG'] = os.environ.get('DEBUG', 'False').lower() == 'true'
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'your-secret-key-here')

# Mock Data
users = [
{'id': 1, 'name': 'Zhang San', 'email': 'zhangsan@example.com'},
{'id': 2, 'name': 'Li Si', 'email': 'lisi@example.com'},
{'id': 3, 'name': 'Wang Wu', 'email': 'wangwu@example.com'}
]

@app.route('/')
def hello():
"""Root path handler function"""
return jsonify({
'message': 'Hello from Flask on CloudBase!',
'framework': 'Flask',
'version': '2.3.0'
})

@app.route('/health')
def health_check():
"""Health Check API"""
return jsonify({
'status': 'healthy',
'framework': 'Flask',
'python_version': os.sys.version
})

@app.route('/api/users', methods=['GET'])
def get_users():
"""Get user list (with pagination support)"""
page = request.args.get('page', 1, type=int)
limit = request.args.get('limit', 10, type=int)

# Simple Pagination Logic
start_index = (page - 1) * limit
end_index = start_index + limit
paginated_users = users[start_index:end_index]

return jsonify({
'success': True,
'data': {
'total': len(users),
'page': page,
'limit': limit,
'items': paginated_users
}
})

@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
"""Obtain user by ID"""
user = next((u for u in users if u['id'] == user_id), None)
if not user:
return jsonify({
'success': False,
'message': 'User not found'
}), 404

return jsonify({
'success': True,
'data': user
})

@app.route('/api/users', methods=['POST'])
def create_user():
"""Create New User"""
data = request.get_json()

if not data or 'name' not in data or 'email' not in data:
return jsonify({
'success': False,
'message': 'Name and email are required'
}), 400

# Check whether the email already exists
if any(u['email'] == data['email'] for u in users):
return jsonify({
'success': False,
'message': 'Email already exists'
}), 400

# Create new user
new_user = {
'id': max(u['id'] for u in users) + 1 if users else 1,
'name': data['name'],
'email': data['email']
}
users.append(new_user)

return jsonify({
'success': True,
'data': new_user
}), 201

@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
"""Update User Information"""
user_index = next((i for i, u in enumerate(users) if u['id'] == user_id), None)
if user_index is None:
return jsonify({
'success': False,
'message': 'User not found'
}), 404

data = request.get_json()
if not data:
return jsonify({
'success': False,
'message': 'No data provided'
}), 400

# Check whether the email is already in use by another user
if 'email' in data and any(u['email'] == data['email'] and u['id'] != user_id for u in users):
return jsonify({
'success': False,
'message': 'Email already exists'
}), 400

# Update User Information
if 'name' in data:
users[user_index]['name'] = data['name']
if 'email' in data:
users[user_index]['email'] = data['email']

return jsonify({
'success': True,
'data': users[user_index]
})

@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
Delete User
user_index = next((i for i, u in enumerate(users) if u['id'] == user_id), None)
if user_index is None:
return jsonify({
'success': False,
'message': 'User not found'
}), 404

deleted_user = users.pop(user_index)
return jsonify({
'success': True,
'message': f'User {deleted_user["name"]} deleted successfully'
})

# Error Handling
@app.errorhandler(404)
def not_found(error):
return jsonify({
'success': False,
'message': 'Resource not found'
}), 404

@app.errorhandler(500)
def internal_error(error):
return jsonify({
'success': False,
'message': 'Internal server error'
}), 500

@app.errorhandler(400)
def bad_request(error):
return jsonify({
'success': False,
'message': 'Bad request'
}), 400

if __name__ == '__main__':
# CloudBase HTTP cloud function requires listening on port 9000
app.run(host='0.0.0.0', port=9000, debug=False)

Code Notes

Let's explain the key parts of the above code in detail:

  1. Flask Application Creation

    app = Flask(__name__)

    Create a Flask application instance. The __name__ parameter helps Flask identify the application's location.

  2. Route Decorator

    @app.route('/')
    def hello():
    return jsonify({'message': 'Hello from Flask!'})

    The @app.route('/') decorator defines the URL route, and the corresponding function is executed when the root URL is accessed.

  3. HTTP Method Support

    @app.route('/api/users', methods=['GET', 'POST'])

    Specify the HTTP methods supported by the route via the methods parameter.

  4. Error Handling

    @app.errorhandler(404)
    def not_found(error):
    return jsonify({'error': 'Not Found'}), 404

    Use the @app.errorhandler decorator to handle specific HTTP errors.

Step 3: Test Locally

Start the Application

python app.py

Test the API

After the application starts up, you can test it in the following ways:

# Test Root Path
curl http://localhost:9000/

# Test Health Check
curl http://localhost:9000/health

# Test User List
curl http://localhost:9000/api/users

# Test Pagination
curl "http://localhost:9000/api/users?page=1&limit=2"

# Test Obtain Single User
curl http://localhost:9000/api/users/1

# Test User Creation
curl -X POST http://localhost:9000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"New User","email":"newuser@example.com"}'

# Test User Update
curl -X PUT http://localhost:9000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Updated User","email":"updated@example.com"}'

# Test User Deletion
curl -X DELETE http://localhost:9000/api/users/1

Step 4: Configure Dependencies

Generate the requirements.txt file:

pip freeze > requirements.txt

⚠️ Note: It is only safe to run the above command in a virtual environment. Otherwise, it will generate all installed Python packages on the system, which may prevent the cloud function from starting up properly.

Typical requirements.txt contents:

blinker==1.7.0
click==8.1.7
Flask==2.3.3
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
Werkzeug==2.3.7

Step 5: Create a Startup Script

Create the scf_bootstrap file (without extension):

#!/bin/bash
export PYTHONPATH="./env/lib/python3.10/site-packages:$PYTHONPATH"
/var/lang/python310/bin/python3.10 app.py

Grant execute permission to the startup script:

chmod +x scf_bootstrap

💡 Note:

  • scf_bootstrap is the startup script for CloudBase cloud functions
  • Set the Python path and start up the Flask application
  • Ensure the application listens on port 9000

Step 6: Prepare Deployment Files

Ensure your project directory structure is as follows:

flask-cloudbase/
├── env/ # Virtual Environment (Optional)
├── app.py # Main application file
├── requirements.txt # Dependency List
└── scf_bootstrap # Startup script

Step 7: Deploy to CloudBase HTTP cloud function

Deploy via the Console

  1. Log in to the CloudBase Console
  2. Select your environment and go to the [Cloud Function] page
  3. Click [New Cloud Function]
  4. Select [HTTP cloud function]
  5. Fill in the function name (for example: flask-app)
  6. Select runtime: Python 3.10
  7. Select submission method: Local folder upload
  8. Select the project root directory for function code upload
  9. Automatic Dependency Installation: Enable this option
  10. Click the "Create" button and wait for the deployment to complete.

Deploy via CLI (Coming Soon)

Step 8: Access Your Application

After successful deployment, you can refer to Accessing Cloud Functions via HTTP to configure custom domain access for

You can test the following APIs:

  • Root Path: / - Welcome Message
  • Health Check: /health - Application Status
  • User List: /api/users - Get User List
  • User Details: /api/users/1 - Obtain a Specific User
  • Create User: POST /api/users - Create a New User

Frequently Asked Questions

Q: Why must I use port 9000?

A: The CloudBase HTTP cloud function requires the application to listen on port 9000, which is the standard configuration of the platform.

Q: How do I handle static files?

A: Flask can handle static files using the static folder or by utilizing CDN services.

Q: How do I view application logs?

A: On the CloudBase console's cloud function page, click the function name to go to the details page and view the running logs.

Q: Which Python versions are supported?

A: CloudBase supports Python versions such as 3.6, 3.7, 3.9, 3.10, etc. It is recommended to use Python 3.10.

Q: How do I handle CORS cross-origin issues?

A: You can use the flask-cors extension or manually set response headers to handle cross-origin requests.

Best Practices

1. Environment Variable Management

import os
from flask import Flask

app = Flask(__name__)

# Use Environment Variables
app.config['DEBUG'] = os.environ.get('DEBUG', 'False').lower() == 'true'
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'fallback-secret-key')
app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL')

2. Adding CORS Support

pip install flask-cors
from flask_cors import CORS

app = Flask(__name__)
CORS(app, origins=['https://yourdomain.com'])

3. Log Configuration

import logging
from flask import Flask

app = Flask(__name__)

# Configure Logs
if not app.debug:
logging.basicConfig(level=logging.INFO)
app.logger.info('Flask app startup')

4. Organizing Code with Blueprints

from flask import Blueprint

# Create Blueprint
api_bp = Blueprint('api', __name__, url_prefix='/api')

@api_bp.route('/users')
def get_users():
return jsonify({'users': []})

# Register Blueprint
app.register_blueprint(api_bp)

5. Database Integration

pip install flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemy

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)

class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)

Advanced Features

1. Form Handling

pip install flask-wtf

2. Authentication

pip install flask-login flask-jwt-extended

3. API Documentation

pip install flask-restx

4. Cache Support

pip install flask-caching

Next Steps