本文已参与「新人创作礼」活动,一起开启掘金创作之路。
项目背景:导入Excel表,然后生成对应的指定格式的新的Excel表 依赖包版本如下:
[tool.poetry.dependencies]
python = "^3.8"
shici = {git = "https://gitee.com/waketzheng/shici.git"}
xlwt = "^1.3.0"
xlutils = "^2.0.0"
xlrd = "^2.0.1"
openpyxl = "^3.0.9"
fastapi = "^0.75.0"
python-dotenv = "^0.19.2"
python-multipart = "^0.0.5"
uvicorn = "^0.17.6"
main文件内容如下:
#!/usr/bin/env python
"""
Usage::
$ ./main.py r # Start server
"""
import re
import traceback
from datetime import datetime
from pathlib import Path
import shici
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from routers import api
from settings import DEBUG, MEDIA_ROOT, PORT
RE_VERSION = re.compile(r'version = "([.\w]+)"')
if not MEDIA_ROOT.exists():
MEDIA_ROOT.mkdir()
def get_version(filename: str = "pyproject.toml") -> str:
if not (p := Path(__file__).parent / filename).exists():
p = p.resolve().parent.parent / filename
if m := RE_VERSION.search(p.read_text()):
return m.group(1) # type: ignore
return "1.0.0"
CURRENT_VERSION = get_version()
app_kwargs: dict = {"version": get_version()}
if DEBUG:
app_kwargs["title"] = "Salary Tip--调试版"
app_kwargs.update(debug=True)
else:
app_kwargs["title"] = "洪荒之力-- Make it easy"
app_kwargs["redoc_url"] = None
app = FastAPI(**app_kwargs)
app.mount("/media", StaticFiles(directory="media"), name="media")
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start = datetime.now()
try:
response = await call_next(request)
except AssertionError as e:
response = JSONResponse({"detail": str(e)}, 400)
except Exception:
code = int(datetime.now().timestamp())
error = traceback.format_exc()
print(code, f"{request.url = }", error)
if request.url.path.split("/")[-1].startswith("_"):
# 内部接口直接返回错误详情
response = JSONResponse({"detail": f"{code=}; {error = }"}, 500)
else:
response = JSONResponse({"detail": f"数据异常,请刷新页面后重试!({code})"}, 500)
end = datetime.now()
process_time = end - start
cost = f"{round(process_time.total_seconds()*1000, 3)} ms"
print(f"{start} --> {end} || Cost: {cost}")
response.headers["X-Process-Time"] = cost
response.headers["version"] = CURRENT_VERSION
return response
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# routers
app.include_router(api.router, prefix="/api", tags=["api"])
@app.get("/")
async def home(request: Request):
ip = request.client.host
word = f"<p><i>{shici.random()}</i></p>"
return HTMLResponse(word + f"<p>Your IP is: {ip}</p>")
@app.get("/robots.txt")
async def robots_txt():
return """
User-agent: *
Disallow: /
"""
def main():
import os
import sys
if not (sys_argv := sys.argv[1:]):
print("No args, do nothing.")
return
cmd = f"uvicorn {Path(__file__).stem}:app --proxy-headers"
if DEBUG:
cmd += " --reload --debug --host 0.0.0.0"
else:
cmd += " --reload"
if "r" in sys_argv:
cmd += f" --port={PORT}"
else:
if (p := sys_argv[0]).isdigit():
cmd += f" --port={p}"
elif p == "clear": # 清除redis缓存
raise NotImplementedError
print("-->", cmd)
os.system(cmd)
if __name__ == "__main__":
main()
启动服务: 直接执行如下命令
poetry run python main.py r