Flask
Flask æ¯ä¸ä¸ªè½»é级ãçµæ´»ç Python Web æ¡æ¶ï¼ä»¥ç®æ´å坿©å±æ§ä¸ºæ ¸å¿è®¾è®¡ç念ãå®ä¸å¼ºå¶ä¾èµç¹å®åºææ¶æï¼ä» æä¾æ ¸å¿åè½ï¼å¦è·¯ç±ãæ¨¡æ¿æ¸²æï¼ï¼å¼åè å¯èªç±éé æ°æ®åºã表åéªè¯çç»ä»¶ãè¿ç§"å¾®æ¡æ¶"ç¹æ§ä½¿å ¶å¦ä¹ ææ¬æä½ï¼åæ¶è½éè¿æ©å±è½»æ¾æå»ºå¤æåºç¨ï¼ç¹å«éåå¿«éå¼åå°åé¡¹ç®æä½ä¸ºå¾®æå¡åºç¡ã
æ¬æåä»ç»å¦ä½å¨ CloudBase HTTP äºå½æ°ä¸é¨ç½² Flask åºç¨ç¨åºã
åç½®æ¡ä»¶â
å¨å¼å§ä¹åï¼è¯·ç¡®ä¿æ¨å·²ç»ï¼
- å®è£ äº Python 3.10 ææ´é«çæ¬
- æ¥æè ¾è®¯äºè´¦å·å¹¶å建äºäºå¼åç¯å¢
- äºè§£åºæ¬ç Python å Flask å¼åç¥è¯
ç¬¬ä¸æ¥ï¼å建 Flask åºç¨â
ð¡ æç¤ºï¼å¦ææ¨å·²ç»æä¸ä¸ª Flask åºç¨ï¼å¯ä»¥è·³è¿æ¤æ¥éª¤ã
å建项ç®ç®å½â
mkdir flask-cloudbase
cd flask-cloudbase
设置èæç¯å¢â
# å建èæç¯å¢
python -m venv env
# æ¿æ´»èæç¯å¢
# Linux/macOS
source env/bin/activate
# Windows
# env\Scripts\activate
å® è£ Flaskâ
pip install flask
ç¬¬äºæ¥ï¼ç¼ååºç¨ä»£ç â
å建 app.py æä»¶ä½ä¸ºåºç¨çå
¥å£æä»¶ï¼
â ï¸ éè¦æç¤ºï¼CloudBase HTTP äºå½æ°è¦æ±åºç¨çå¬ 9000 端å£ã
import os
from flask import Flask, jsonify, request
app = Flask(__name__)
# é
ç½®åºç¨
app.config['DEBUG'] = os.environ.get('DEBUG', 'False').lower() == 'true'
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'your-secret-key-here')
# æ¨¡ææ°æ®
users = [
{'id': 1, 'name': 'å¼ ä¸', 'email': 'zhangsan@example.com'},
{'id': 2, 'name': 'æå', 'email': 'lisi@example.com'},
{'id': 3, 'name': 'çäº', 'email': 'wangwu@example.com'}
]
@app.route('/')
def hello():
"""æ ¹è·¯å¾å¤ç彿°"""
return jsonify({
'message': 'Hello from Flask on CloudBase!',
'framework': 'Flask',
'version': '2.3.0'
})
@app.route('/health')
def health_check():
"""å¥åº·æ£æ¥æ¥å£"""
return jsonify({
'status': 'healthy',
'framework': 'Flask',
'python_version': os.sys.version
})
@app.route('/api/users', methods=['GET'])
def get_users():
"""è·åç¨æ·åè¡¨ï¼æ¯æå页ï¼"""
page = request.args.get('page', 1, type=int)
limit = request.args.get('limit', 10, type=int)
# ç®åå页é»è¾
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):
"""æ ¹æ® 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():
"""å建æ°ç¨æ·"""
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
# æ£æ¥é®ç®±æ¯å¦å·²åå¨
if any(u['email'] == data['email'] for u in users):
return jsonify({
'success': False,
'message': 'Email already exists'
}), 400
# å建æ°ç¨æ·
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):
"""æ´æ°ç¨æ·ä¿¡æ¯"""
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
# æ£æ¥é®ç®±æ¯å¦è¢«å
¶ä»ç¨æ·ä½¿ç¨
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
# æ´æ°ç¨æ·ä¿¡æ¯
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):
"""å é¤ç¨æ·"""
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'
})
# é误å¤ç
@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 äºå½æ°è¦æ±çå¬ 9000 端å£
app.run(host='0.0.0.0', port=9000, debug=False)
代ç 说æâ
让æä»¬è¯¦ç»è§£éä¸è¿°ä»£ç çå ³é®é¨åï¼
-
Flask åºç¨å建
app = Flask(__name__)å建 Flask åºç¨å®ä¾ï¼
__name__åæ°å¸®å© Flask è¯å«åºç¨ç¨åºçä½ç½®ã -
è·¯ç±è£ 饰å¨
@app.route('/')def hello():return jsonify({'message': 'Hello from Flask!'})@app.route('/')è£ é¥°å¨å®ä¹ URL è·¯ç±ï¼å½è®¿é®æ ¹ URL æ¶æ§è¡å¯¹åºå½æ°ã -
HTTP æ¹æ³æ¯æ
@app.route('/api/users', methods=['GET', 'POST'])éè¿
methodsåæ°æå®è·¯ç±æ¯æç HTTP æ¹æ³ã -
é误å¤ç
@app.errorhandler(404)def not_found(error):return jsonify({'error': 'Not Found'}), 404使ç¨
@app.errorhandlerè£ é¥°å¨å¤çç¹å®ç HTTP é误ã
ç¬¬ä¸æ¥ï¼æ¬å°æµè¯â
å¯å¨åºç¨â
python app.py
æµè¯ API æ¥å£â
åºç¨å¯å¨åï¼æ¨å¯ä»¥éè¿ä»¥ä¸æ¹å¼æµè¯ï¼
# æµè¯æ ¹è·¯å¾
curl http://localhost:9000/
# æµè¯å¥åº·æ£æ¥
curl http://localhost:9000/health
# æµè¯ç¨æ·å表
curl http://localhost:9000/api/users
# æµè¯å页
curl "http://localhost:9000/api/users?page=1&limit=2"
# æµè¯è·ååä¸ªç¨æ·
curl http://localhost:9000/api/users/1
# æµè¯åå»ºç¨æ·
curl -X POST http://localhost:9000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"æ°ç¨æ·","email":"newuser@example.com"}'
# æµè¯æ´æ°ç¨æ·
curl -X PUT http://localhost:9000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"æ´æ°ç¨æ·","email":"updated@example.com"}'
# æµè¯å é¤ç¨æ·
curl -X DELETE http://localhost:9000/api/users/1
ç¬¬åæ¥ï¼é ç½®ä¾èµé¡¹â
çæ requirements.txt æä»¶ï¼
pip freeze > requirements.txt
â ï¸ æ³¨æï¼åªæå¨èæç¯å¢ä¸è¿è¡ä¸è¿°å½ä»¤ææ¯å®å ¨çï¼å¦åå®å°çæç³»ç»ä¸ææå·²å®è£ ç Python å ï¼å¯è½å¯¼è´äºå½æ°æ æ³æ£å¸¸å¯å¨ã
å
¸åç requirements.txt å
容ï¼
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
ç¬¬äºæ¥ï¼å建å¯å¨èæ¬â
ð¡ æ³¨æï¼
- å¨ windows ä¸å建
scf_bootstrapæä»¶æ¶ï¼ä¼å 使ç¨nano scf_bootstrapæèvim scf_bootstrapå建- å¨ windows ä¸ä½¿ç¨ vscode å建
scf_bootstrapæä»¶æ¶ï¼é¨ç½²å° HTTP äºå½æ°å¯è½ä¼æ¥é:scf_bootstrapæä»¶ä¸åå¨- è¿ä¸ªé误æ¯å ä¸ºèæ¬æä»¶å å«äº Windows æ ¼å¼çå车符ï¼^Mï¼ï¼å¯¼è´ Linux æ æ³æ£ç¡®è¯å«è§£éå¨è·¯å¾ãè¿æ¯ WSL ä¸å¸¸è§çé®é¢
å建 scf_bootstrap æä»¶ï¼æ æ©å±åï¼ï¼
#!/bin/bash
# 设置 Python ä¾èµå 载路å¾ï¼æä»¬é»è®¤è®¾ç½®å¨ third_party ç®å½
export PYTHONPATH="./third_party:$PYTHONPATH"
/var/lang/python310/bin/python3.10 app.py
为å¯å¨èæ¬æ·»å æ§è¡æéï¼
chmod +x scf_bootstrap
ð¡ 说æï¼
scf_bootstrapæ¯ CloudBase äºå½æ°çå¯å¨èæ¬- 设置 Python è·¯å¾å¹¶å¯å¨ Flask åºç¨
- ç¡®ä¿åºç¨çå¬ 9000 端å£