dc-python-sdk 1.5.21__tar.gz → 1.5.22__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 (35) hide show
  1. {dc_python_sdk-1.5.21/src/dc_python_sdk.egg-info → dc_python_sdk-1.5.22}/PKG-INFO +1 -1
  2. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/pyproject.toml +1 -1
  3. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/setup.cfg +1 -1
  4. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22/src/dc_python_sdk.egg-info}/PKG-INFO +1 -1
  5. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/cli.py +1 -1
  6. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/ai_http.py +91 -3
  7. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/server.py +3 -2
  8. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/LICENSE +0 -0
  9. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/README.md +0 -0
  10. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_python_sdk.egg-info/SOURCES.txt +0 -0
  11. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_python_sdk.egg-info/dependency_links.txt +0 -0
  12. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_python_sdk.egg-info/entry_points.txt +0 -0
  13. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_python_sdk.egg-info/requires.txt +0 -0
  14. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_python_sdk.egg-info/top_level.txt +0 -0
  15. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/__init__.py +0 -0
  16. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/app.py +0 -0
  17. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/errors.py +0 -0
  18. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/handler.py +0 -0
  19. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/__init__.py +0 -0
  20. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/ai.py +0 -0
  21. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/mapping.py +0 -0
  22. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/models/__init__.py +0 -0
  23. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/models/enums.py +0 -0
  24. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/models/errors.py +0 -0
  25. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/models/log_templates.py +0 -0
  26. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/models/pipeline_details.py +0 -0
  27. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/pipeline.py +0 -0
  28. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/__init__.py +0 -0
  29. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/api.py +0 -0
  30. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/aws.py +0 -0
  31. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/environment.py +0 -0
  32. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/loader.py +0 -0
  33. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/logger.py +0 -0
  34. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/src/services/session.py +0 -0
  35. {dc_python_sdk-1.5.21 → dc_python_sdk-1.5.22}/src/dc_sdk/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dc-python-sdk
3
- Version: 1.5.21
3
+ Version: 1.5.22
4
4
  Summary: Data Connector Python SDK
5
5
  Home-page: https://github.com/data-connector/dc-python-sdk
6
6
  Author: DataConnector
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dc-python-sdk"
7
- version = "1.5.21"
7
+ version = "1.5.22"
8
8
  description = "Data Connector Python SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6"
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = dc-python-sdk
3
- version = 1.5.21
3
+ version = 1.5.22
4
4
  author = DataConnector
5
5
  author_email = josh@dataconnector.com
6
6
  description = A small example package
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dc-python-sdk
3
- Version: 1.5.21
3
+ Version: 1.5.22
4
4
  Summary: Data Connector Python SDK
5
5
  Home-page: https://github.com/data-connector/dc-python-sdk
6
6
  Author: DataConnector
@@ -31,7 +31,7 @@ def main():
31
31
 
32
32
  elif command == "ai-http":
33
33
  from dc_sdk.src.ai_http import start_ai_http
34
- start_ai_http()
34
+ start_ai_http(connector_port=port)
35
35
 
36
36
  else:
37
37
  print(f"Unknown command: {command}")
@@ -10,6 +10,7 @@ from openai import OpenAI
10
10
  import atexit
11
11
  import signal
12
12
  import shutil
13
+ import threading
13
14
 
14
15
  logger = logging.getLogger(__name__)
15
16
 
@@ -21,6 +22,11 @@ client = None
21
22
  workspace = os.getenv("WORKSPACE", "/workspace")
22
23
  port_for_connector = 5000
23
24
 
25
+ # Process-wide TTL for ai-http (see DC_SDK_TTL_SECONDS); exposed in /session-info.
26
+ process_ttl_seconds: Optional[float] = None
27
+ process_ttl_deadline_unix: Optional[float] = None
28
+ _process_ttl_timer: Optional[threading.Timer] = None
29
+
24
30
  # -----------------------------
25
31
  # MODELS
26
32
  # -----------------------------
@@ -71,6 +77,34 @@ def get_free_port():
71
77
  return port
72
78
 
73
79
 
80
+ _DEFAULT_PROCESS_TTL_SECONDS = 600.0
81
+
82
+
83
+ def _parse_process_ttl_seconds() -> float:
84
+ """
85
+ Wall-clock lifetime for the whole ai-http process from start_ai_http() entry.
86
+ Env DC_SDK_TTL_SECONDS: positive seconds; unset or empty → 600 (10m); 0 → disabled.
87
+ """
88
+ raw = os.environ.get("DC_SDK_TTL_SECONDS")
89
+ if raw is None:
90
+ return _DEFAULT_PROCESS_TTL_SECONDS
91
+ raw = raw.strip()
92
+ if raw == "":
93
+ return _DEFAULT_PROCESS_TTL_SECONDS
94
+ try:
95
+ v = float(raw)
96
+ except ValueError:
97
+ logger.warning(
98
+ "Invalid DC_SDK_TTL_SECONDS=%r; using default %s",
99
+ raw,
100
+ _DEFAULT_PROCESS_TTL_SECONDS,
101
+ )
102
+ return _DEFAULT_PROCESS_TTL_SECONDS
103
+ if v <= 0:
104
+ return 0.0
105
+ return v
106
+
107
+
74
108
  def start_connector():
75
109
  global workspace
76
110
  global port_for_connector
@@ -708,9 +742,49 @@ def start_ai_http(connector_port=5000):
708
742
  global client
709
743
  global workspace
710
744
  global port_for_connector
745
+ global process_ttl_seconds
746
+ global process_ttl_deadline_unix
747
+ global _process_ttl_timer
711
748
 
712
749
  port_for_connector = connector_port
713
750
 
751
+ process_ttl_seconds = None
752
+ process_ttl_deadline_unix = None
753
+ _process_ttl_timer = None
754
+
755
+ ttl_sec = _parse_process_ttl_seconds()
756
+ ttl_shutdown_holder: Dict[str, Any] = {"fn": None}
757
+
758
+ if ttl_sec > 0:
759
+ process_ttl_seconds = ttl_sec
760
+ process_ttl_deadline_unix = time.time() + ttl_sec
761
+
762
+ def on_process_ttl():
763
+ logger.warning(
764
+ "DC_SDK_TTL_SECONDS (%s s) elapsed; stopping and exiting process",
765
+ ttl_sec,
766
+ )
767
+ fn = ttl_shutdown_holder.get("fn")
768
+ if callable(fn):
769
+ try:
770
+ fn()
771
+ except Exception:
772
+ logger.exception("Process TTL shutdown hook failed")
773
+ os._exit(0)
774
+
775
+ _process_ttl_timer = threading.Timer(ttl_sec, on_process_ttl)
776
+ _process_ttl_timer.daemon = True
777
+ _process_ttl_timer.start()
778
+ logger.info(
779
+ "Process TTL active: exit after %s s wall clock (DC_SDK_TTL_SECONDS)",
780
+ ttl_sec,
781
+ )
782
+ else:
783
+ logger.info(
784
+ "Process TTL disabled (DC_SDK_TTL_SECONDS=%r)",
785
+ os.environ.get("DC_SDK_TTL_SECONDS"),
786
+ )
787
+
714
788
  api_key = os.getenv("OPENAI_API_KEY")
715
789
  ai_port = int(os.getenv("AI_PORT", 5050))
716
790
  code_port = int(os.getenv("CODE_SERVER_PORT", 5002))
@@ -759,10 +833,17 @@ def start_ai_http(connector_port=5000):
759
833
  raise Exception("code-server failed to start")
760
834
 
761
835
  def shutdown():
836
+ global _process_ttl_timer
837
+ tm = _process_ttl_timer
838
+ _process_ttl_timer = None
839
+ if tm is not None:
840
+ tm.cancel()
762
841
  logger.info("Shutting down code-server...")
763
842
  if code_server_proc:
764
843
  code_server_proc.terminate()
765
844
 
845
+ ttl_shutdown_holder["fn"] = shutdown
846
+
766
847
  atexit.register(shutdown)
767
848
 
768
849
  def handle_signal(sig, frame):
@@ -784,9 +865,16 @@ def start_ai_http(connector_port=5000):
784
865
 
785
866
  @app.get("/session-info")
786
867
  def session_info():
787
- return {
868
+ out: Dict[str, Any] = {
788
869
  "workspace": workspace,
789
870
  "ai_port": int(os.getenv("AI_PORT", 5050)),
790
871
  "code_server_port": int(os.getenv("CODE_SERVER_PORT", 5002)),
791
- "api_base": f"http://localhost:{os.getenv('AI_PORT', 5050)}"
792
- }
872
+ "api_base": f"http://localhost:{os.getenv('AI_PORT', 5050)}",
873
+ }
874
+ if process_ttl_seconds is not None and process_ttl_deadline_unix is not None:
875
+ out["ttl_seconds"] = process_ttl_seconds
876
+ out["ttl_deadline_unix"] = process_ttl_deadline_unix
877
+ out["ttl_remaining_seconds"] = max(
878
+ 0.0, process_ttl_deadline_unix - time.time()
879
+ )
880
+ return out
@@ -88,10 +88,11 @@ def invoke(req: InvokeRequest):
88
88
  }
89
89
 
90
90
 
91
- def start_server():
91
+ def start_server(port: Optional[int] = None):
92
92
  import uvicorn
93
+ listen = int(os.getenv("PORT", 5000)) if port is None else int(port)
93
94
  uvicorn.run(
94
95
  "dc_sdk.src.server:app",
95
96
  host="0.0.0.0",
96
- port=int(os.getenv("PORT", 5000))
97
+ port=listen,
97
98
  )
File without changes
File without changes