diff --git a/difyPlugin/.env.example b/difyPlugin/.env.example new file mode 100644 index 00000000..352dea98 --- /dev/null +++ b/difyPlugin/.env.example @@ -0,0 +1,16 @@ +# 应用配置 +APP_NAME=DifyPlugin +APP_VERSION=1.0.0 +DEBUG=false + +# API配置 +API_V1_PREFIX=/api/v1 + +# 跨域配置 +CORS_ORIGINS=["*"] + +# Redis配置 +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD= +REDIS_DB=0 diff --git a/difyPlugin/.gitignore b/difyPlugin/.gitignore new file mode 100644 index 00000000..c08f6e8e --- /dev/null +++ b/difyPlugin/.gitignore @@ -0,0 +1,27 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +venv/ +.venv/ +ENV/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# 环境配置 +.env + +# 日志 +*.log +logs/ + +# 测试 +.pytest_cache/ +.coverage +htmlcov/ diff --git a/difyPlugin/README.md b/difyPlugin/README.md new file mode 100644 index 00000000..5d4bb3ea --- /dev/null +++ b/difyPlugin/README.md @@ -0,0 +1,38 @@ +# DifyPlugin + +Dify插件服务 - 基于FastAPI构建 + +## 快速开始 + +### 安装依赖 + +```bash +pip install -r requirements.txt +``` + +### 运行服务 + +```bash +uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 +``` + +### API文档 + +- Swagger UI: http://localhost:8000/docs +- ReDoc: http://localhost:8000/redoc + +## 项目结构 + +``` +difyPlugin/ +├── app/ +│ ├── main.py # 应用入口 +│ ├── config.py # 配置管理 +│ ├── api/v1/ # API路由 +│ ├── schemas/ # Pydantic数据模型 +│ ├── services/ # 业务逻辑 +│ ├── core/ # 核心功能 +│ └── utils/ # 工具函数 +├── requirements.txt +└── README.md +``` diff --git a/difyPlugin/app/__init__.py b/difyPlugin/app/__init__.py new file mode 100644 index 00000000..e170429b --- /dev/null +++ b/difyPlugin/app/__init__.py @@ -0,0 +1 @@ +# DifyPlugin FastAPI Application diff --git a/difyPlugin/app/api/__init__.py b/difyPlugin/app/api/__init__.py new file mode 100644 index 00000000..3c31f3e2 --- /dev/null +++ b/difyPlugin/app/api/__init__.py @@ -0,0 +1,16 @@ +# API模块 +from fastapi import APIRouter + +from app.api.workcase import router as workcase_router +from app.api.bidding import router as bidding_router +from app.api.test import router as test_router + +# 创建主路由器 +router = APIRouter() + +# 注册所有子路由 +router.include_router(workcase_router, prefix="/workcase", tags=["工单相关服务"]) +router.include_router(bidding_router, prefix="/bidding", tags=["招标相关服务"]) +router.include_router(test_router, prefix="/test", tags=["招标相关服务"]) + +__all__ = ["router"] diff --git a/difyPlugin/app/api/bidding/ReadFileAPI.py b/difyPlugin/app/api/bidding/ReadFileAPI.py new file mode 100644 index 00000000..bc1b8dcb --- /dev/null +++ b/difyPlugin/app/api/bidding/ReadFileAPI.py @@ -0,0 +1,38 @@ +"""文件读取相关接口""" +from fastapi import APIRouter + +from app.schemas import ResultDomain + +router = APIRouter() + + +@router.post( + "/read", + response_model=ResultDomain[dict], + summary="读取文件", + description="读取指定路径的文件内容" +) +async def read_file(file_path: str) -> ResultDomain[dict]: + """ + 读取文件内容 + + - **file_path**: 文件路径 + """ + # TODO: 实现文件读取逻辑 + return ResultDomain.success(message="读取成功", data={"content": ""}) + + +@router.post( + "/parse", + response_model=ResultDomain[dict], + summary="解析文件", + description="解析招标文件内容" +) +async def parse_file(file_path: str) -> ResultDomain[dict]: + """ + 解析招标文件 + + - **file_path**: 文件路径 + """ + # TODO: 实现文件解析逻辑 + return ResultDomain.success(message="解析成功", data={"result": {}}) diff --git a/difyPlugin/app/api/bidding/__init__.py b/difyPlugin/app/api/bidding/__init__.py new file mode 100644 index 00000000..116bf39e --- /dev/null +++ b/difyPlugin/app/api/bidding/__init__.py @@ -0,0 +1,13 @@ +# API模块 +from fastapi import APIRouter + +from .ReadFileAPI import router as readfile_router + + +# 创建主路由器 +router = APIRouter() + +# 注册所有子路由 +router.include_router(readfile_router, prefix="/readfile", tags=["文件读取相关服务"]) + +__all__ = ["router"] \ No newline at end of file diff --git a/difyPlugin/app/api/test/HelloWordAPI.py b/difyPlugin/app/api/test/HelloWordAPI.py new file mode 100644 index 00000000..1d9534f0 --- /dev/null +++ b/difyPlugin/app/api/test/HelloWordAPI.py @@ -0,0 +1,28 @@ +"""测试相关接口""" +from fastapi import APIRouter + +from app.schemas.base import ResultDomain + +router = APIRouter() + + +@router.get( + "/world", + response_model=ResultDomain[str], + summary="Hello World", + description="测试接口连通性" +) +async def hello_word() -> ResultDomain[str]: + """Hello World 测试接口""" + return ResultDomain.ok(message="Hello World", data="Hello World") + + +@router.get( + "/ping", + response_model=ResultDomain[str], + summary="Ping测试", + description="测试服务是否正常运行" +) +async def ping() -> ResultDomain[str]: + """Ping 测试接口""" + return ResultDomain.ok(message="pong", data="pong") diff --git a/difyPlugin/app/api/test/__init__.py b/difyPlugin/app/api/test/__init__.py new file mode 100644 index 00000000..48162d70 --- /dev/null +++ b/difyPlugin/app/api/test/__init__.py @@ -0,0 +1,13 @@ +# API模块 +from fastapi import APIRouter + +from .HelloWordAPI import router as hello_router + + +# 创建主路由器 +router = APIRouter() + +# 注册所有子路由 +router.include_router(hello_router, prefix="/hello", tags=["测试服务"]) + +__all__ = ["router"] diff --git a/difyPlugin/app/api/workcase/QrCodeAPI.py b/difyPlugin/app/api/workcase/QrCodeAPI.py new file mode 100644 index 00000000..1dae773e --- /dev/null +++ b/difyPlugin/app/api/workcase/QrCodeAPI.py @@ -0,0 +1,38 @@ +"""二维码相关接口""" +from fastapi import APIRouter + +from app.schemas import ResultDomain + +router = APIRouter() + + +@router.post( + "/generate", + response_model=ResultDomain[dict], + summary="生成二维码", + description="根据内容生成二维码" +) +async def generate_qrcode(content: str) -> ResultDomain[dict]: + """ + 生成二维码 + + - **content**: 二维码内容 + """ + # TODO: 实现二维码生成逻辑 + return ResultDomain.success(message="生成成功", data={"content": content}) + + +@router.post( + "/parse", + response_model=ResultDomain[dict], + summary="解析二维码", + description="解析二维码图片内容" +) +async def parse_qrcode(image_url: str) -> ResultDomain[dict]: + """ + 解析二维码 + + - **image_url**: 二维码图片URL + """ + # TODO: 实现二维码解析逻辑 + return ResultDomain.success(message="解析成功", data={"result": ""}) diff --git a/difyPlugin/app/api/workcase/__init__.py b/difyPlugin/app/api/workcase/__init__.py new file mode 100644 index 00000000..bb53b71f --- /dev/null +++ b/difyPlugin/app/api/workcase/__init__.py @@ -0,0 +1,13 @@ +# API模块 +from fastapi import APIRouter + +from .QrCodeAPI import router as qrcode_router + + +# 创建主路由器 +router = APIRouter() + +# 注册所有子路由 +router.include_router(qrcode_router, prefix="/qrcode", tags=["二维码相关服务"]) + +__all__ = ["router"] \ No newline at end of file diff --git a/difyPlugin/app/config.py b/difyPlugin/app/config.py new file mode 100644 index 00000000..f1708da9 --- /dev/null +++ b/difyPlugin/app/config.py @@ -0,0 +1,38 @@ +"""应用配置管理""" +from pydantic_settings import BaseSettings +from functools import lru_cache + + +class Settings(BaseSettings): + """应用配置""" + # 应用基础配置 + APP_NAME: str = "DifyPlugin" + APP_VERSION: str = "1.0.0" + DEBUG: bool = False + + # API配置 + API_V1_PREFIX: str = "/api/v1" + HOST: str = "0.0.0.0" + API_HOST: str = "localhost" # OpenAPI servers 显示的地址 + PORT: int = 8380 + + # 跨域配置 + CORS_ORIGINS: list[str] = ["*"] + + # Redis配置 + REDIS_HOST: str = "localhost" + REDIS_PORT: int = 6379 + REDIS_PASSWORD: str = "123456" + REDIS_DB: int = 0 + + class Config: + env_file = ".env" + case_sensitive = True + + +@lru_cache() +def get_settings() -> Settings: + return Settings() + + +settings = get_settings() diff --git a/difyPlugin/app/core/__init__.py b/difyPlugin/app/core/__init__.py new file mode 100644 index 00000000..a343c25f --- /dev/null +++ b/difyPlugin/app/core/__init__.py @@ -0,0 +1 @@ +# Core模块 diff --git a/difyPlugin/app/core/exceptions.py b/difyPlugin/app/core/exceptions.py new file mode 100644 index 00000000..c26ffce9 --- /dev/null +++ b/difyPlugin/app/core/exceptions.py @@ -0,0 +1,42 @@ +"""自定义异常和异常处理器""" +from fastapi import FastAPI, Request +from fastapi.responses import JSONResponse + +from app.schemas.base import ResultDomain + + +class BusinessException(Exception): + """业务异常""" + def __init__(self, code: int = 500, message: str = "业务异常"): + self.code = code + self.message = message + + +class NotFoundException(BusinessException): + """资源不存在异常""" + def __init__(self, message: str = "资源不存在"): + super().__init__(code=404, message=message) + + +class ValidationException(BusinessException): + """参数校验异常""" + def __init__(self, message: str = "参数校验失败"): + super().__init__(code=400, message=message) + + +def register_exception_handlers(app: FastAPI): + """注册全局异常处理器""" + + @app.exception_handler(BusinessException) + async def business_exception_handler(request: Request, exc: BusinessException): + return JSONResponse( + status_code=200, + content=ResultDomain.fail(message=exc.message, code=exc.code).model_dump() + ) + + @app.exception_handler(Exception) + async def global_exception_handler(request: Request, exc: Exception): + return JSONResponse( + status_code=500, + content=ResultDomain.fail(message=str(exc), code=500).model_dump() + ) diff --git a/difyPlugin/app/core/middleware.py b/difyPlugin/app/core/middleware.py new file mode 100644 index 00000000..7ea8b274 --- /dev/null +++ b/difyPlugin/app/core/middleware.py @@ -0,0 +1,26 @@ +"""中间件定义""" +import time +import logging +from fastapi import Request +from starlette.middleware.base import BaseHTTPMiddleware + +logger = logging.getLogger(__name__) + + +class RequestLoggingMiddleware(BaseHTTPMiddleware): + """请求日志中间件""" + + async def dispatch(self, request: Request, call_next): + start_time = time.time() + + response = await call_next(request) + + process_time = time.time() - start_time + logger.info( + f"{request.method} {request.url.path} " + f"- Status: {response.status_code} " + f"- Time: {process_time:.3f}s" + ) + + response.headers["X-Process-Time"] = str(process_time) + return response diff --git a/difyPlugin/app/core/redis.py b/difyPlugin/app/core/redis.py new file mode 100644 index 00000000..33678a85 --- /dev/null +++ b/difyPlugin/app/core/redis.py @@ -0,0 +1,128 @@ +"""Redis 服务""" +import json +from typing import Any, Optional, Union + +import redis.asyncio as redis +from redis.asyncio import Redis + +from app.config import settings + + +class RedisService: + """Redis 服务类""" + + _client: Optional[Redis] = None + + @classmethod + async def init(cls) -> None: + """初始化 Redis 连接""" + cls._client = redis.Redis( + host=settings.REDIS_HOST, + port=settings.REDIS_PORT, + password=settings.REDIS_PASSWORD or None, + db=settings.REDIS_DB, + decode_responses=True + ) + + @classmethod + async def close(cls) -> None: + """关闭 Redis 连接""" + if cls._client: + await cls._client.close() + cls._client = None + + @classmethod + def get_client(cls) -> Redis: + """获取 Redis 客户端""" + if not cls._client: + raise RuntimeError("Redis 未初始化,请先调用 init()") + return cls._client + + # ==================== String 操作 ==================== + + @classmethod + async def get(cls, key: str) -> Optional[str]: + """获取值""" + return await cls.get_client().get(key) + + @classmethod + async def set(cls, key: str, value: Union[str, int, float], expire: Optional[int] = None) -> bool: + """设置值""" + return await cls.get_client().set(key, value, ex=expire) + + @classmethod + async def delete(cls, *keys: str) -> int: + """删除键""" + return await cls.get_client().delete(*keys) + + @classmethod + async def exists(cls, key: str) -> bool: + """判断键是否存在""" + return await cls.get_client().exists(key) > 0 + + @classmethod + async def expire(cls, key: str, seconds: int) -> bool: + """设置过期时间""" + return await cls.get_client().expire(key, seconds) + + @classmethod + async def ttl(cls, key: str) -> int: + """获取剩余过期时间""" + return await cls.get_client().ttl(key) + + # ==================== JSON 操作 ==================== + + @classmethod + async def get_json(cls, key: str) -> Optional[Any]: + """获取 JSON 值""" + value = await cls.get(key) + return json.loads(value) if value else None + + @classmethod + async def set_json(cls, key: str, value: Any, expire: Optional[int] = None) -> bool: + """设置 JSON 值""" + return await cls.set(key, json.dumps(value, ensure_ascii=False), expire) + + # ==================== Hash 操作 ==================== + + @classmethod + async def hget(cls, name: str, key: str) -> Optional[str]: + """获取 Hash 字段值""" + return await cls.get_client().hget(name, key) + + @classmethod + async def hset(cls, name: str, key: str, value: str) -> int: + """设置 Hash 字段值""" + return await cls.get_client().hset(name, key, value) + + @classmethod + async def hgetall(cls, name: str) -> dict: + """获取 Hash 所有字段""" + return await cls.get_client().hgetall(name) + + @classmethod + async def hdel(cls, name: str, *keys: str) -> int: + """删除 Hash 字段""" + return await cls.get_client().hdel(name, *keys) + + # ==================== List 操作 ==================== + + @classmethod + async def lpush(cls, key: str, *values: str) -> int: + """左侧插入列表""" + return await cls.get_client().lpush(key, *values) + + @classmethod + async def rpush(cls, key: str, *values: str) -> int: + """右侧插入列表""" + return await cls.get_client().rpush(key, *values) + + @classmethod + async def lrange(cls, key: str, start: int = 0, end: int = -1) -> list: + """获取列表范围""" + return await cls.get_client().lrange(key, start, end) + + @classmethod + async def llen(cls, key: str) -> int: + """获取列表长度""" + return await cls.get_client().llen(key) diff --git a/difyPlugin/app/main.py b/difyPlugin/app/main.py new file mode 100644 index 00000000..2d3f1aed --- /dev/null +++ b/difyPlugin/app/main.py @@ -0,0 +1,78 @@ +"""FastAPI 应用入口""" +from contextlib import asynccontextmanager + +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from app.config import settings +from app.api import router as api_router +from app.core.exceptions import register_exception_handlers +from app.core.redis import RedisService + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """应用生命周期管理""" + # 启动时初始化 + await RedisService.init() + yield + # 关闭时清理 + await RedisService.close() + + +def create_app() -> FastAPI: + """创建FastAPI应用实例""" + app = FastAPI( + title=settings.APP_NAME, + version=settings.APP_VERSION, + description="Dify插件服务API", + openapi_url=f"{settings.API_V1_PREFIX}/openapi.json", + docs_url="/docs", + redoc_url="/redoc", + lifespan=lifespan, + servers=[ + {"url": f"http://{settings.API_HOST}:{settings.PORT}", "description": "API服务器"}, + ], + ) + + # 注册CORS中间件 + app.add_middleware( + CORSMiddleware, + allow_origins=settings.CORS_ORIGINS, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + + # 注册异常处理器 + register_exception_handlers(app) + + # 注册路由 + app.include_router(api_router, prefix=settings.API_V1_PREFIX) + + return app + + +app = create_app() + + +def print_routes(app: FastAPI): + """打印所有注册的路由""" + print("\n" + "=" * 60) + print("Registered Routes:") + print("=" * 60) + for route in app.routes: + if hasattr(route, "methods"): + methods = ", ".join(route.methods - {"HEAD", "OPTIONS"}) + print(f" {methods:8} {route.path}") + print("=" * 60 + "\n") + + +# 启动时打印路由 +print_routes(app) + + +@app.get("/health", tags=["健康检查"], summary="健康检查接口") +async def health_check(): + """服务健康检查""" + diff --git a/difyPlugin/app/schemas/__init__.py b/difyPlugin/app/schemas/__init__.py new file mode 100644 index 00000000..d0a36ce0 --- /dev/null +++ b/difyPlugin/app/schemas/__init__.py @@ -0,0 +1,4 @@ +from app.schemas.base import ResultDomain +from app.schemas.plugin import PluginRequest, PluginResponse + +__all__ = ["ResultDomain", "PluginRequest", "PluginResponse"] diff --git a/difyPlugin/app/schemas/base.py b/difyPlugin/app/schemas/base.py new file mode 100644 index 00000000..4b182acf --- /dev/null +++ b/difyPlugin/app/schemas/base.py @@ -0,0 +1,52 @@ +"""统一返回类型定义""" +from typing import TypeVar, Generic, Optional, List, Any +from pydantic import BaseModel, Field + +T = TypeVar('T') + + +class PageDomain(BaseModel, Generic[T]): + """分页数据模型""" + page: int = Field(default=1, description="当前页码") + pageSize: int = Field(default=10, description="每页大小") + total: int = Field(default=0, description="总记录数") + dataList: Optional[List[T]] = Field(default=None, description="数据列表") + + +class ResultDomain(BaseModel, Generic[T]): + """统一返回类型""" + code: Optional[int] = Field(default=None, description="状态码") + success: Optional[bool] = Field(default=None, description="是否成功") + message: Optional[str] = Field(default=None, description="返回消息") + data: Optional[T] = Field(default=None, description="单条数据") + dataList: Optional[List[T]] = Field(default=None, description="数据列表") + pageDomain: Optional[PageDomain[T]] = Field(default=None, description="分页数据") + + @staticmethod + def ok(message: str = "success", data: Any = None) -> "ResultDomain": + """成功返回 - 单条数据""" + return ResultDomain(code=200, success=True, message=message, data=data) + + @staticmethod + def ok_list(message: str = "success", data_list: List[Any] = None) -> "ResultDomain": + """成功返回 - 数据列表""" + return ResultDomain(code=200, success=True, message=message, dataList=data_list) + + @staticmethod + def ok_page(message: str = "success", page_domain: "PageDomain" = None) -> "ResultDomain": + """成功返回 - 分页数据""" + result = ResultDomain(code=200, success=True, message=message, pageDomain=page_domain) + if page_domain: + result.dataList = page_domain.dataList + return result + + @staticmethod + def fail(message: str = "failure", code: int = 500) -> "ResultDomain": + """失败返回""" + return ResultDomain(code=code, success=False, message=message) + + model_config = { + "json_schema_extra": { + "examples": [{"code": 200, "success": True, "message": "操作成功"}] + } + } diff --git a/difyPlugin/app/schemas/plugin.py b/difyPlugin/app/schemas/plugin.py new file mode 100644 index 00000000..6a5dea24 --- /dev/null +++ b/difyPlugin/app/schemas/plugin.py @@ -0,0 +1,43 @@ +"""插件相关数据模型""" +from typing import Optional, Dict, Any +from pydantic import BaseModel, Field + + +class PluginRequest(BaseModel): + """ + 插件请求模型 + + Attributes: + plugin_id: 插件ID + action: 执行动作 + params: 请求参数 + """ + plugin_id: str = Field(..., description="插件ID", examples=["plugin_001"]) + action: str = Field(..., description="执行动作", examples=["execute"]) + params: Optional[Dict[str, Any]] = Field(default=None, description="请求参数") + + model_config = { + "json_schema_extra": { + "examples": [ + { + "plugin_id": "plugin_001", + "action": "execute", + "params": {"key": "value"} + } + ] + } + } + + +class PluginResponse(BaseModel): + """ + 插件响应模型 + + Attributes: + plugin_id: 插件ID + result: 执行结果 + status: 执行状态 + """ + plugin_id: str = Field(..., description="插件ID") + result: Optional[Dict[str, Any]] = Field(default=None, description="执行结果") + status: str = Field(default="success", description="执行状态") diff --git a/difyPlugin/app/services/__init__.py b/difyPlugin/app/services/__init__.py new file mode 100644 index 00000000..c278cbe8 --- /dev/null +++ b/difyPlugin/app/services/__init__.py @@ -0,0 +1,3 @@ +from app.services.plugin_service import PluginService + +__all__ = ["PluginService"] diff --git a/difyPlugin/app/services/plugin_service.py b/difyPlugin/app/services/plugin_service.py new file mode 100644 index 00000000..d6019320 --- /dev/null +++ b/difyPlugin/app/services/plugin_service.py @@ -0,0 +1,45 @@ +"""插件业务逻辑层""" +from typing import List, Optional, Dict, Any + +from app.schemas.plugin import PluginRequest, PluginResponse + + +class PluginService: + """插件服务类""" + + def __init__(self): + # 模拟插件数据 + self._plugins: Dict[str, dict] = { + "plugin_001": { + "id": "plugin_001", + "name": "示例插件", + "description": "这是一个示例插件", + "version": "1.0.0", + "enabled": True + } + } + + async def execute(self, request: PluginRequest) -> PluginResponse: + """ + 执行插件 + + Args: + request: 插件请求参数 + + Returns: + PluginResponse: 插件执行结果 + """ + # TODO: 实现具体的插件执行逻辑 + return PluginResponse( + plugin_id=request.plugin_id, + result={"executed": True, "action": request.action}, + status="success" + ) + + async def get_all_plugins(self) -> List[dict]: + """获取所有插件列表""" + return list(self._plugins.values()) + + async def get_plugin_by_id(self, plugin_id: str) -> Optional[dict]: + """根据ID获取插件""" + return self._plugins.get(plugin_id) diff --git a/difyPlugin/app/utils/__init__.py b/difyPlugin/app/utils/__init__.py new file mode 100644 index 00000000..eae7b095 --- /dev/null +++ b/difyPlugin/app/utils/__init__.py @@ -0,0 +1 @@ +# Utils模块 diff --git a/difyPlugin/app/utils/helpers.py b/difyPlugin/app/utils/helpers.py new file mode 100644 index 00000000..17baf94f --- /dev/null +++ b/difyPlugin/app/utils/helpers.py @@ -0,0 +1,22 @@ +"""工具函数""" +from typing import Any, Dict +import json +from datetime import datetime + + +def format_datetime(dt: datetime, fmt: str = "%Y-%m-%d %H:%M:%S") -> str: + """格式化日期时间""" + return dt.strftime(fmt) + + +def safe_json_loads(json_str: str, default: Any = None) -> Any: + """安全的JSON解析""" + try: + return json.loads(json_str) + except (json.JSONDecodeError, TypeError): + return default + + +def dict_filter_none(data: Dict[str, Any]) -> Dict[str, Any]: + """过滤字典中的None值""" + return {k: v for k, v in data.items() if v is not None} diff --git a/difyPlugin/dify-tools.json b/difyPlugin/dify-tools.json new file mode 100644 index 00000000..967415dd --- /dev/null +++ b/difyPlugin/dify-tools.json @@ -0,0 +1,78 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "DifyPlugin", + "description": "Dify插件服务API", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://192.168.0.253:8380/api/v1", + "description": "开发服务器" + } + ], + "paths": { + "/test/hello/world": { + "get": { + "operationId": "HelloWord", + "summary": "Hello World", + "description": "测试接口连通性", + "responses": { + "200": { + "description": "成功响应", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResultDomain" + } + } + } + } + } + } + }, + "/test/hello/ping": { + "get": { + "operationId": "Ping", + "summary": "Ping测试", + "description": "测试服务是否正常运行", + "responses": { + "200": { + "description": "成功响应", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResultDomain" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ResultDomain": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "description": "状态码" + }, + "success": { + "type": "boolean", + "description": "是否成功" + }, + "message": { + "type": "string", + "description": "返回消息" + }, + "data": { + "description": "返回数据" + } + } + } + } + } +} diff --git a/difyPlugin/requirements.txt b/difyPlugin/requirements.txt new file mode 100644 index 00000000..304aad81 --- /dev/null +++ b/difyPlugin/requirements.txt @@ -0,0 +1,7 @@ +fastapi +pydantic +pydantic-settings +python-dotenv +redis +anyio>=4.5 +uvicorn[standard]>=0.31.1 \ No newline at end of file diff --git a/difyPlugin/run.py b/difyPlugin/run.py new file mode 100644 index 00000000..149681ec --- /dev/null +++ b/difyPlugin/run.py @@ -0,0 +1,11 @@ +"""启动脚本 - 从config读取配置""" +import uvicorn +from app.config import settings + +if __name__ == "__main__": + uvicorn.run( + "app.main:app", + host="0.0.0.0", + port=settings.PORT, + reload=settings.DEBUG + )