dc-python-sdk 1.5.25__tar.gz → 1.5.27__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.
- {dc_python_sdk-1.5.25/src/dc_python_sdk.egg-info → dc_python_sdk-1.5.27}/PKG-INFO +1 -1
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/pyproject.toml +1 -1
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/setup.cfg +1 -1
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27/src/dc_python_sdk.egg-info}/PKG-INFO +1 -1
- dc_python_sdk-1.5.25/src/dc_sdk/src/ai_http.py → dc_python_sdk-1.5.27/src/dc_sdk/src/ai.py +2 -218
- dc_python_sdk-1.5.27/src/dc_sdk/src/ai_http.py +662 -0
- dc_python_sdk-1.5.25/src/dc_sdk/src/ai.py +0 -933
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/LICENSE +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/README.md +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_python_sdk.egg-info/SOURCES.txt +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_python_sdk.egg-info/dependency_links.txt +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_python_sdk.egg-info/entry_points.txt +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_python_sdk.egg-info/requires.txt +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_python_sdk.egg-info/top_level.txt +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/__init__.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/app.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/cli.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/errors.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/handler.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/__init__.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/mapping.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/models/__init__.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/models/enums.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/models/errors.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/models/log_templates.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/models/pipeline_details.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/pipeline.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/server.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/__init__.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/api.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/aws.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/environment.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/loader.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/logger.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/src/services/session.py +0 -0
- {dc_python_sdk-1.5.25 → dc_python_sdk-1.5.27}/src/dc_sdk/types.py +0 -0
|
@@ -74,92 +74,6 @@ class RunRequest(BaseModel):
|
|
|
74
74
|
# When objects_dynamic is true and get_objects returns []: required — used to probe get_fields/get_data.
|
|
75
75
|
test_object_ids: Optional[List[str]] = None
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
def _parse_process_ttl_seconds() -> float:
|
|
79
|
-
"""
|
|
80
|
-
Wall-clock lifetime for the whole ai-http process from start_ai_http() entry.
|
|
81
|
-
Env DC_SDK_TTL_SECONDS: positive seconds; unset or empty → 600 (10m); 0 → disabled.
|
|
82
|
-
"""
|
|
83
|
-
raw = os.environ.get("DC_SDK_TTL_SECONDS")
|
|
84
|
-
if raw is None:
|
|
85
|
-
return _DEFAULT_PROCESS_TTL_SECONDS
|
|
86
|
-
raw = raw.strip()
|
|
87
|
-
if raw == "":
|
|
88
|
-
return _DEFAULT_PROCESS_TTL_SECONDS
|
|
89
|
-
try:
|
|
90
|
-
v = float(raw)
|
|
91
|
-
except ValueError:
|
|
92
|
-
logger.warning(
|
|
93
|
-
"Invalid DC_SDK_TTL_SECONDS=%r; using default %s",
|
|
94
|
-
raw,
|
|
95
|
-
_DEFAULT_PROCESS_TTL_SECONDS,
|
|
96
|
-
)
|
|
97
|
-
return _DEFAULT_PROCESS_TTL_SECONDS
|
|
98
|
-
if v <= 0:
|
|
99
|
-
return 0.0
|
|
100
|
-
return v
|
|
101
|
-
|
|
102
|
-
def _wait_connector_healthy() -> None:
|
|
103
|
-
for _ in range(50):
|
|
104
|
-
try:
|
|
105
|
-
res = requests.get(f"http://localhost:{CONNECTOR_PORT}/health", timeout=2)
|
|
106
|
-
if res.status_code == 200:
|
|
107
|
-
logger.info("Connector ready on port %s", CONNECTOR_PORT)
|
|
108
|
-
return
|
|
109
|
-
except Exception:
|
|
110
|
-
logger.debug("Health check not ready yet on port %s", CONNECTOR_PORT)
|
|
111
|
-
time.sleep(0.1)
|
|
112
|
-
raise RuntimeError(
|
|
113
|
-
f"Connector failed to become healthy on port {CONNECTOR_PORT} within timeout"
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def _start_connector_subprocess_unlocked() -> None:
|
|
118
|
-
global _connector_proc, workspace
|
|
119
|
-
env = os.environ.copy()
|
|
120
|
-
env["CONNECTOR_HTTP_RELOAD"] = "1"
|
|
121
|
-
proc = subprocess.Popen(
|
|
122
|
-
["dc-sdk", "http"],
|
|
123
|
-
cwd=workspace,
|
|
124
|
-
env=env,
|
|
125
|
-
stdout=subprocess.DEVNULL,
|
|
126
|
-
stderr=subprocess.DEVNULL,
|
|
127
|
-
)
|
|
128
|
-
try:
|
|
129
|
-
_wait_connector_healthy()
|
|
130
|
-
except Exception:
|
|
131
|
-
proc.terminate()
|
|
132
|
-
try:
|
|
133
|
-
proc.wait(timeout=5)
|
|
134
|
-
except Exception:
|
|
135
|
-
pass
|
|
136
|
-
raise
|
|
137
|
-
_connector_proc = proc
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def _stop_connector_subprocess_unlocked() -> None:
|
|
141
|
-
global _connector_proc
|
|
142
|
-
proc = _connector_proc
|
|
143
|
-
_connector_proc = None
|
|
144
|
-
if proc is None:
|
|
145
|
-
return
|
|
146
|
-
try:
|
|
147
|
-
proc.terminate()
|
|
148
|
-
proc.wait(timeout=15)
|
|
149
|
-
logger.debug("Connector subprocess stopped")
|
|
150
|
-
except Exception:
|
|
151
|
-
logger.debug("Error stopping connector subprocess", exc_info=True)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def start_connector_http_server() -> None:
|
|
155
|
-
"""Start the connector HTTP child once; restart if the previous child exited."""
|
|
156
|
-
with _connector_lock:
|
|
157
|
-
if _connector_proc is not None and _connector_proc.poll() is None:
|
|
158
|
-
return
|
|
159
|
-
_stop_connector_subprocess_unlocked()
|
|
160
|
-
_start_connector_subprocess_unlocked()
|
|
161
|
-
|
|
162
|
-
|
|
163
77
|
def invoke(method, session_id=None, credentials=None, params=None):
|
|
164
78
|
payload = {
|
|
165
79
|
"method": method,
|
|
@@ -245,7 +159,6 @@ def run_test(
|
|
|
245
159
|
test_object_ids: Optional[List[str]] = None,
|
|
246
160
|
):
|
|
247
161
|
requested_ids = [_canon_object_id(x) for x in (test_object_ids or []) if _canon_object_id(x)]
|
|
248
|
-
print(requested_ids)
|
|
249
162
|
|
|
250
163
|
session_id = None
|
|
251
164
|
|
|
@@ -721,121 +634,11 @@ def feedback(req: FeedbackRequest):
|
|
|
721
634
|
"ai_messages": ai_messages,
|
|
722
635
|
}
|
|
723
636
|
|
|
724
|
-
def
|
|
725
|
-
global workspace
|
|
726
|
-
repo = os.getenv("GH_REPO_URL")
|
|
727
|
-
token = os.getenv("GH_TOKEN")
|
|
728
|
-
branch = os.getenv("GH_BRANCH", "development")
|
|
729
|
-
|
|
730
|
-
if not repo:
|
|
731
|
-
return
|
|
732
|
-
|
|
733
|
-
if not os.path.exists(f"{workspace}/.git"):
|
|
734
|
-
clone_url = repo.replace("https://", f"https://{token}@")
|
|
735
|
-
subprocess.run(["git", "clone", clone_url, workspace], check=True)
|
|
736
|
-
else:
|
|
737
|
-
subprocess.run(["git", "-C", workspace, "fetch"], check=True)
|
|
738
|
-
|
|
739
|
-
subprocess.run(["git", "-C", workspace, "checkout", branch], check=True)
|
|
740
|
-
subprocess.run(["git", "-C", workspace, "pull"], check=True)
|
|
741
|
-
|
|
742
|
-
def run_code_server():
|
|
743
|
-
logger.info("code-server path: %s", shutil.which("code-server"))
|
|
744
|
-
|
|
745
|
-
# ✅ Ensure config dir exists
|
|
746
|
-
os.makedirs("/root/.config/code-server", exist_ok=True)
|
|
747
|
-
|
|
748
|
-
# ✅ Write code-server config
|
|
749
|
-
with open("/root/.config/code-server/config.yaml", "w") as f:
|
|
750
|
-
f.write(
|
|
751
|
-
f"bind-addr: 0.0.0.0:{CODE_SERVER_PORT}\n"
|
|
752
|
-
"auth: none\n"
|
|
753
|
-
)
|
|
754
|
-
|
|
755
|
-
with open("/root/.config/code-server/config.yaml", "r") as f:
|
|
756
|
-
logger.info("code-server config:\n%s", f.read())
|
|
757
|
-
|
|
758
|
-
# ✅ Ensure workspace + vscode dir exists
|
|
759
|
-
os.makedirs(workspace, exist_ok=True)
|
|
760
|
-
os.makedirs(f"{workspace}/.vscode", exist_ok=True)
|
|
761
|
-
|
|
762
|
-
# ✅ Write VS Code settings
|
|
763
|
-
with open(f"{workspace}/.vscode/settings.json", "w") as f:
|
|
764
|
-
f.write("""{
|
|
765
|
-
"chat.disableAIFeatures": true,
|
|
766
|
-
"workbench.colorTheme": "Default Dark+",
|
|
767
|
-
"outline.showFiles": false,
|
|
768
|
-
"timeline.enabled": false,
|
|
769
|
-
"python.defaultInterpreterPath": "/usr/local/bin/python"
|
|
770
|
-
}""")
|
|
771
|
-
|
|
772
|
-
# ✅ Start code-server (NO extension install here)
|
|
773
|
-
code_server_proc = subprocess.Popen([
|
|
774
|
-
"code-server",
|
|
775
|
-
workspace,
|
|
776
|
-
"--config", "/root/.config/code-server/config.yaml"
|
|
777
|
-
])
|
|
778
|
-
|
|
779
|
-
time.sleep(3)
|
|
780
|
-
|
|
781
|
-
if code_server_proc.poll() is not None:
|
|
782
|
-
raise Exception("code-server failed to start")
|
|
783
|
-
|
|
784
|
-
return code_server_proc
|
|
785
|
-
|
|
786
|
-
def start_ai_http(start_code_server=True):
|
|
637
|
+
def start_ai_http():
|
|
787
638
|
global client
|
|
788
|
-
global workspace
|
|
789
|
-
global process_ttl_seconds
|
|
790
|
-
global process_ttl_deadline_unix
|
|
791
|
-
global _process_ttl_timer
|
|
792
|
-
|
|
793
|
-
process_ttl_seconds = None
|
|
794
|
-
process_ttl_deadline_unix = None
|
|
795
|
-
_process_ttl_timer = None
|
|
796
|
-
|
|
797
|
-
ttl_sec = _parse_process_ttl_seconds()
|
|
798
|
-
ttl_shutdown_holder: Dict[str, Any] = {"fn": None}
|
|
799
|
-
|
|
800
|
-
if ttl_sec > 0:
|
|
801
|
-
process_ttl_seconds = ttl_sec
|
|
802
|
-
process_ttl_deadline_unix = time.time() + ttl_sec
|
|
803
|
-
|
|
804
|
-
def on_process_ttl():
|
|
805
|
-
logger.warning(
|
|
806
|
-
"DC_SDK_TTL_SECONDS (%s s) elapsed; stopping and exiting process",
|
|
807
|
-
ttl_sec,
|
|
808
|
-
)
|
|
809
|
-
fn = ttl_shutdown_holder.get("fn")
|
|
810
|
-
if callable(fn):
|
|
811
|
-
try:
|
|
812
|
-
fn()
|
|
813
|
-
except Exception:
|
|
814
|
-
logger.exception("Process TTL shutdown hook failed")
|
|
815
|
-
os._exit(0)
|
|
816
|
-
|
|
817
|
-
_process_ttl_timer = threading.Timer(ttl_sec, on_process_ttl)
|
|
818
|
-
_process_ttl_timer.daemon = True
|
|
819
|
-
_process_ttl_timer.start()
|
|
820
|
-
logger.info(
|
|
821
|
-
"Process TTL active: exit after %s s wall clock (DC_SDK_TTL_SECONDS)",
|
|
822
|
-
ttl_sec,
|
|
823
|
-
)
|
|
824
|
-
else:
|
|
825
|
-
logger.info(
|
|
826
|
-
"Process TTL disabled (DC_SDK_TTL_SECONDS=%r)",
|
|
827
|
-
os.environ.get("DC_SDK_TTL_SECONDS"),
|
|
828
|
-
)
|
|
829
639
|
|
|
830
640
|
api_key = os.getenv("OPENAI_API_KEY")
|
|
831
641
|
|
|
832
|
-
clone_repo()
|
|
833
|
-
start_connector_http_server()
|
|
834
|
-
|
|
835
|
-
code_server_proc = None
|
|
836
|
-
if start_code_server:
|
|
837
|
-
code_server_proc = run_code_server()
|
|
838
|
-
|
|
839
642
|
def shutdown():
|
|
840
643
|
global _process_ttl_timer
|
|
841
644
|
tm = _process_ttl_timer
|
|
@@ -843,8 +646,6 @@ def start_ai_http(start_code_server=True):
|
|
|
843
646
|
if tm is not None:
|
|
844
647
|
tm.cancel()
|
|
845
648
|
logger.info("Shutting down code-server...")
|
|
846
|
-
if code_server_proc is not None:
|
|
847
|
-
code_server_proc.terminate()
|
|
848
649
|
logger.info("Shutting down connector HTTP...")
|
|
849
650
|
with _connector_lock:
|
|
850
651
|
_stop_connector_subprocess_unlocked()
|
|
@@ -868,21 +669,4 @@ def start_ai_http(start_code_server=True):
|
|
|
868
669
|
logger.info("Starting AI HTTP controller on 0.0.0.0:%s", AI_PORT)
|
|
869
670
|
|
|
870
671
|
import uvicorn
|
|
871
|
-
uvicorn.run(app, host="0.0.0.0", port=AI_PORT)
|
|
872
|
-
|
|
873
|
-
@app.get("/session-info")
|
|
874
|
-
def session_info():
|
|
875
|
-
out: Dict[str, Any] = {
|
|
876
|
-
"workspace": workspace,
|
|
877
|
-
"connector_port": CONNECTOR_PORT,
|
|
878
|
-
"ai_port": AI_PORT,
|
|
879
|
-
"code_server_port": CODE_SERVER_PORT,
|
|
880
|
-
"api_base": f"http://localhost:{AI_PORT}",
|
|
881
|
-
}
|
|
882
|
-
if process_ttl_seconds is not None and process_ttl_deadline_unix is not None:
|
|
883
|
-
out["ttl_seconds"] = process_ttl_seconds
|
|
884
|
-
out["ttl_deadline_unix"] = process_ttl_deadline_unix
|
|
885
|
-
out["ttl_remaining_seconds"] = max(
|
|
886
|
-
0.0, process_ttl_deadline_unix - time.time()
|
|
887
|
-
)
|
|
888
|
-
return out
|
|
672
|
+
uvicorn.run(app, host="0.0.0.0", port=AI_PORT)
|