yq 3 ay önce
ebeveyn
işleme
bd4035565f

+ 8 - 1
.gitignore

@@ -57,4 +57,11 @@ docs/_build/
 
 # PyBuilder
 target/
-
+/.idea/
+/logs
+/cache
+*/image
+*/~$*
+*.ipynb
+/flagged
+.gradio

+ 4 - 2
README.md

@@ -1,3 +1,5 @@
-# coze_znjd
+# znjd
 
-智能尽调
+智能尽调
+
+环境 python3.10

+ 16 - 0
commom/__init__.py

@@ -0,0 +1,16 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2021/11/9
+@desc: 
+"""
+
+from .logger import get_logger
+from .traceId_util import request_id_context
+from .utils import f_doc_export
+
+__all__ = ['get_logger', 'f_doc_export', 'request_id_context']
+
+
+
+

+ 65 - 0
commom/logger.py

@@ -0,0 +1,65 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2022/8/29
+@desc:
+"""
+
+import datetime
+import logging
+import logging.handlers
+import os
+import threading
+import time
+from os.path import dirname, realpath
+
+import pytz
+
+from commom.traceId_util import TraceIdFilter
+
+
+def my_time(*args):
+    return time.strptime(datetime.datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S"),
+                         "%Y-%m-%d %H:%M:%S")
+
+
+_instance_lock = threading.Lock()
+logger_map = {}
+
+
+def get_logger(logger_name: str = None) -> logging.Logger:
+    if logger_name is None:
+        logger_name = "app"
+    if logger_name in logger_map.keys():
+        return logger_map.get(logger_name)
+    with _instance_lock:
+        if logger_name in logger_map.keys():
+            return logger_map.get(logger_name)
+
+        _logger = logging.Logger(logger_name)
+        _logger.setLevel(logging.INFO)
+        _logger.addFilter(TraceIdFilter())
+
+        formatter = logging.Formatter(
+            '[%(asctime)s] [requestId-%(requestId)s] [%(levelname)s] [%(threadName)s] [%(filename)s] [func:%(funcName)s line:%(lineno)d]\n %(message)s')
+        formatter.converter = my_time
+
+        log_path = os.path.join(dirname(dirname(realpath(__file__))), "logs")
+        filename = os.path.join(log_path, f"{logger_name}.log")
+
+        if not os.path.exists(dirname(filename)):
+            os.makedirs(dirname(filename))
+        print(f"日志路径:{filename}")
+
+        handler = logging.handlers.TimedRotatingFileHandler(filename, when="MIDNIGHT", interval=30, backupCount=4,
+                                                            encoding="utf8", atTime=datetime.time(0, 0, 0, 0))
+        handler.setFormatter(formatter)
+        _logger.addHandler(handler)
+
+        console_handler = logging.StreamHandler()
+        console_handler.setFormatter(formatter)
+        _logger.addHandler(console_handler)
+
+        logger_map[logger_name] = _logger
+
+        return _logger

+ 18 - 0
commom/traceId_util.py

@@ -0,0 +1,18 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2023/5/16
+@desc: 
+"""
+
+import logging
+from contextvars import ContextVar
+
+request_id_context = ContextVar('request_id')
+
+
+class TraceIdFilter(logging.Filter):
+
+    def filter(self, record):
+        record.requestId = request_id_context.get()
+        return True

+ 96 - 0
commom/utils.py

@@ -0,0 +1,96 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2023/12/28
+@desc: 
+"""
+
+import json
+import os
+import time
+
+import lark_oapi as lark
+from lark_oapi.api.drive.v1 import CreateExportTaskRequest, ExportTask, CreateExportTaskResponse, GetExportTaskRequest, \
+    GetExportTaskResponse, DownloadExportTaskRequest, DownloadExportTaskResponse
+
+from config import BaseConfig
+
+
+def f_doc_export(token:str) -> str:
+    # 飞书在线文档转word
+    app_id = BaseConfig.app_id
+    app_secret = BaseConfig.app_secret
+    word_save_dir = BaseConfig.word_save_dir
+
+    client = lark.Client.builder() \
+        .app_id(app_id) \
+        .app_secret(app_secret) \
+        .log_level(lark.LogLevel.DEBUG) \
+        .build()
+
+    # 构造请求对象
+    request1: CreateExportTaskRequest = CreateExportTaskRequest.builder() \
+        .request_body(ExportTask.builder()
+                      .file_extension("docx")
+                      .token(token)
+                      .type("docx")
+                      .build()) \
+        .build()
+
+    # 发起请求
+    response1: CreateExportTaskResponse = client.drive.v1.export_task.create(request1)
+
+    # 处理失败返回
+    if not response1.success():
+        lark.logger.error(
+            f"client.drive.v1.export_task.create failed, code: {response1.code}, msg: {response1.msg}, log_id: {response1.get_log_id()}, resp: \n{json.dumps(json.loads(response1.raw.content), indent=4, ensure_ascii=False)}")
+        return
+
+    # 处理业务结果
+    lark.logger.info(lark.JSON.marshal(response1.data, indent=4))
+    ticket = response1.data.ticket
+
+    time.sleep(5)
+    # 构造请求对象
+    request2: GetExportTaskRequest = GetExportTaskRequest.builder() \
+        .ticket(ticket) \
+        .token(token) \
+        .build()
+
+    # 发起请求
+    response2: GetExportTaskResponse = client.drive.v1.export_task.get(request2)
+
+    # 处理失败返回
+    if not response2.success():
+        lark.logger.error(
+            f"client.drive.v1.export_task.get failed, code: {response2.code}, msg: {response2.msg}, log_id: {response2.get_log_id()}, resp: \n{json.dumps(json.loads(response2.raw.content), indent=4, ensure_ascii=False)}")
+        return
+
+    # 处理业务结果
+    lark.logger.info(lark.JSON.marshal(response2.data, indent=4))
+    file_token = response2.data.result.file_token
+
+    # 构造请求对象
+    request3: DownloadExportTaskRequest = DownloadExportTaskRequest.builder() \
+        .file_token(file_token) \
+        .build()
+
+    # 发起请求
+    response3: DownloadExportTaskResponse = client.drive.v1.export_task.download(request3)
+
+    # 处理失败返回
+    if not response3.success():
+        lark.logger.error(
+            f"client.drive.v1.export_task.download failed, code: {response3.code}, msg: {response3.msg}, log_id: {response3.get_log_id()}")
+        return
+
+    # 处理业务结果
+    save_path = os.path.join(word_save_dir, response3.file_name)
+    with open(save_path, "wb") as f:
+        f.write(response3.file.read())
+
+    return save_path
+
+
+if __name__ == "__main__":
+    f_doc_export('YKNBdbs10oA3pCxTdnAczcvOnxc')

+ 13 - 0
config/__init__.py

@@ -0,0 +1,13 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2022/10/24
+@desc: 
+"""
+
+from .base_config import BaseConfig
+
+__all__ = ['BaseConfig']
+
+
+

+ 13 - 0
config/base_config.py

@@ -0,0 +1,13 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2022/10/24
+@desc: 
+"""
+import os
+
+class BaseConfig:
+    app_id = "cli_a7d162fba475500b"
+    app_secret = "HmnOf7JdQTnoysFxn7aMBeHQt48nqHou"
+    word_save_dir = os.path.join(".", "大模型企业调查报告")
+    os.makedirs(word_save_dir, exist_ok=True)

+ 0 - 0
entitys/__init__.py


+ 33 - 0
entitys/response.py

@@ -0,0 +1,33 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2023/12/29
+@desc: 
+"""
+import pydantic
+from pydantic import BaseModel
+
+
+class BaseResponse(BaseModel):
+    data: object = pydantic.Field(None, description="request id")
+    code: int = pydantic.Field(200, description="HTTP status code")
+    msg: str = pydantic.Field("success", description="HTTP status message")
+    success: bool = pydantic.Field(True, description="success status")
+
+    class Config:
+        schema_extra = {
+            "example": {
+                "data": None,
+                "code": 200,
+                "msg": "success",
+                "success": True
+            }
+        }
+
+    @staticmethod
+    def ofSuccess(data: object):
+        return BaseResponse(data=data, code=200, msg="success", success=True)
+
+    @staticmethod
+    def ofFailure(msg: str = "error"):
+        return BaseResponse(data=None, code=500, msg=msg, success=False)

+ 0 - 0
enums/__init__.py


+ 68 - 0
main.py

@@ -0,0 +1,68 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2022/8/29
+@desc:
+"""
+
+import argparse
+import time
+import traceback
+import uuid
+
+import uvicorn
+from fastapi import FastAPI, Request, Path
+from starlette.responses import RedirectResponse
+
+from commom import f_doc_export, get_logger, request_id_context
+from entitys.response import BaseResponse
+
+logger = get_logger()
+app = FastAPI()
+
+
+def doc_export(
+        token: str = Path(title='doc token', description="文档的token")
+):
+    try:
+        logger.info(f"{token=}")
+        f_doc_export(token)
+
+        return BaseResponse.ofSuccess("")
+
+    except Exception as msg:
+        logger.error(traceback.format_exc())
+        return BaseResponse.ofFailure(str(msg))
+
+
+@app.middleware("http")
+async def add_request_id_header(request: Request, call_next):
+    request_id = request.headers.get("X-REQUEST-ID")
+    if request_id is None or len(request_id) == 0:
+        request_id = str(uuid.uuid4())
+    request_id_context.set(request_id)
+    start_time = time.time()
+    response = await call_next(request)
+    process_time = time.time() - start_time
+    response.headers["X-REQUEST-ID"] = request_id_context.get()
+    response.headers["PROCESS-TIME"] = f"{process_time:.2f}"
+
+    return response
+
+
+async def document():
+    return RedirectResponse(url="/docs")
+
+
+def api_start(host, port):
+    app.get("/", response_model=BaseResponse)(document)
+    app.get("/znjd/doc/export/{token}", response_model=BaseResponse)(doc_export)
+    uvicorn.run(app, host=host, port=port)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--host", type=str, default="0.0.0.0")
+    parser.add_argument("--port", type=int, default=18070)
+    args = parser.parse_args()
+    api_start(args.host, args.port)

+ 1 - 0
requirements.txt

@@ -0,0 +1 @@
+lark-oapi==1.4.6

+ 6 - 0
services/__init__.py

@@ -0,0 +1,6 @@
+# -*- coding:utf-8 -*-
+"""
+@author: isaacqyang
+@time: 2023/12/28
+@desc: 
+"""

+ 31 - 0
start.sh

@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#source activate py310
+
+PATH_APP=$(pwd)
+
+function get_pid() {
+  APP_PID=$(ps -ef | grep "python $PATH_APP/main.py" | grep -v grep | awk '{print $2}')
+}
+
+function kill_app() {
+  if [ -n $APP_PID ]; then
+    for v in $APP_PID; do
+      echo $(date +%F%n%T) "开始杀死已有进程: $v"
+      kill -9 $v
+    done
+  fi
+}
+
+function start_app() {
+  echo $(date +%F%n%T) "开始启动 app..."
+  PYTHONIOENCODING=utf-8 nohup python $PATH_APP/main.py > $PATH_APP/nohup.out 2>&1 &
+  sleep 3
+  echo $(tail -50 $PATH_APP/nohup.out)
+  echo "启动完成..."
+  echo "日志请查看 $PATH_APP/nohup.out"
+}
+
+get_pid
+kill_app
+start_app