programgarden 1.22.3__tar.gz → 1.22.4__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 (34) hide show
  1. {programgarden-1.22.3 → programgarden-1.22.4}/PKG-INFO +2 -2
  2. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/context.py +5 -0
  3. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/executor.py +35 -2
  4. {programgarden-1.22.3 → programgarden-1.22.4}/pyproject.toml +2 -2
  5. {programgarden-1.22.3 → programgarden-1.22.4}/README.md +0 -0
  6. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/__init__.py +0 -0
  7. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/binding_validator.py +0 -0
  8. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/client.py +0 -0
  9. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/database/__init__.py +0 -0
  10. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/database/checkpoint_manager.py +0 -0
  11. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/database/query_builder.py +0 -0
  12. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/database/workflow_position_tracker.py +0 -0
  13. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/database/workflow_risk_tracker.py +0 -0
  14. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/node_runner.py +0 -0
  15. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/plugin/__init__.py +0 -0
  16. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/plugin/sandbox.py +0 -0
  17. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/providers/__init__.py +0 -0
  18. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/providers/llm_errors.py +0 -0
  19. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/providers/llm_provider.py +0 -0
  20. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/reconnect_handler.py +0 -0
  21. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resolver.py +0 -0
  22. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resource/__init__.py +0 -0
  23. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resource/context.py +0 -0
  24. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resource/limiter.py +0 -0
  25. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resource/monitor.py +0 -0
  26. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/resource/throttle.py +0 -0
  27. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/__init__.py +0 -0
  28. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/credential_tools.py +0 -0
  29. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/definition_tools.py +0 -0
  30. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/event_tools.py +0 -0
  31. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/job_tools.py +0 -0
  32. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/registry_tools.py +0 -0
  33. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/tools/sqlite_tools.py +0 -0
  34. {programgarden-1.22.3 → programgarden-1.22.4}/programgarden/validation_recommender.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: programgarden
3
- Version: 1.22.3
3
+ Version: 1.22.4
4
4
  Summary: ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진
5
5
  Author: 프로그램동산
6
6
  Author-email: coding@programgarden.com
@@ -16,7 +16,7 @@ Requires-Dist: litellm (>=1.40.0)
16
16
  Requires-Dist: lxml (>=6.0.2,<7.0.0)
17
17
  Requires-Dist: programgarden-community (>=1.13.8,<2.0.0)
18
18
  Requires-Dist: programgarden-core (>=1.14.3,<2.0.0)
19
- Requires-Dist: programgarden-finance (>=1.6.9,<2.0.0)
19
+ Requires-Dist: programgarden-finance (>=1.6.10,<2.0.0)
20
20
  Requires-Dist: psutil (>=6.0.0,<7.0.0)
21
21
  Requires-Dist: psycopg2-binary (>=2.9.11,<3.0.0)
22
22
  Requires-Dist: pydantic (>=2.0.0,<3.0.0)
@@ -150,12 +150,17 @@ class ExecutionContext:
150
150
  workflow_edges: Optional[List[Any]] = None, # List[ResolvedEdge]
151
151
  workflow_nodes: Optional[Dict[str, Any]] = None, # Dict[str, ResolvedNode]
152
152
  storage_dir: Optional[str] = None,
153
+ ls_token_provider: Optional[Any] = None, # sync (appkey, product, paper_trading) -> (token, expires_at_epoch)
153
154
  ):
154
155
  self.job_id = job_id
155
156
  self.workflow_id = workflow_id
156
157
  self._storage_dir = storage_dir
157
158
  self.context_params = context_params or {}
158
159
 
160
+ # Opt-in LS token provider (Verified League §3.2.3). When set, broker
161
+ # logins consume a server-issued token instead of self-issuing.
162
+ self.ls_token_provider = ls_token_provider
163
+
159
164
  # Secrets storage (never logged, separate from context_params)
160
165
  self._secrets: Dict[str, Any] = secrets or {}
161
166
 
@@ -277,7 +277,23 @@ class LSClientManager:
277
277
  # 새 인스턴스 생성 (싱글톤 우회)
278
278
  ls = object.__new__(LS)
279
279
  ls.__init__()
280
-
280
+
281
+ # Verified League §3.2.3: when a token provider is configured, route this
282
+ # LS instance through it (server = single issuer) so login consumes a
283
+ # server-issued token instead of self-issuing via GenerateToken. login()
284
+ # is synchronous, so we register a sync provider (it is also reused by the
285
+ # async refresh path as a fallback). Bound to this instance's
286
+ # appkey/product/paper_trading; returns (access_token, expires_at_epoch).
287
+ token_provider = getattr(context, "ls_token_provider", None)
288
+ if token_provider is not None:
289
+ def _sync_token_provider(
290
+ _appkey=appkey, _product=product, _paper=paper_trading,
291
+ ):
292
+ return token_provider(_appkey, _product, _paper)
293
+
294
+ ls.set_token_provider(provider=_sync_token_provider)
295
+ context.log("info", f"LS token provider attached for {product}", node_id)
296
+
281
297
  # 로그인
282
298
  login_result = ls.login(
283
299
  appkey=appkey,
@@ -14976,6 +14992,21 @@ class WorkflowExecutor:
14976
14992
  self._executors: Dict[str, NodeExecutorBase] = self._init_executors()
14977
14993
  # 동적 노드 레지스트리 (지연 임포트로 순환 참조 방지)
14978
14994
  self._dynamic_registry = None
14995
+ # Opt-in LS token provider (Verified League §3.2.3). When set, broker
14996
+ # logins fetch the token from this callback (a remote server) instead of
14997
+ # self-issuing via GenerateToken, so the platform server is the single
14998
+ # token issuer and this executor is a pure consumer. login() is sync, so
14999
+ # the provider is a sync callable:
15000
+ # (appkey: str, product: str, paper_trading: bool) -> (access_token, expires_at_epoch)
15001
+ # Left None for standalone/public usage (unchanged self-issue path).
15002
+ self.ls_token_provider = None
15003
+
15004
+ def set_ls_token_provider(self, provider) -> None:
15005
+ """Configure the opt-in LS token provider (Verified League §3.2.3).
15006
+
15007
+ Pass None to clear and revert to the default self-issue path.
15008
+ """
15009
+ self.ls_token_provider = provider
14979
15010
 
14980
15011
  def _get_dynamic_registry(self):
14981
15012
  """DynamicNodeRegistry 싱글톤 반환 (지연 로딩)"""
@@ -15231,8 +15262,9 @@ class WorkflowExecutor:
15231
15262
  workflow_edges=resolved.edges,
15232
15263
  workflow_nodes=resolved.nodes,
15233
15264
  storage_dir=storage_dir,
15265
+ ls_token_provider=self.ls_token_provider,
15234
15266
  )
15235
-
15267
+
15236
15268
  # Set listeners (Option A: inject at creation)
15237
15269
  if listeners:
15238
15270
  context.set_listeners(listeners)
@@ -15355,6 +15387,7 @@ class WorkflowExecutor:
15355
15387
  workflow_edges=resolved.edges,
15356
15388
  workflow_nodes=resolved.nodes,
15357
15389
  storage_dir=storage_dir,
15390
+ ls_token_provider=self.ls_token_provider,
15358
15391
  )
15359
15392
 
15360
15393
  if listeners:
@@ -5,7 +5,7 @@ authors = [
5
5
  homepage = "https://programgarden.com"
6
6
  requires-python = ">=3.12"
7
7
  name = "programgarden"
8
- version = "1.22.3"
8
+ version = "1.22.4"
9
9
  description = "ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진"
10
10
  readme = "README.md"
11
11
 
@@ -29,7 +29,7 @@ pytickersymbols = {version = ">=1.17.5", python = ">=3.12,<4.0"}
29
29
  aiosqlite = "^0.20.0"
30
30
  litellm = ">=1.40.0"
31
31
  programgarden-core = "^1.14.3"
32
- programgarden-finance = "^1.6.9"
32
+ programgarden-finance = "^1.6.10"
33
33
  programgarden-community = "^1.13.8"
34
34
 
35
35
  [tool.poetry.group.dev.dependencies]
File without changes