python3 写一个主服务与子服务的工具

72 阅读2分钟

启动时候 可以配置属性 管理员权限运行旧可以存C盘

打包参数 点击运行后没有图标 可以在任务管理器进行管理进程

支持电脑首屏截图 /api/color 取鼠标所在位置颜色

支持自定义 mock 接口的数据响应

# -*- coding: utf-8 -*-
from flask import Flask, jsonify, request
from flask_cors import CORS
import subprocess
import threading
import os
import signal
import time
import pyautogui
from PIL import ImageGrab
import pyperclip
'''

pyinstaller -F --noconsole MainApp.py   --icon=itool.ico 
pyinstaller -F --noconsole Color.py   --icon=itool.ico 
'''


# 全局变量map,用于副应用
map_data = {}

# 主Flask应用
app_main = Flask(__name__)
CORS(app_main)

# 副Flask应用
app_sub = Flask('sub_app')
CORS(app_sub)

# 副应用的路由
@app_sub.route('/<path:path>', methods=['GET', 'POST'])
def get_path_value(path):
    print(path)
    global map_data
    print(path in map_data) 
    print(map_data)
    if path in map_data:
        return map_data[path]
    else:
        return jsonify({'url': request.url, 'message': '未设置参数'}), 404

# 主应用的路由
@app_main.route('/api/cmd', methods=['POST'])
def cmd_execution():
    cmd = request.json.get('cmd')
    if not cmd:
        return jsonify({'error': 'Missing "cmd" parameter'}), 400
    result = subprocess.getoutput(cmd)
    return jsonify({'result': result})

@app_main.route('/api/close', methods=['POST','GET'])
def close_port():
    # 注意:这里只是一个模拟关闭的示例,真实情况下需要更复杂的处理
    port = request.json.get('port')
    if not port:
        return jsonify({'error': 'Missing "port" parameter'}), 400
    print(f"Closing process on port {port} (simulated)")
    return jsonify({'message': f"Closing process on port {port} (simulated)"})

# 省略了其他路由的实现,如文件操作等
@app_main.route('/api/color', methods=['POST','GET'])
def get_color_at():
    # 获取鼠标当前位置
    x, y = pyautogui.position() 
    img = ImageGrab.grab() 
    rgb_img = img.load()
    r, g, b = rgb_img[x, y] 
    hex_color = "#{:02x}{:02x}{:02x}".format(r, g, b)
    pyperclip.copy(hex_color) 
    return  jsonify({'hex_color': 'hex_color', 'rgba': (r, g, b)}), 200   

@app_main.route('/api/mock/async', methods=['POST'])
def update_map():
    # 使用请求对象获取 JSON 数据
    data = request.get_json()
    print(data)
    global map_data
    map_data = data
    return jsonify({'status': 'success', 'message': 1}), 200



# 启动Flask应用的函数
def run_app(app, port):
    app.run(host='0.0.0.0', port=port, threaded=True)

# 线程目标函数,用于启动Flask应用
def start_flask_app(app, port):
    try:
        run_app(app, port)
    except Exception as e:
        print(f"Error running Flask app on port {port}: {e}")

# 启动两个Flask应用
if __name__ == '__main__':
    # 使用线程启动副应用
    sub_app_thread = threading.Thread(target=start_flask_app, args=(app_sub, 9000))
    sub_app_thread.start()

    # 等待副应用启动后再启动主应用(可选,根据实际情况调整)
    time.sleep(1)

    # 启动主应用
    run_app(app_main, 1001)

    # 注意:由于主线程会阻塞在app_main.run(),副应用线程将在主应用关闭后结束
    # 在生产环境中,你应该使用更健壮的进程管理方式,如Gunicorn、uWSGI等