国家税务总局电子发票查询下载
全电发票受票试点全面铺开,全国每个省、自治区、直辖市、计划单列市都能收取全电发票了!作为我们会计人员犯愁了,收到全电发票,如何勾选认证呢?如果作为可以开具全电发票的城市如何开具全电发票呢?发票开错了,
2024.11.08用一系列文章介绍如何用python写一个发票管理小工具。
本文介绍如何用Uvicorn+FastAPI搭建后台接口,如何使用loguru打印日志,以及自动打开浏览器显示前端页面。
代码结构
大家一般运行Uvicorn都是uvicorn.run()直接运行,这样uvicorn启动后会阻塞程序,后续无法执行代码。
所以这里我们使用Python多进程,一个主进程用于打开浏览器以及后续其他功能,一个独立的子进程运行Uvicorn。
创建一个配置文件config.yml,编写config.py用于读取配置文件。使用ruamel.yaml模块读取yaml文件。
#config.pyfrom ruamel.yaml import YAMLclass AppConfig():def __init__(self):with open("config/config.yml","r",encoding="utf-8") as configFile:yaml = YAML()conf = yaml.load(configFile)self.config = confself.loguru = self.config['loguru']self.uvicorn = self.config['uvicorn']appConfig = AppConfig()
# config.yml# 日志配置loguru:format: '{time:YYYY-MM-DDTHH:mm:ss.SSSZ} {level} tid[{extra[tid]}] {message}'level: DEBUGfile: logs/application.logrotation: 00:00retention: 30 days# uvicorn设置uvicorn:host: 127.0.0.1port: 8088# 等待web服务启动时间,服务启动后自动打开浏览器waitWebServerTime: 10
使用multiprocessing.Process创建子进程,注意设置daemon=True,这样主进程关闭时会自动关掉子进程。
import uvicornfrom multiprocessing import Processfrom config import appConfigdef runUvicorn():uvicorn.run("webapi:app", host=appConfig.uvicorn["host"], port=appConfig.uvicorn["port"], reload=False, log_config='config/uvicornLog.json', access_log=True, workers=1)# 启动web服务webapiProcess = Process(target=runUvicorn, name="webapi_process", daemon=True)webapiProcess.start()try:while True:time.sleep(1)except KeyboardInterrupt: logger.info("user interrupt, close application")sys.exit(0)
为了方便日志追踪,一般我们都会在日志中打印一个transaction_id,用户一个请求过程中的所有日志都有这样一个唯一的transaction_id。
我们使用loguru模块来打印日志,loguru配置和使用非常简单,而且我们的程序使用了多进程,loguru是支持多进程的。
第一节的配置文件中已经有loguru需要的配置项了,下面介绍如何使用loguru,以及fastapi如何生成transaction_id,并且将tid添加到日志中。
创建log.py
from loguru import loggerimport sysfrom config import appConfiglogger.remove()logger.configure(extra={"tid":""})logger.add(sys.stderr,enqueue=True, format=appConfig.loguru["format"], level=appConfig.loguru["level"])logger.add(appConfig.loguru["file"], enqueue=True, format=appConfig.loguru["format"], level=appConfig.loguru["level"], rotation=appConfig.loguru["rotation"], retention=appConfig.loguru["retention"])
需要关注的是logger.configure(extra={"tid":""})这一行,将tid添加到日志record的extra中,extra是loguru提供给用户添加自定义日志字段的属性。虽然也有办法直接修改record,但是建议添加到extra中。
在webapi.py中添加middleware,在收到请求时生成tid。然后通过loguru的pach将tid添加到日志record中。
#webapi.pyfrom random import randintfrom typing import Callable, Optionalfrom fastapi import FastAPI,Requestfrom loguru import loggerfrom datetime import datetimefrom contextvars import ContextVar# 用于日志记录当前请求IDtransaction_id: ContextVar[Optional[str]] = ContextVar('transaction_id', default='')def transaction_id_filter(record):record['extra']['tid'] = transaction_id.get()return record# 此处向日志中设置tidlogger.configure(patcher=transaction_id_filter)app = FastAPI(title='My Invoice Folder', docs_url=None, redoc_url=None)# 生成请求ID@app.middleware("http")async def create_transaction_id(request: Request, call_next: Callable):# tid格式为时间戳+4位随机数transaction_id.set(f"{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}{randint(1000, 9999)}")response = await call_next(request)return response
我们之前已经写了一个发票夹html页面,这里直接将fastapi首页跳转到这个页面就可以了。
将页面资源都放到项目ui文件夹中,加载ui文件夹。
app.mount("/ui", StaticFiles(directory="ui"), name="ui")
设置首页跳转
# 首页跳转到我的发票夹页面@app.get("/", include_in_schema=False)def read_root():logger.info("access index page")return RedirectResponse("/ui/index.html")
首先我们在启动Uvicorn进程后,使用request请求首页,如果请求成功,则打开系统默认浏览器并打开发票夹首页。代码如下:
# 启动系统默认浏览器打开界面waitWebServerTime = appConfig.config["waitWebServerTime"]openBrowserSuccess = Falsewhile waitWebServerTime > 0:time.sleep(1)try: # 判断web服务是否已启动indexUrl = f'http://{appConfig.uvicorn["host"]}:{appConfig.uvicorn["port"]}/'response = requests.get(indexUrl, timeout=1)if response.status_code == 200:# 打开主页openBrowserSuccess = openBrowser(indexUrl)breakexcept Exception as e:passwaitWebServerTime -= 1
现在我们可以直接运行main.py,就可以运行后端api,并且自动打开浏览器看到页面了~后续逻辑抽空继续写。
控制台日志
自动打开浏览器,访问本地页面
代码比较多,已经上传到github(https://github.com/xy12358/my-invoice-folder.git)和gitee(https://gitee.com/xinying/my-invoice-folder)。
全电发票受票试点全面铺开,全国每个省、自治区、直辖市、计划单列市都能收取全电发票了!作为我们会计人员犯愁了,收到全电发票,如何勾选认证呢?如果作为可以开具全电发票的城市如何开具全电发票呢?发票开错了,
2024.11.08数字化电子发票全流 程系统操作问题解答国家税务总局上海市税务局第四税务分局 2022 年 11 月编写说明按照税务总局发票电子化改革统一部署, 以 12 月底实 现数字化电子发票开票全覆盖为目标,本市
2024.11.07税务征期即“纳税申报日期”。一般纳税人企业需要在每月初进行抄报税,申报上一月度开发票信息及增值税申报情况,并缴纳税款。 征期一般是每月1-15日,遇到连续超过3天的节假日会按放假的天数顺延。征期最后一
2024.11.08关键词:发票识别 私有云发票识别 发票识别API接口 webservice发票识别平台发票,一个再也熟悉不过的财务往来凭证,录入发票,一项让多少财会人员头疼的工作。过去录入一张发票需要一个财会人员5分
2024.11.08发票,相信大家都不陌生,对于公司来讲,发票主要是公司做账的依据,同时也是缴税的费用凭证;而对于员工来讲,发票主要是用来报销的。对于收到的发票,会计需要统计、核查、录入到企业的财务系统,而这几个环节往往
2024.11.08