init commit

This commit is contained in:
BryantHe 2023-08-10 12:27:18 +08:00
commit 56f93165ba
21 changed files with 457 additions and 0 deletions

5
.apiflaskenv Normal file
View File

@ -0,0 +1,5 @@
FLASK_APP=starter:app
FLASK_RUN_HOST="127.0.0.1"
FLASK_RUN_PORT=5000
# production or development etc.
FLASK_DEBUG=production

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
.venv

162
.gitignore vendored Normal file
View File

@ -0,0 +1,162 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
*.env
*.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

6
Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM python:3.11
RUN python3 -m pip uninstall -y chassis
# 拷贝依赖
COPY requirements.txt .
# 安装依赖
RUN python3 -m pip install -i https://mirrors.cloud.tencent.com/pypi/simple --trusted-host=mirrors.cloud.tencent.com -r requirements.txt

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# pzx-web-api
pzx 专属的 web api 服务

44
app/__init__.py Normal file
View File

@ -0,0 +1,44 @@
import os
# from dotenv import load_dotenv
from apiflask import APIFlask
from chassis.flask_nameko import FlaskPooledClusterRpcProxy
from app.config.config import Config
from app.util.common import basedir
rpc = FlaskPooledClusterRpcProxy()
def register_blueprints(apiflask_app):
from app.api.v1 import create_v1
apiflask_app.register_blueprint(create_v1(), url_prefix='/v1')
def load_app_config(app):
"""
加载环境变量和配置类到app config
"""
# 读取 .env
# load_dotenv(os.path.join(basedir, '.apiflask.env'))
# 读取配置类
app.config.from_object('app.config.config.Config')
def load_rpc_client(apiflask_app):
apiflask_app.config.update(dict(
NAMEKO_AMQP_URI=str(Config.RABBITMQ_URI)
))
rpc.init_app(apiflask_app)
def create_app():
# http wsgi server 托管启动需指定读取环境配置
# load_dotenv(os.path.join(basedir, '.apiflaskenv'))
app = APIFlask(__name__)
load_app_config(app)
register_blueprints(app)
# load_rpc_client(app)
return app

0
app/api/__init__.py Normal file
View File

16
app/api/v1/__init__.py Normal file
View File

@ -0,0 +1,16 @@
from apiflask import APIBlueprint
from app.api.v1.api import api
def create_v1():
bp_v1 = APIBlueprint('v1', __name__)
bp_v1.register_blueprint(api, url_prefix='/api')
return bp_v1

80
app/api/v1/api.py Normal file
View File

@ -0,0 +1,80 @@
import socket
import platform
import psutil
from apiflask import APIBlueprint
api = APIBlueprint('api', __name__)
@api.get('/hello')
def hello():
result_one = f'我是您的专属接口提供服务器: {socket.gethostname()}'
result_two = f'我的机器参数如下'
result_three = f'操作系统:{platform.system()}CPU 核数:{psutil.cpu_count()},目前 CPU 占用率: {psutil.cpu_percent()}'
text = """
<style type="text/css">
* {
padding: 0;
margin: 0;
}
div {
padding: 4px 48px;
}
a {
color: black;
cursor: pointer;
text-decoration: none
}
a:hover {
text-decoration: None;
}
body {
background: #fff;
font-family:
"Century Gothic", "Microsoft yahei";
color: #333;
font-size: 18px;
}
h1 {
font-size: 100px;
font-weight: normal;
margin-bottom: 12px;
}
p {
line-height: 1.6em;
font-size: 42px
}
</style>
<div style="padding: 24px 48px;">
<p>
<a href="" target="_Blank">您好PZX 大人</a>
<br />
<span style="font-size:30px">
<a href=""> """ + result_one + """</a>
</span>
<br />
<span style="font-size:25px">
<a href=""> """ + result_two + """</a>
</span>
<br />
<span style="font-size:20px">
<a href=""> """ + result_three + """</a>
<br />
<a href=""> """ + result_three + """</a>
<br />
<a href=""> """ + f'总内存 {psutil.virtual_memory().total / 1024 / 1024},使用中内存:{round(psutil.virtual_memory().used / 1024 / 1024, 2)}' + """</a>
<br />
<a href=""> """ + f'磁盘总空间 {round(psutil.disk_usage("/").total / 1024 / 1024 / 1024, 2)},磁盘使用情况:{round(psutil.disk_usage("/").used / 1024 / 1024 / 1024, 2)}' + """</a>
</span>
</p>
</div>
"""
return text

View File

View File

51
app/api/v1/schema/api.py Normal file
View File

@ -0,0 +1,51 @@
from apiflask import Schema
from apiflask.fields import Integer, String, Boolean, Nested, List
class LoginIn(Schema):
username = String(required=True)
password = String(required=True)
tenantId = String(required=True)
uuid = String()
code = String()
class LoginNestedOut(Schema):
token = String()
class LoginOut(Schema):
code = Integer()
msg = String()
data = Nested(LoginNestedOut)
class CaptchaImageNestedOut(Schema):
captchaEnabled = Boolean()
img = String()
uuid = String()
class CaptchaImageOut(Schema):
code = Integer()
msg = String()
data = Nested(CaptchaImageNestedOut)
class TenantOut(Schema):
companyName = String()
domain = String()
tenantId = String()
class TenantsNestedOut(Schema):
tenantEnabled = Boolean()
voList = List(Nested(TenantOut))
class TenantsOut(Schema):
code = Integer()
msg = String()
data = Nested(TenantsNestedOut)

0
app/config/__init__.py Normal file
View File

11
app/config/config.py Normal file
View File

@ -0,0 +1,11 @@
import os
from chassis.config import Config as _Config
class Config(_Config):
"""
配置
"""
RABBITMQ_URI = os.getenv('RABBITMQ_URI')

0
app/util/__init__.py Normal file
View File

15
app/util/common.py Normal file
View File

@ -0,0 +1,15 @@
import os
from itertools import groupby
from operator import itemgetter
def split_group(dict_list, key):
dict_list.sort(key=itemgetter(key))
tmps = groupby(dict_list, itemgetter(key))
result = []
for key, group in tmps:
result.append({key: list(group)})
return result
basedir = os.getcwd()

23
docker-compose.yml Normal file
View File

@ -0,0 +1,23 @@
version: "3"
services:
pzx-web-api:
build:
context: .
dockerfile: ./Dockerfile
container_name: pzx-web-api
hostname: pzx-web-api
ports:
- "5010:5000"
volumes:
- .:/app
environment:
TZ: "Asia/Shanghai"
LOG_LEVEL: "DEBUG"
env_file:
- .apiflaskenv
- .apiflask.env
working_dir: /app
tty: true
restart: always
command: ["sh", "docker-deploy.sh"]

1
docker-deploy.sh Normal file
View File

@ -0,0 +1 @@
gunicorn -c gunicorn.conf.py starter:app

22
gunicorn.conf.py Normal file
View File

@ -0,0 +1,22 @@
import multiprocessing
from gevent import monkey
monkey.patch_all()
bind = "0.0.0.0:5000"
worker_class = 'gevent'
# 设置最大并发量
daemon = False
debug = False
worker_connections = 2000
workers = multiprocessing.cpu_count() * 2 + 1
# 指定每个工作者的线程数
threads = 10
# pidfile = "/var/run/gunicorn.pid"
# accesslog = '/var/log/gunicorn_access.log'
# errorlog = '/var/log/gunicorn_error.log'
# 设置日志记录水平
loglevel = 'warning'

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
git+https://gitea.bearcatlog.com/BryantStudio/chassis.git@main#egg=chassis[apiflask,nameko]
psutil

14
starter.py Normal file
View File

@ -0,0 +1,14 @@
from app import create_app
app = create_app()
if __name__ == "__main__":
app.logger.warning(
"""
----------------------------
| app.run() => apiflask run |
----------------------------
"""
)
app.run()