本文已参与「新人创作礼」活动,一起开启掘金创作之路。
接口代码内容(routers/api.py)
from fastapi import APIRouter, BackgroundTasks, HTTPException, Request
from excel import run
from schemas import TableData
from tasks import do_sync
from utils import get_host
router = APIRouter()
class ValidationError(HTTPException):
def __init__(self, detail: str, status_code: int = 400):
super().__init__(status_code, detail=detail)
NAME_COL = {
"customerNum": 1,
"factoryNum": 2,
"size": 3,
"juan": 4,
"autoJian": 5,
"price": 6,
"total": 7,
"pack": 8,
"maiTou": 9,
}
def _build_table_body(lines):
row = 4
body = []
for auto_no, line in enumerate(lines, 1):
row_data = [(row, 0, auto_no)]
for k, v in line.dict().items():
if v is None:
continue
col = NAME_COL[k]
if k == "size":
v = f"0.45*{v}米/卷"
elif k == "juan":
unit = 50 if v >= 50 else 30
auto_jian = v // unit + bool(v % unit)
cell = (row, NAME_COL["autoJian"], auto_jian)
row_data.append(cell)
row_data.append((row, col, v))
body.append(row_data)
row += 1
return body
@router.post("/like")
async def gen_table_生成表格(
request: Request, table: TableData, background_tasks: BackgroundTasks
):
datas = _build_table_body(table.lines)
fname = run(datas, order_num=table.orderNum)
url = f"{get_host(request)}/{fname}"
background_tasks.add_task(do_sync, table.lines)
return {"url": url}
pyproject.toml内容如下:
[tool.poetry]
name = "sunquan"
version = "0.3.0"
description = "Easy Order"
authors = ["Waket Zheng <waketzheng@gmail.com>"]
[tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.75.2"
uvicorn = "^0.17.6"
xlrd = "^2.0.1"
xlwt = "^1.3.0"
python-dotenv = "^0.20.0"
openpyxl = "^3.0.9"
aioredis = {extras = ["hiredis"], version = "^2.0.1"}
httpx = "^0.22.0"
gunicorn = "^20.1.0"
loguru = "^0.6.0"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
bump="run:bump"
update="run:update"
run.py内容如下:
#!/usr/bin/env python
import os
import re
import shlex
import subprocess
import sys
def get_part(s: str) -> str:
choices = {"1": "patch", "2": "minor", "3": "major"}
choices.update({v: v for v in choices.values()})
try:
return choices[s]
except KeyError:
print(f"Invalid part: {s!r}")
sys.exit(1)
def run_and_echo(cmd: str) -> int:
print("-->", cmd)
return os.system(cmd)
def bump():
print("Current version:")
os.system("poetry version")
if sys.argv[1:]:
part = get_part(sys.argv[1])
else:
tip = "Choices:\n1. patch\n2. minor\n3. major\n\nWhich one to bump?(Leave blank to use `patch`) "
if a := input(tip).strip():
part = get_part(a)
else:
part = "patch"
if (rc := run_and_echo(f"bumpversion {part}")) == 0:
sys.exit(run_and_echo("git push && git push --tags && git log -1"))
sys.exit(rc)
def update():
"""升级所有依赖包到最新版"""
cmd = "poetry show --tree"
r = subprocess.run(shlex.split(cmd), capture_output=True)
packages = re.findall(r"^([\w-]+)", r.stdout.decode(), re.M)
upgrade = "poetry add " + " ".join(f"{i}@latest" for i in packages)
print("-->", upgrade)
subprocess.run(upgrade, shell=True)
utils.py内容如下:
from decimal import ROUND_HALF_UP, Decimal
from typing import Union
from settings import IS_PROD, PORT
def to_decimal(
amount: Union[int, str, float, Decimal], decimal_places: int = 2
) -> Decimal:
"""将传入的数值,四舍五入转化为两个小数的Decimal对象
:param decimal_places: 要保留多少为小数
Usage::
>>> to_decimal(1.565)
Decimal('1.57')
>>> to_decimal('1.564')
Decimal('1.56')
>>> to_decimal('1.564', 1)
Decimal('1.6')
"""
return Decimal(str(amount)).quantize(
Decimal("0." + "0" * decimal_places), ROUND_HALF_UP
)
def get_host(req) -> str:
"""获取协议+域名"""
if v := getattr(req, "headers", {}).get("host"):
if ":" in v:
v = "http://" + v
else:
v = "https://" + v
return v
if IS_PROD:
return "https://www.my-domain.com" # 生产服
return f"http://loalhost:{PORT}" # 测试服