From b6845cbd09137cd938d8b093f9598fded716b9ac Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Mon, 1 Aug 2022 16:10:50 +0800 Subject: [PATCH] feat: api server framework --- Basis/Api.py | 36 ++++++++++++++++++++++++++++++++++++ Basis/Compile.py | 4 ++-- Basis/Constant.py | 10 +++++----- Basis/Logger.py | 4 ++-- Dockerfile | 2 +- Tester/Plugin.py | 6 +++--- 6 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 Basis/Api.py diff --git a/Basis/Api.py b/Basis/Api.py new file mode 100644 index 0000000..213576b --- /dev/null +++ b/Basis/Api.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import json +from gevent import pywsgi +from Basis.Logger import logging +from Basis.Constant import Version +from flask import Flask, Response, request + +webPath = '/' # root of api server +webApi = Flask(__name__) # init flask server + + +def jsonResponse(data: dict) -> Response: + return Response(json.dumps(data), mimetype = 'application/json') + + +@webApi.route('/version', methods = ['GET']) +def getVersion() -> Response: + logging.debug('get version -> %s' + Version) + return jsonResponse({ + 'version': Version + }) + + +def startServer(apiPort: int = 7839, apiToken: str = '', isWsgi: bool = True) -> None: + global webApi, webPath + logging.warning( + 'start api server at http://:%i/' % apiPort + (' (enable WSGI)' if isWsgi else '') + ) + logging.warning('server ' + ('without token' if apiToken == '' else 'api token -> %s' % apiToken)) + if not isWsgi: + webApi.run(host = '0.0.0.0', port = apiPort, debug = True, threaded = True) # ordinary server (for debug) + else: + server = pywsgi.WSGIServer(('0.0.0.0', apiPort), webApi) # powered by gevent + server.serve_forever() diff --git a/Basis/Compile.py b/Basis/Compile.py index e0e5f7f..c599130 100644 --- a/Basis/Compile.py +++ b/Basis/Compile.py @@ -5,7 +5,7 @@ import compileall from Basis.Logger import logging -def startCompile(dirRange: str = '/'): +def startCompile(dirRange: str = '/') -> None: for optimize in [-1, 1, 2]: - logging.warning('start compile -> %s (optimize = %i)' %(dirRange, optimize)) + logging.warning('start python compile -> %s (optimize = %i)' % (dirRange, optimize)) compileall.compile_dir(dirRange, quiet = 1, maxlevels = 256, optimize = optimize) diff --git a/Basis/Constant.py b/Basis/Constant.py index f974176..4fc0eb6 100644 --- a/Basis/Constant.py +++ b/Basis/Constant.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -version = 'dev' +Version = 'dev' # Shadowsocks Info ssMethods = { # methods support of different Shadowsocks project @@ -69,7 +69,7 @@ ssAllMethods = set() ssAllMethods = sorted(list(ssAllMethods)) # methods of Shadowsocks # Plugin Info -plugins = { +Plugins = { 'simple-obfs': ['obfs-local', 'obfs-server'], 'simple-tls': ['simple-tls'], 'v2ray': ['v2ray-plugin'], @@ -84,9 +84,9 @@ plugins = { 'gun': ['gun-plugin'], } -plugins = {x: [plugins[x][0], plugins[x][1 if len(plugins[x]) == 2 else 0]] for x in plugins} -plugins = {x: {'client': plugins[x][0], 'server': plugins[x][1]} for x in plugins} # format plugins info -pluginClients = [plugins[x]['client'] for x in plugins] # plugin client list -> obfs-local / simple-tls / ... +Plugins = {x: [Plugins[x][0], Plugins[x][1 if len(Plugins[x]) == 2 else 0]] for x in Plugins} +Plugins = {x: {'client': Plugins[x][0], 'server': Plugins[x][1]} for x in Plugins} # format plugins info +pluginClients = [Plugins[x]['client'] for x in Plugins] # plugin client list -> obfs-local / simple-tls / ... # ShadowsocksR Info ssrMethods = [ # methods of ShadowsocksR diff --git a/Basis/Logger.py b/Basis/Logger.py index 764bf9e..383cee2 100644 --- a/Basis/Logger.py +++ b/Basis/Logger.py @@ -6,8 +6,8 @@ import logging from colorlog import ColoredFormatter logFile = 'runtime.log' -# logLevel = logging.DEBUG -logLevel = logging.WARNING +logLevel = logging.DEBUG +# logLevel = logging.WARNING dateFormat = '%Y-%m-%d %H:%M:%S' logFormat = '[%(asctime)s] [%(levelname)s] %(message)s (%(module)s.%(funcName)s)' logging.basicConfig( diff --git a/Dockerfile b/Dockerfile index b66a330..138cdb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -478,7 +478,7 @@ FROM python:3.10-alpine3.16 RUN \ apk add --no-cache boost-program_options c-ares \ ca-certificates glib libev libsodium libstdc++ mbedtls pcre redis && \ - pip3 --no-cache-dir install colorlog flask IPy pysocks redis requests && \ + pip3 --no-cache-dir install colorlog flask gevent IPy pysocks redis requests && \ rm -rf $(find / -name '__pycache__') && \ echo "daemonize yes" >> /etc/redis.conf COPY --from=asset /asset / diff --git a/Tester/Plugin.py b/Tester/Plugin.py index 6eeddd1..249c2a5 100644 --- a/Tester/Plugin.py +++ b/Tester/Plugin.py @@ -6,7 +6,7 @@ import re import json from Basis.Logger import logging from Basis.Process import Process -from Basis.Constant import plugins +from Basis.Constant import Plugins from Tester.Settings import Settings from Basis.Functions import genFlag, hostFormat, getAvailablePort @@ -333,11 +333,11 @@ def load(proxyType: str): 'type': pluginType, 'caption': pluginTest, 'server': { # plugin info for server - 'type': plugins[pluginType]['server'], + 'type': Plugins[pluginType]['server'], 'param': paramFill(pluginTestInfo[0]), }, 'client': { # plugin info for client - 'type': plugins[pluginType]['client'], + 'type': Plugins[pluginType]['client'], 'param': paramFill(pluginTestInfo[1]), }, 'inject': ssInject if proxyType == 'ss' else trojanInject # for some special plugins