fiuai-sdk-python 0.2.1__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fiuai_sdk_python
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: FiuAI Python SDK - 企业级AI服务集成开发工具包
5
5
  Project-URL: Homepage, https://github.com/fiuai/fiuai-sdk-python
6
6
  Project-URL: Documentation, https://github.com/fiuai/fiuai-sdk-python#readme
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fiuai_sdk_python"
3
- version = "0.2.1"
3
+ version = "0.2.3"
4
4
  description = "FiuAI Python SDK - 企业级AI服务集成开发工具包"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -315,6 +315,12 @@ class FiuaiSDK(object):
315
315
 
316
316
 
317
317
  def get_client(username: str, password: str="", auth_type: Literal["internal", "password"]="password")-> FiuaiSDK:
318
+ """
319
+ 获取FiuaiSDK客户端, 需要提取调用init_fiuai()初始化
320
+ 使用方式有两种:
321
+ 1. 使用密码认证, 需要在调用的的时候传入username和password
322
+ 2. 使用内部认证, 需要在初始化的时候传入tokens, 调用时传入username
323
+ """
318
324
  # 检查是否已初始化
319
325
  if not is_initialized():
320
326
  raise ValueError("FiuaiSDK not initialized. Please call init_fiuai() first.")
@@ -7,7 +7,6 @@
7
7
 
8
8
  from typing import List, Optional, Dict, Any
9
9
  from pydantic import BaseModel, Field
10
- from .setup import get_client
11
10
  from .client import FiuaiSDK
12
11
 
13
12
 
@@ -0,0 +1,170 @@
1
+ # -- coding: utf-8 --
2
+ # Project: fiuaiapp
3
+ # Created Date: 2025 05 Tu
4
+ # Author: liming
5
+ # Email: lmlala@aliyun.com
6
+ # Copyright (c) 2025 FiuAI
7
+
8
+ # const
9
+ AI_ALLOWED_DOCTYPE_META = [
10
+ "Contract",
11
+ "Contract Item",
12
+ "Bank Transaction",
13
+ "Bank Statement",
14
+ # "invoice"
15
+ ]
16
+ USED_COUNTRY_LIST = ["China", "United States", "Japan", "Thailand", "India", "Indonesia", "Malaysia", "Philippines", "Singapore", "South Korea", "United Kingdom", "Vietnam"]
17
+ USED_LANGUAGE_LIST = ["zh", "en", "ja", "th", "id", "ms", "ph", "sg", "kr", "uk", "vn"]
18
+ from .type import (
19
+ UOM,
20
+ Currency,
21
+ Country,
22
+ Language,
23
+ DocTypeMeta,
24
+ DocField,
25
+ AiRecognitionValue
26
+ )
27
+ from typing import List
28
+ from logging import getLogger
29
+
30
+ from .client import FiuaiSDK
31
+
32
+ logger = getLogger(__name__)
33
+
34
+
35
+
36
+ def load_uom_data(client: FiuaiSDK)-> List[UOM]:
37
+ """
38
+ 从frappe获取uom数据
39
+ """
40
+ uom_list = client.get_list(doctype="UOM", fields=["name", "uom_name", "common_code"])
41
+ return [UOM(name=uom["name"], uom_name=uom["uom_name"], common_code=uom["common_code"]) for uom in uom_list]
42
+
43
+ def load_currency_data(client: FiuaiSDK)-> List[Currency]:
44
+ """
45
+ 从frappe获取currency数据
46
+ """
47
+ currency_list = client.get_list(
48
+ doctype="Currency",
49
+ filters={"enabled": 1},
50
+ fields=["name", "currency_name", "fraction_units", "smallest_currency_fraction_value"]
51
+ )
52
+ return [Currency(name=currency["name"], currency_name=currency["currency_name"], fraction_units=currency["fraction_units"], smallest_currency_fraction_value=currency["smallest_currency_fraction_value"]) for currency in currency_list]
53
+
54
+ def load_country_data(client: FiuaiSDK)-> List[Country]:
55
+ """
56
+ 从frappe获取country数据
57
+ """
58
+ country_list = client.get_list(
59
+ doctype="Country",
60
+ filters={"name": ["in", USED_COUNTRY_LIST]},
61
+ fields=["name", "code"]
62
+ )
63
+ return [Country(name=country["name"], code=country["code"]) for country in country_list]
64
+
65
+ def load_language_data(client: FiuaiSDK)-> List[Language]:
66
+ """
67
+ 从frappe获取language数据
68
+ """
69
+ language_list = client.get_list(
70
+ doctype="Language",
71
+ filters={"name": ["in", USED_LANGUAGE_LIST]},
72
+ fields=["name", "language_name"]
73
+ )
74
+ return [Language(name=language["name"], language_name=language["language_name"]) for language in language_list]
75
+
76
+ def load_doctype_meta(client: FiuaiSDK, doctype: str, max_api_retry: int = 3)-> DocTypeMeta:
77
+ """
78
+ 从frappe获取doctype数据
79
+ """
80
+
81
+ retry_count = 0
82
+ doc_meta = None
83
+ while retry_count < max_api_retry:
84
+
85
+ doc_meta = _get_meta(client, doctype)
86
+
87
+ if doc_meta:
88
+ break
89
+ else:
90
+ retry_count += 1
91
+
92
+ return doc_meta
93
+
94
+ def _get_meta(client: FiuaiSDK, doctype: str) -> DocTypeMeta:
95
+ try:
96
+ m = client.get_meta(doctype)
97
+
98
+ if m is None:
99
+ return None
100
+
101
+ _fields = []
102
+ links = []
103
+ child_docs = []
104
+ for _f in m["fields"]:
105
+ field_name = _f["fieldname"]
106
+ field_type = _f["fieldtype"]
107
+ field_prompt = _f.get("field_prompt", "")
108
+ options_str = _f.get("options", "")
109
+ hidden = _f.get("hidden", 0)
110
+ reqd = _f.get("reqd", 0)
111
+ read_only = _f.get("read_only", 0)
112
+
113
+ options = []
114
+ match field_type:
115
+ case "Select":
116
+ options = options_str.split("\n")
117
+ case "Link":
118
+ links.append(options_str)
119
+ options.append(options_str)
120
+ case "Table":
121
+ child_docs.append(options_str)
122
+ options.append(options_str)
123
+ case _:
124
+ pass
125
+
126
+
127
+ if field_prompt == "":
128
+ # 仅有prompt的field才是应该关心的字段,降低复杂度
129
+ continue
130
+ if hidden == 1:
131
+ continue
132
+
133
+
134
+ _fields.append(DocField(
135
+ fieldname=field_name,
136
+ fieldtype=field_type,
137
+ hidden=True if _f.get("hidden", 0) == 1 else False,
138
+ read_only=True if _f.get("read_only", 0) == 1 else False,
139
+ reqd=True if _f.get("reqd", 0) == 1 else False,
140
+ options=options,
141
+ field_prompt=field_prompt,
142
+ ai_recognition_value=AiRecognitionValue(value=None, confidence=0, ai_comment="")
143
+ ))
144
+
145
+ # links, child 去重
146
+ links = list(set(links))
147
+ child_docs = list(set(child_docs))
148
+
149
+ doc_meta = DocTypeMeta(
150
+ name=doctype,
151
+ doctype_prompts=m["doctype_prompts"],
152
+ fields=_fields,
153
+ link_docs=links,
154
+ child_docs=child_docs
155
+ )
156
+ return doc_meta
157
+ except Exception as e:
158
+ logger.error(f"load doctype meta failed: {e.args}")
159
+ return None
160
+
161
+
162
+ def load_all_allowed_doctype_meta(client: FiuaiSDK)-> List[DocTypeMeta]:
163
+ """
164
+ 从frappe获取doctype数据
165
+ """
166
+ r = []
167
+ for _d in AI_ALLOWED_DOCTYPE_META:
168
+ m = load_doctype_meta(client, _d)
169
+ r.append(m)
170
+ return r
@@ -1,187 +0,0 @@
1
- # -- coding: utf-8 --
2
- # Project: fiuaiapp
3
- # Created Date: 2025 05 Tu
4
- # Author: liming
5
- # Email: lmlala@aliyun.com
6
- # Copyright (c) 2025 FiuAI
7
-
8
- # const
9
- AI_ALLOWED_DOCTYPE_META = [
10
- "Contract",
11
- "Contract Item",
12
- "Bank Transaction",
13
- "Bank Statement",
14
- # "invoice"
15
- ]
16
- USED_COUNTRY_LIST = ["China", "United States", "Japan", "Thailand", "India", "Indonesia", "Malaysia", "Philippines", "Singapore", "South Korea", "United Kingdom", "Vietnam"]
17
- USED_LANGUAGE_LIST = ["zh", "en", "ja", "th", "id", "ms", "ph", "sg", "kr", "uk", "vn"]
18
- from .type import (
19
- UOM,
20
- Currency,
21
- Country,
22
- Language,
23
- DocTypeMeta,
24
- DocField,
25
- AiRecognitionValue
26
- )
27
- from typing import List
28
- from logging import getLogger
29
-
30
- from .client import FiuaiSDK
31
- from .util import get_client
32
-
33
- logger = getLogger(__name__)
34
-
35
-
36
- def get_client(username: str="assistant@fiuai.com")-> FiuaiSDK:
37
- """
38
- 获取frappe client
39
- """
40
- return FiuaiSDK(username)
41
-
42
- async def aget_client(username: str="assistant@fiuai.com")-> FiuaiSDK:
43
- """
44
- 获取frappe client
45
- """
46
- return FiuaiSDK(username)
47
-
48
- def load_uom_data()-> List[UOM]:
49
- """
50
- 从frappe获取uom数据
51
- """
52
- with get_client() as client:
53
- uom_list = client.get_list(doctype="UOM", fields=["name", "uom_name", "common_code"])
54
- return [UOM(name=uom["name"], uom_name=uom["uom_name"], common_code=uom["common_code"]) for uom in uom_list]
55
-
56
- def load_currency_data()-> List[Currency]:
57
- """
58
- 从frappe获取currency数据
59
- """
60
- with get_client() as client:
61
- currency_list = client.get_list(
62
- doctype="Currency",
63
- filters={"enabled": 1},
64
- fields=["name", "currency_name", "fraction_units", "smallest_currency_fraction_value"]
65
- )
66
- return [Currency(name=currency["name"], currency_name=currency["currency_name"], fraction_units=currency["fraction_units"], smallest_currency_fraction_value=currency["smallest_currency_fraction_value"]) for currency in currency_list]
67
-
68
- def load_country_data()-> List[Country]:
69
- """
70
- 从frappe获取country数据
71
- """
72
- with get_client() as client:
73
- country_list = client.get_list(
74
- doctype="Country",
75
- filters={"name": ["in", USED_COUNTRY_LIST]},
76
- fields=["name", "code"]
77
- )
78
- return [Country(name=country["name"], code=country["code"]) for country in country_list]
79
-
80
- def load_language_data()-> List[Language]:
81
- """
82
- 从frappe获取language数据
83
- """
84
- with get_client() as client:
85
- language_list = client.get_list(
86
- doctype="Language",
87
- filters={"name": ["in", USED_LANGUAGE_LIST]},
88
- fields=["name", "language_name"]
89
- )
90
- return [Language(name=language["name"], language_name=language["language_name"]) for language in language_list]
91
-
92
- def load_doctype_meta(doctype: str, max_api_retry: int = 3)-> DocTypeMeta:
93
- """
94
- 从frappe获取doctype数据
95
- """
96
-
97
- retry_count = 0
98
- doc_meta = None
99
- while retry_count < max_api_retry:
100
-
101
- doc_meta = _get_meta(doctype=doctype)
102
-
103
- if doc_meta:
104
- break
105
- else:
106
- retry_count += 1
107
-
108
- return doc_meta
109
-
110
- def _get_meta(doctype: str) -> DocTypeMeta:
111
- try:
112
- with get_client() as client:
113
- m = client.get_meta(doctype)
114
-
115
- if m is None:
116
- return None
117
-
118
- _fields = []
119
- links = []
120
- child_docs = []
121
- for _f in m["fields"]:
122
- field_name = _f["fieldname"]
123
- field_type = _f["fieldtype"]
124
- field_prompt = _f.get("field_prompt", "")
125
- options_str = _f.get("options", "")
126
- hidden = _f.get("hidden", 0)
127
- reqd = _f.get("reqd", 0)
128
- read_only = _f.get("read_only", 0)
129
-
130
- options = []
131
- match field_type:
132
- case "Select":
133
- options = options_str.split("\n")
134
- case "Link":
135
- links.append(options_str)
136
- options.append(options_str)
137
- case "Table":
138
- child_docs.append(options_str)
139
- options.append(options_str)
140
- case _:
141
- pass
142
-
143
-
144
- if field_prompt == "":
145
- # 仅有prompt的field才是应该关心的字段,降低复杂度
146
- continue
147
- if hidden == 1:
148
- continue
149
-
150
-
151
- _fields.append(DocField(
152
- fieldname=field_name,
153
- fieldtype=field_type,
154
- hidden=True if _f.get("hidden", 0) == 1 else False,
155
- read_only=True if _f.get("read_only", 0) == 1 else False,
156
- reqd=True if _f.get("reqd", 0) == 1 else False,
157
- options=options,
158
- field_prompt=field_prompt,
159
- ai_recognition_value=AiRecognitionValue(value=None, confidence=0, ai_comment="")
160
- ))
161
-
162
- # links, child 去重
163
- links = list(set(links))
164
- child_docs = list(set(child_docs))
165
-
166
- doc_meta = DocTypeMeta(
167
- name=doctype,
168
- doctype_prompts=m["doctype_prompts"],
169
- fields=_fields,
170
- link_docs=links,
171
- child_docs=child_docs
172
- )
173
- return doc_meta
174
- except Exception as e:
175
- logger.error(f"load doctype meta failed: {e.args}")
176
- return None
177
-
178
-
179
- def load_all_allowed_doctype_meta()-> List[DocTypeMeta]:
180
- """
181
- 从frappe获取doctype数据
182
- """
183
- r = []
184
- for _d in AI_ALLOWED_DOCTYPE_META:
185
- m = load_doctype_meta(_d)
186
- r.append(m)
187
- return r