fiuai-sdk-python 0.10.0__tar.gz → 0.11.1__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.
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/PKG-INFO +1 -1
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/pyproject.toml +1 -1
- fiuai_sdk_python-0.11.1/src/fiuai_sdk_python/pkg/scheduler/__init__.py +13 -0
- fiuai_sdk_python-0.11.1/src/fiuai_sdk_python/pkg/scheduler/runner.py +153 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/profile.py +2 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/.gitignore +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/CHANGELOG.md +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/LICENSE +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/README.md +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/__init__.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/__init__.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/context_mgr.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/header.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/helper.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/type.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/bank.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/client.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/company.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/config.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/const.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/context.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/datatype.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/doctype.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/error.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/examples/fastapi_integration.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/http/__init__.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/http/client.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/item.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/perm.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/__init__.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/cache_client.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/circuit_breaker.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/decorator.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/redis_manager.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/types.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/resp.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/setup.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/type.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/util.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/__init__.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/ids.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/logger.py +0 -0
- {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/text.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fiuai_sdk_python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
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
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# -- coding: utf-8 --
|
|
2
|
+
# Project: fiuai-sdk-python
|
|
3
|
+
# Created Date: 2026-04-10
|
|
4
|
+
# Author: liming
|
|
5
|
+
# Agent: Cursor
|
|
6
|
+
# Email: lmlala@aliyun.com
|
|
7
|
+
# Copyright (c) 2025 FiuAI
|
|
8
|
+
|
|
9
|
+
from .runner import PeriodicRunner
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"PeriodicRunner",
|
|
13
|
+
]
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# -- coding: utf-8 --
|
|
2
|
+
# Project: fiuai-sdk-python
|
|
3
|
+
# Created Date: 2026-04-10
|
|
4
|
+
# Author: liming
|
|
5
|
+
# Agent: Cursor
|
|
6
|
+
# Email: lmlala@aliyun.com
|
|
7
|
+
# Copyright (c) 2025 FiuAI
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import random
|
|
11
|
+
from collections.abc import Awaitable, Callable
|
|
12
|
+
from datetime import datetime, timezone
|
|
13
|
+
|
|
14
|
+
from ...utils.logger import get_logger
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PeriodicRunner:
|
|
20
|
+
"""通用异步定时任务运行器
|
|
21
|
+
|
|
22
|
+
支持两种运行方式:
|
|
23
|
+
- 嵌入 FastAPI: asyncio.create_task(runner.start())
|
|
24
|
+
- 独立进程: asyncio.run(runner.start())
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
name: str,
|
|
30
|
+
task: Callable[[], Awaitable[None]],
|
|
31
|
+
interval_seconds: float,
|
|
32
|
+
*,
|
|
33
|
+
run_on_start: bool = True,
|
|
34
|
+
error_handler: Callable[[Exception], Awaitable[None]] | None = None,
|
|
35
|
+
jitter_seconds: float = 0,
|
|
36
|
+
) -> None:
|
|
37
|
+
if not name:
|
|
38
|
+
raise ValueError("name must not be empty")
|
|
39
|
+
if not callable(task):
|
|
40
|
+
raise TypeError("task must be callable")
|
|
41
|
+
if interval_seconds <= 0:
|
|
42
|
+
raise ValueError("interval_seconds must be positive")
|
|
43
|
+
if jitter_seconds < 0:
|
|
44
|
+
raise ValueError("jitter_seconds must be non-negative")
|
|
45
|
+
|
|
46
|
+
self._name = name
|
|
47
|
+
self._task = task
|
|
48
|
+
self._interval_seconds = interval_seconds
|
|
49
|
+
self._run_on_start = run_on_start
|
|
50
|
+
self._error_handler = error_handler
|
|
51
|
+
self._jitter_seconds = jitter_seconds
|
|
52
|
+
|
|
53
|
+
self._running = False
|
|
54
|
+
self._stop_event: asyncio.Event | None = None
|
|
55
|
+
self._last_run_at: datetime | None = None
|
|
56
|
+
self._last_error: Exception | None = None
|
|
57
|
+
self._consecutive_failures = 0
|
|
58
|
+
|
|
59
|
+
# -- public API ----------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
async def start(self) -> None:
|
|
62
|
+
"""启动循环, 阻塞直到 stop() 被调用"""
|
|
63
|
+
self._running = True
|
|
64
|
+
self._stop_event = asyncio.Event()
|
|
65
|
+
|
|
66
|
+
logger.info(
|
|
67
|
+
"[PeriodicRunner:%s] started (interval=%ss, jitter=%ss)",
|
|
68
|
+
self._name,
|
|
69
|
+
self._interval_seconds,
|
|
70
|
+
self._jitter_seconds,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
if self._run_on_start:
|
|
75
|
+
await self._safe_execute()
|
|
76
|
+
|
|
77
|
+
while self._running:
|
|
78
|
+
sleep_time = self._interval_seconds
|
|
79
|
+
if self._jitter_seconds > 0:
|
|
80
|
+
sleep_time += random.uniform(0, self._jitter_seconds)
|
|
81
|
+
|
|
82
|
+
# 可中断 sleep: stop() 时 _stop_event 被 set, wait_for 立即返回
|
|
83
|
+
try:
|
|
84
|
+
await asyncio.wait_for(
|
|
85
|
+
self._stop_event.wait(), timeout=sleep_time
|
|
86
|
+
)
|
|
87
|
+
break
|
|
88
|
+
except asyncio.TimeoutError:
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
if not self._running:
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
await self._safe_execute()
|
|
95
|
+
finally:
|
|
96
|
+
self._running = False
|
|
97
|
+
logger.info("[PeriodicRunner:%s] stopped", self._name)
|
|
98
|
+
|
|
99
|
+
def stop(self) -> None:
|
|
100
|
+
"""请求停止 (当前周期结束后退出)"""
|
|
101
|
+
self._running = False
|
|
102
|
+
if self._stop_event is not None:
|
|
103
|
+
self._stop_event.set()
|
|
104
|
+
|
|
105
|
+
# -- properties -----------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def name(self) -> str:
|
|
109
|
+
return self._name
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def is_running(self) -> bool:
|
|
113
|
+
return self._running
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def last_run_at(self) -> datetime | None:
|
|
117
|
+
return self._last_run_at
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def last_error(self) -> Exception | None:
|
|
121
|
+
return self._last_error
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def consecutive_failures(self) -> int:
|
|
125
|
+
return self._consecutive_failures
|
|
126
|
+
|
|
127
|
+
# -- internals ------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
async def _safe_execute(self) -> None:
|
|
130
|
+
try:
|
|
131
|
+
await self._task()
|
|
132
|
+
self._last_run_at = datetime.now(timezone.utc)
|
|
133
|
+
self._last_error = None
|
|
134
|
+
self._consecutive_failures = 0
|
|
135
|
+
except Exception as exc:
|
|
136
|
+
self._last_error = exc
|
|
137
|
+
self._consecutive_failures += 1
|
|
138
|
+
logger.error(
|
|
139
|
+
"[PeriodicRunner:%s] task failed (%d): %s",
|
|
140
|
+
self._name,
|
|
141
|
+
self._consecutive_failures,
|
|
142
|
+
exc,
|
|
143
|
+
exc_info=True,
|
|
144
|
+
)
|
|
145
|
+
if self._error_handler:
|
|
146
|
+
try:
|
|
147
|
+
await self._error_handler(exc)
|
|
148
|
+
except Exception as handler_exc:
|
|
149
|
+
logger.warning(
|
|
150
|
+
"[PeriodicRunner:%s] error_handler raised: %s",
|
|
151
|
+
self._name,
|
|
152
|
+
handler_exc,
|
|
153
|
+
)
|
|
@@ -145,6 +145,7 @@ class UserCurrentCompanyInfo(BaseModel):
|
|
|
145
145
|
country_region: str = Field(description="国家")
|
|
146
146
|
default_currency: str = Field(description="货币")
|
|
147
147
|
company_size: str = Field(description="公司规模")
|
|
148
|
+
industry: str = Field(description="行业")
|
|
148
149
|
entity_type: Literal["Enterprise", "Individual", "Other"] = Field(description="公司类型")
|
|
149
150
|
tax_payer_type: Optional[TaxPayerType] = Field(default=None, description="纳税人类型,一般纳税人,小规模纳税人,其他")
|
|
150
151
|
tax_source_location: Optional[str] = Field(default=None, description="税务登记地,中国特有配置,按省级行政区划分,比如江苏是3200")
|
|
@@ -234,6 +235,7 @@ class UserProfileInfo(BaseModel):
|
|
|
234
235
|
country_region=self.user_current_company_info.country_region,
|
|
235
236
|
default_currency=self.user_current_company_info.default_currency,
|
|
236
237
|
company_size=self.user_current_company_info.company_size,
|
|
238
|
+
industry=self.user_current_company_info.industry,
|
|
237
239
|
entity_type=self.user_current_company_info.entity_type,
|
|
238
240
|
tax_payer_type=self.user_current_company_info.tax_payer_type,
|
|
239
241
|
tax_source_location=self.user_current_company_info.tax_source_location,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/context_mgr.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/__init__.py
RENAMED
|
File without changes
|
{fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/cache_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/decorator.py
RENAMED
|
File without changes
|
{fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/redis_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|