一般网上的文章都是以脚本的方式写Demor的,没找到自己想要的那种项目结构型的示例(类似Java SpringBoot 创建 Model,通过 pom 进行关联配置的那种)
看了一些源码,再结合自己的想法,建了一个简单的示例, 用 Python 做接口服务的项目搭建,仅供参考
代码结构说明
VipQA │ .env # 环境变量配置文件 │ app_init.py # 我用它来放了项目初始化代码 │ main.py # 主程序,用来启动项目 │ requirements.txt # 项目依赖包 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 进行安装 │ settings.py # 用来将 .env 里的变更值取出来。 Python 设置环境变量方法(https://www.cnblogs.com/vipsoft/p/17677020.html) │ __init__.py # 目前没放代码 │ ├─db # 里面放了初始化数据库的脚本 │ └─ build_nodes.py │ ├─routers # 路由目录,相当于 Java 里的 Controller │ │ node_router.py # neo4j 节点接口,用来处理节点相关的接口方法 │ └─ __init__.py # 路由配置,把目录下的各模块路由注册到 API 里面 │ ├─service # 业务逻辑处理,参考JAVA,供 Controller 调用 │ node_service.py # neo4j 节点服务,处理节点逻辑 │ __init__.py # 目前空 │ ├─static # 静态资源目录 │ 404.html # URL地址不存在时,显示这个页面 │ index.html # 默认首页 │ └─utils # 工具类 │ neo4j_provider.py # neo4j 连接工具 └─ __init__.py # 目前空
主程序代码
requirements.txt
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
#pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 知识图谱依赖包 neo4j==5.10.0 # async web framework # web 服务器 uvicorn==0.23.2 # 代码框架 fastapi==0.101.1 # 环境配置 .env 使用依赖包 python-dotenv==0.20.0 # 命令行、控制台,返回内容,字体变颜色 colorama==0.4.4
.env 环境变量配置文件
# app APP_HOST=127.0.0.1 APP_PORT=8000 # neo4j NEO4J_URI=neo4j://172.16.3.64:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=password NEO4J_VERSION=5 NEO4J_DATABASE=neo4j NEO4J_PORT=8080
settings.py
变量设置一般有两种,一种取文件里的,还有是取系统的环境变量,详见:Python 设置环境变量方法
from dotenv import dotenv_values from typing import List dotenv_config = dotenv_values('.env') class Settings: BACKEND_CORS_ORIGINS: List = ['*'] # APP APP_HOST = dotenv_config.get("APP_HOST", "127.0.0.1") APP_PORT = int(dotenv_config.get("APP_PORT", 8000)) # Neo4j NEO4J_URI = dotenv_config.get("NEO4J_URI", "neo4j://172.16.3.64:7687") NEO4J_USER = dotenv_config.get("NEO4J_USER", "neo4j") NEO4J_PASSWORD = dotenv_config.get("NEO4J_PASSWORD", "password") NEO4J_VERSION = dotenv_config.get("NEO4J_VERSION", "5") NEO4J_DATABASE = dotenv_config.get("NEO4J_DATABASE", "neo4j") NEO4J_PORT = int(dotenv_config.get("NEO4J_PORT", 8080)) settings = Settings()
app_init.py
项目启动
import time import logging import os from settings import settings from starlette.middleware.cors import CORSMiddleware from fastapi import FastAPI, Request from fastapi.responses import JSONResponse, FileResponse from fastapi.staticfiles import StaticFiles from routers import api_router # 创建 FastAPI 实类,供 main.py 调用 def create_application() -> FastAPI: # 等待其他组件启动完成 time.sleep(3) application = FastAPI( title="FastAPI结构示例", # 文档标题 description="使用 FastAPI 实现 Node4j 基础功能. 🚀", # 文档简介 version="0.0.1", # 文档版本号 # docs_url=None, redoc_url=None, # 配置离线文档,None 后,http://127.0.0.1:8000/docs 就不能再访问了 ) # api_router => routers/__init__.py 里面 的 api_router = APIRouter() # 访问接口时,所有的接口前面都要加上 api 前缀,相当于 Java 里的 server.servlet.context-path: /api 配置 application.include_router(api_router, prefix='/api') # 后面带 API 的就表示接口,路由到 routers 目录下找对应的接口,相当于 Java 的 Controller, register_middleware(application) # 支付跨域 register_static(application) # 添加HTML静态页面配置 register_event(application) # 添加项目事件 return application def register_static(app): # 如果需要使用静态文件, 可以使用 StaticFiles,将它挂载到应用程序中。 html_path = os.path.dirname(os.path.abspath(__file__)) app.mount('/static', StaticFiles(directory=os.path.join(html_path, 'static'))) @app.get('/') async def read_index(): # 跳转到 static 下面的 index.html 文件 return FileResponse(os.path.join(html_path, 'static', 'index.html')) @app.exception_handler(404) async def not_found(request: Request, exc): accept = request.headers.get('accept') if not accept: # 返回JSON 格式 return JSONResponse(content={'error': "Not found"}, status_code=exc.status_code) if exc.status_code == 404 and 'text/html' in accept: # 404 跳转到 static 下面的 404.html 页面 return FileResponse(os.path.join(html_path, 'static', '404.html')) else: return JSONResponse(content={'error': "Not found"}, status_code=exc.status_code) # 支持跨域 def register_middleware(application): if settings.BACKEND_CORS_ORIGINS: application.add_middleware( CORSMiddleware, allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) def register_event(app): @app.on_event("startup") async def startup_event(): logging.info("App Startup") @app.on_event("shutdown") async def shutdown_event(): logging.info("App Shutdown")
接口路由
routers/init.py
from fastapi import APIRouter from . import node_router api_router = APIRouter() # tags 显示在 Swagger 上的标题 # 这边的 prefix 相当于 java 里的 Controller 上的 @RequestMapping("/node") api_router.include_router(node_router.router, tags=['Node'], prefix='/node')
node_router.py
from fastapi import APIRouter, status from fastapi.responses import JSONResponse router = APIRouter() # 定义一个根路由 @router.get("/add") def add_node(): # TODO 往 neo4j 里创建新的节点 data = { 'code': 0, 'message': '', 'data': 'add success' } return JSONResponse(content=data, status_code=status.HTTP_200_OK)
URL访问 http://127.0.0.1:8000/api/node/add
附JAVA,接口前缀配置
所有接口前面的前缀
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8088 servlet: # 应用的访问路径 context-path: /api
业务接口上的前缀(所有类方法前)
@RequestMapping("/node") public class NodeController{ @PostMapping("/add") public void add(){ } }