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.
Files changed (43) hide show
  1. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/PKG-INFO +1 -1
  2. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/pyproject.toml +1 -1
  3. fiuai_sdk_python-0.11.1/src/fiuai_sdk_python/pkg/scheduler/__init__.py +13 -0
  4. fiuai_sdk_python-0.11.1/src/fiuai_sdk_python/pkg/scheduler/runner.py +153 -0
  5. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/profile.py +2 -0
  6. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/.gitignore +0 -0
  7. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/CHANGELOG.md +0 -0
  8. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/LICENSE +0 -0
  9. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/README.md +0 -0
  10. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/__init__.py +0 -0
  11. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/__init__.py +0 -0
  12. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/context_mgr.py +0 -0
  13. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/header.py +0 -0
  14. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/helper.py +0 -0
  15. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/auth/type.py +0 -0
  16. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/bank.py +0 -0
  17. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/client.py +0 -0
  18. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/company.py +0 -0
  19. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/config.py +0 -0
  20. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/const.py +0 -0
  21. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/context.py +0 -0
  22. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/datatype.py +0 -0
  23. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/doctype.py +0 -0
  24. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/error.py +0 -0
  25. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/examples/fastapi_integration.py +0 -0
  26. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/http/__init__.py +0 -0
  27. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/http/client.py +0 -0
  28. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/item.py +0 -0
  29. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/perm.py +0 -0
  30. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/__init__.py +0 -0
  31. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/cache_client.py +0 -0
  32. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/circuit_breaker.py +0 -0
  33. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/decorator.py +0 -0
  34. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/redis_manager.py +0 -0
  35. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/pkg/cache/types.py +0 -0
  36. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/resp.py +0 -0
  37. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/setup.py +0 -0
  38. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/type.py +0 -0
  39. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/util.py +0 -0
  40. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/__init__.py +0 -0
  41. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/ids.py +0 -0
  42. {fiuai_sdk_python-0.10.0 → fiuai_sdk_python-0.11.1}/src/fiuai_sdk_python/utils/logger.py +0 -0
  43. {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.10.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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fiuai_sdk_python"
3
- version = "0.10.0"
3
+ version = "0.11.1"
4
4
  description = "FiuAI Python SDK - 企业级AI服务集成开发工具包"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -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,