Download apps/documents/api/generation_api.py from jun2024/fc: direct link, hf CLI and curl.
- Browser
- Download file 8.34 kB
-
https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/documents/api/generation_api.py
- Command line
-
hf download hf://spaces/jun2024/fc/apps/documents/api/generation_api.py
-
curl -L -o generation_api.py https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/documents/api/generation_api.py
8.34 kB
| """ | |
| 文档生成 API | |
| 提供合同文件夹和补充协议的下载接口. | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| from typing import Any | |
| from django.utils.translation import gettext_lazy as _ | |
| from ninja import Router | |
| from apps.core.exceptions import ValidationException | |
| from apps.core.infrastructure.throttling import rate_limit_from_settings | |
| from apps.core.security.auth import JWTOrSessionAuth | |
| from .download_response_factory import build_download_response | |
| logger = logging.getLogger("apps.documents.api") | |
| router = Router(auth=JWTOrSessionAuth()) | |
| def _require_contract_access(request: Any, contract_id: int) -> None: | |
| from apps.core.security.access_context import get_request_access_context | |
| from apps.documents.services.infrastructure.wiring import get_contract_service | |
| ctx = get_request_access_context(request) | |
| get_contract_service().ensure_contract_access_ctx(contract_id=contract_id, ctx=ctx) | |
| def _get_folder_generation_service() -> Any: | |
| """工厂函数:获取 FolderGenerationService 实例""" | |
| from apps.documents.services.generation.folder_generation_service import FolderGenerationService | |
| from apps.documents.services.infrastructure.wiring import get_contract_folder_binding_service, get_contract_service | |
| return FolderGenerationService( | |
| contract_service=get_contract_service(), | |
| folder_binding_service=get_contract_folder_binding_service(), | |
| ) | |
| def _get_supplementary_agreement_service() -> Any: | |
| """工厂函数:获取 SupplementaryAgreementGenerationService 实例""" | |
| from apps.documents.services.infrastructure.wiring import get_supplementary_agreement_generation_service | |
| return get_supplementary_agreement_generation_service() | |
| def _get_contract_generation_service() -> Any: | |
| """工厂函数:获取 ContractGenerationService 实例""" | |
| from apps.documents.services.infrastructure.wiring import get_contract_generation_service | |
| return get_contract_generation_service() | |
| def preview_contract_context(request: Any, contract_id: int) -> Any: | |
| """合同占位符预览""" | |
| _require_contract_access(request, contract_id) | |
| service = _get_contract_generation_service() | |
| rows = service.get_preview_context(contract_id) | |
| return {"success": True, "data": rows} | |
| def preview_supplementary_agreement_context(request: Any, contract_id: int, agreement_id: int) -> Any: | |
| """补充协议占位符预览""" | |
| _require_contract_access(request, contract_id) | |
| service = _get_supplementary_agreement_service() | |
| rows = service.get_preview_context(contract_id, agreement_id) | |
| return {"success": True, "data": rows} | |
| def download_contract_document(request: Any, contract_id: int, split_fee: bool = True) -> Any: | |
| """ | |
| 下载合同文档(DOCX 格式) | |
| 生成单个合同 Word 文档. | |
| 如果合同有文件夹绑定,文件会保存到绑定文件夹,返回 JSON 响应. | |
| 如果没有绑定,返回文件下载响应. | |
| Args: | |
| contract_id: 合同 ID | |
| Returns: | |
| DOCX 文件下载响应或 JSON 响应 | |
| """ | |
| _require_contract_access(request, contract_id) | |
| service = _get_contract_generation_service() | |
| # 生成合同文档 | |
| content, filename, saved_path, error = service.generate_contract_document_result(contract_id, split_fee=split_fee) | |
| if error: | |
| logger.warning("生成合同文档失败: %s", error, extra={"contract_id": contract_id, "error": error}) | |
| raise ValidationException( | |
| message=_("生成合同文档失败"), code="CONTRACT_GENERATION_FAILED", errors={"detail": error} | |
| ) | |
| if saved_path: | |
| logger.info( | |
| "合同文档已保存到绑定文件夹", | |
| extra={ | |
| "contract_id": contract_id, | |
| "doc_filename": filename, | |
| "saved_path": saved_path, | |
| }, | |
| ) | |
| return { | |
| "success": True, | |
| "message": f"合同文档已生成并保存到: {saved_path}", | |
| "filename": filename, | |
| "folder_path": saved_path, | |
| } | |
| response = build_download_response( | |
| content=content, | |
| filename=filename, | |
| content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", | |
| ) | |
| logger.info("合同文档下载成功", extra={"contract_id": contract_id, "doc_filename": filename}) | |
| return response | |
| def download_contract_folder(request: Any, contract_id: int) -> Any: | |
| """ | |
| 下载合同文件夹(ZIP 格式) | |
| 生成包含完整文件夹结构和合同文书的 ZIP 压缩包. | |
| Args: | |
| contract_id: 合同 ID | |
| Returns: | |
| ZIP 文件下载响应 | |
| """ | |
| _require_contract_access(request, contract_id) | |
| service = _get_folder_generation_service() | |
| # 生成文件夹 ZIP | |
| zip_content, zip_filename, extract_path, error = service.generate_folder_with_documents_result(contract_id) | |
| if error: | |
| logger.warning("生成合同文件夹失败: %s", error, extra={"contract_id": contract_id, "error": error}) | |
| raise ValidationException( | |
| message=_("生成合同文件夹失败"), code="FOLDER_GENERATION_FAILED", errors={"detail": error} | |
| ) | |
| if extract_path: | |
| logger.info( | |
| "合同文件夹已解压到绑定文件夹", | |
| extra={"contract_id": contract_id, "zip_filename": zip_filename, "extract_path": extract_path}, | |
| ) | |
| return { | |
| "success": True, | |
| "message": f"合同文件夹已生成并解压到: {extract_path}", | |
| "filename": zip_filename, | |
| "folder_path": extract_path, | |
| } | |
| response = build_download_response(content=zip_content, filename=zip_filename, content_type="application/zip") | |
| logger.info("合同文件夹下载成功", extra={"contract_id": contract_id, "zip_filename": zip_filename}) | |
| return response | |
| def download_supplementary_agreement(request: Any, contract_id: int, agreement_id: int) -> Any: | |
| """ | |
| 下载补充协议文档(DOCX 格式) | |
| 生成补充协议 Word 文档. | |
| 如果合同有文件夹绑定,文件会保存到绑定文件夹,返回 JSON 响应. | |
| 如果没有绑定,返回文件下载响应. | |
| Args: | |
| contract_id: 合同 ID | |
| agreement_id: 补充协议 ID | |
| Returns: | |
| DOCX 文件下载响应或 JSON 响应 | |
| """ | |
| _require_contract_access(request, contract_id) | |
| service = _get_supplementary_agreement_service() | |
| # 生成补充协议文档 | |
| content, filename, saved_path, error = service.generate_supplementary_agreement_result(contract_id, agreement_id) | |
| if error: | |
| logger.warning( | |
| "生成补充协议失败: %s", | |
| error, | |
| extra={"contract_id": contract_id, "agreement_id": agreement_id, "error": error}, | |
| ) | |
| raise ValidationException( | |
| message=_("生成补充协议失败"), code="AGREEMENT_GENERATION_FAILED", errors={"detail": error} | |
| ) | |
| if saved_path: | |
| logger.info( | |
| "补充协议已保存到绑定文件夹", | |
| extra={ | |
| "contract_id": contract_id, | |
| "agreement_id": agreement_id, | |
| "doc_filename": filename, | |
| "saved_path": saved_path, | |
| }, | |
| ) | |
| return { | |
| "success": True, | |
| "message": f"补充协议已生成并保存到: {saved_path}", | |
| "filename": filename, | |
| "folder_path": saved_path, | |
| } | |
| response = build_download_response( | |
| content=content, | |
| filename=filename, | |
| content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", | |
| ) | |
| logger.info( | |
| "补充协议下载成功", extra={"contract_id": contract_id, "agreement_id": agreement_id, "doc_filename": filename} | |
| ) | |
| return response | |