generated from dellevin/template
功能完善1
This commit is contained in:
214
flask-dev-api/app.py
Normal file
214
flask-dev-api/app.py
Normal file
@@ -0,0 +1,214 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
整合工具集主入口
|
||||
只负责创建 Flask 应用、注册蓝图和启动服务
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
from flask import Flask, render_template, jsonify, g, request
|
||||
|
||||
from config import PORT
|
||||
from blueprints import pin_tu_bp, base64_bp, down_video_bp, fen_ci_bp, content_tag_bp, chmod_calc_bp, json_format_bp, qr_code_bp, http_status_bp, url_parser_bp, token_gen_bp, sovits_tts_bp, stt_bp, ai_dubbing_bp, rvc_bp
|
||||
from utils.stats_db import init_db, record_call, get_total_count, get_avg_duration, get_daily_counts, get_monthly_counts, get_available_years, get_available_months, get_daily_counts_by_month, get_hourly_counts, get_endpoint_stats, get_today_count, get_yesterday_count, get_month_count, get_success_rate, get_duration_distribution, get_slowest_endpoints, get_week_compare, get_recent_calls, get_active_days
|
||||
from utils.stats_db import ALLOWED_TABLES, get_table_info, get_table_rows, get_table_count, insert_row, update_row, delete_rows, clear_table
|
||||
|
||||
TOOL_COUNT = 15
|
||||
|
||||
|
||||
def create_app():
|
||||
# 打包模式下,模板和静态文件在 sys._MEIPASS 临时目录
|
||||
if getattr(sys, 'frozen', False):
|
||||
base = sys._MEIPASS
|
||||
app = Flask(__name__,
|
||||
template_folder=os.path.join(base, 'templates'),
|
||||
static_folder=os.path.join(base, 'static'))
|
||||
else:
|
||||
app = Flask(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
# 主页
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# 数据管理页面
|
||||
@app.route('/data-manage')
|
||||
def data_manage():
|
||||
return render_template('data_manage.html')
|
||||
|
||||
# 仪表盘统计接口
|
||||
@app.route('/api/stats')
|
||||
def api_stats():
|
||||
year = request.args.get('year')
|
||||
if not year:
|
||||
year = datetime.now().strftime('%Y')
|
||||
return jsonify({
|
||||
'tool_count': TOOL_COUNT,
|
||||
'total_calls': get_total_count(),
|
||||
'avg_duration': get_avg_duration(),
|
||||
'daily': get_daily_counts(30),
|
||||
'years': get_available_years(),
|
||||
'months': get_available_months(year)
|
||||
})
|
||||
|
||||
# 某月每日调用统计
|
||||
@app.route('/api/stats/daily-by-month')
|
||||
def api_stats_daily_by_month():
|
||||
year = request.args.get('year', datetime.now().strftime('%Y'))
|
||||
month = request.args.get('month', datetime.now().strftime('%m'))
|
||||
return jsonify({
|
||||
'year': year,
|
||||
'month': month,
|
||||
'daily': get_daily_counts_by_month(year, int(month))
|
||||
})
|
||||
|
||||
# 每天按小时统计
|
||||
@app.route('/api/stats/hourly')
|
||||
def api_stats_hourly():
|
||||
date_str = request.args.get('date')
|
||||
if not date_str:
|
||||
date_str = datetime.now().strftime('%Y-%m-%d')
|
||||
return jsonify({
|
||||
'date': date_str,
|
||||
'hourly': get_hourly_counts(date_str)
|
||||
})
|
||||
|
||||
# 接口调用分布
|
||||
@app.route('/api/stats/endpoints')
|
||||
def api_stats_endpoints():
|
||||
date = request.args.get('date')
|
||||
return jsonify({'endpoints': get_endpoint_stats(date)})
|
||||
|
||||
# 高级统计数据
|
||||
@app.route('/api/stats/advanced')
|
||||
def api_stats_advanced():
|
||||
return jsonify({
|
||||
'today_count': get_today_count(),
|
||||
'yesterday_count': get_yesterday_count(),
|
||||
'month_count': get_month_count(),
|
||||
'success_rate': get_success_rate(),
|
||||
'duration_distribution': get_duration_distribution(),
|
||||
'slowest_endpoints': get_slowest_endpoints(),
|
||||
'week_compare': get_week_compare(),
|
||||
'recent_calls': get_recent_calls(),
|
||||
'active_days': get_active_days()
|
||||
})
|
||||
|
||||
# ===== 数据管理 API =====
|
||||
|
||||
@app.route('/api/db/tables')
|
||||
def api_db_tables():
|
||||
return jsonify({'tables': get_table_info()})
|
||||
|
||||
@app.route('/api/db/<table>')
|
||||
def api_db_list(table):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
page = int(request.args.get('page', 1))
|
||||
page_size = int(request.args.get('page_size', 20))
|
||||
search = request.args.get('search', '').strip()
|
||||
rows = get_table_rows(table, page, page_size, search)
|
||||
total = get_table_count(table, search)
|
||||
return jsonify({'success': True, 'rows': rows, 'total': total, 'page': page, 'page_size': page_size})
|
||||
|
||||
@app.route('/api/db/<table>', methods=['POST'])
|
||||
def api_db_insert(table):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'success': False, 'error': '缺少数据'}), 400
|
||||
new_id = insert_row(table, data)
|
||||
if new_id:
|
||||
return jsonify({'success': True, 'id': new_id})
|
||||
return jsonify({'success': False, 'error': '插入失败'}), 400
|
||||
|
||||
@app.route('/api/db/<table>/<int:row_id>', methods=['PUT'])
|
||||
def api_db_update(table, row_id):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'success': False, 'error': '缺少数据'}), 400
|
||||
if update_row(table, row_id, data):
|
||||
return jsonify({'success': True})
|
||||
return jsonify({'success': False, 'error': '更新失败'}), 400
|
||||
|
||||
@app.route('/api/db/<table>/<int:row_id>', methods=['DELETE'])
|
||||
def api_db_delete(table, row_id):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
deleted = delete_rows(table, [row_id])
|
||||
return jsonify({'success': deleted > 0})
|
||||
|
||||
@app.route('/api/db/<table>/delete-batch', methods=['POST'])
|
||||
def api_db_delete_batch(table):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
data = request.get_json()
|
||||
ids = data.get('ids', []) if data else []
|
||||
if not ids:
|
||||
return jsonify({'success': False, 'error': '未选择记录'}), 400
|
||||
deleted = delete_rows(table, ids)
|
||||
return jsonify({'success': True, 'deleted': deleted})
|
||||
|
||||
@app.route('/api/db/<table>/clear', methods=['POST'])
|
||||
def api_db_clear(table):
|
||||
if table not in ALLOWED_TABLES:
|
||||
return jsonify({'success': False, 'error': '不允许的表名'}), 400
|
||||
deleted = clear_table(table)
|
||||
return jsonify({'success': True, 'deleted': deleted})
|
||||
|
||||
# 请求计时
|
||||
@app.before_request
|
||||
def _start_timer():
|
||||
g.start_time = time.time()
|
||||
|
||||
# 请求追踪
|
||||
@app.after_request
|
||||
def _track_request(response):
|
||||
path = request.path
|
||||
if path == '/' or path.startswith('/static/') or path.startswith('/api/'):
|
||||
return response
|
||||
if request.method != 'POST':
|
||||
return response
|
||||
duration_ms = (time.time() - g.start_time) * 1000
|
||||
record_call(path, request.method, response.status_code, duration_ms)
|
||||
return response
|
||||
|
||||
# 注册蓝图
|
||||
app.register_blueprint(pin_tu_bp)
|
||||
app.register_blueprint(base64_bp)
|
||||
app.register_blueprint(down_video_bp)
|
||||
app.register_blueprint(fen_ci_bp)
|
||||
app.register_blueprint(content_tag_bp)
|
||||
app.register_blueprint(chmod_calc_bp)
|
||||
app.register_blueprint(json_format_bp)
|
||||
app.register_blueprint(qr_code_bp)
|
||||
app.register_blueprint(http_status_bp)
|
||||
app.register_blueprint(url_parser_bp)
|
||||
app.register_blueprint(token_gen_bp)
|
||||
app.register_blueprint(sovits_tts_bp)
|
||||
app.register_blueprint(stt_bp)
|
||||
app.register_blueprint(ai_dubbing_bp)
|
||||
app.register_blueprint(rvc_bp)
|
||||
|
||||
return app
|
||||
|
||||
app = create_app()
|
||||
|
||||
|
||||
def start_flask():
|
||||
"""供桌面启动器调用,以非调试模式运行 Flask"""
|
||||
a = create_app()
|
||||
a.run(host='127.0.0.1', port=PORT, use_reloader=False, threaded=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# import webbrowser
|
||||
# import threading as _t
|
||||
# _t.Timer(1, webbrowser.open, args=[f'http://127.0.0.1:{PORT}']).start()
|
||||
app.run(debug=True, host='0.0.0.0', port=PORT, threaded=True)
|
||||
Reference in New Issue
Block a user