xenfra-sdk 0.1.6__tar.gz → 0.1.8__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.
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/PKG-INFO +1 -1
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/pyproject.toml +1 -1
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/resources/deployments.py +38 -11
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/README.md +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/__init__.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/cli/__init__.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/cli/main.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/client.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/client_with_hooks.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/config.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/db/__init__.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/db/models.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/db/session.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/dependencies.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/dockerizer.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/engine.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/exceptions.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/mcp_client.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/models.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/patterns.json +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/privacy.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/recipes.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/resources/__init__.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/resources/base.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/resources/intelligence.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/resources/projects.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/security.py +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/templates/Dockerfile.j2 +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/templates/cloud-init.sh.j2 +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/templates/docker-compose.yml.j2 +0 -0
- {xenfra_sdk-0.1.6 → xenfra_sdk-0.1.8}/src/xenfra_sdk/utils.py +0 -0
|
@@ -133,6 +133,7 @@ class DeploymentsManager(BaseManager):
|
|
|
133
133
|
try:
|
|
134
134
|
# Use httpx to stream the SSE response
|
|
135
135
|
import httpx
|
|
136
|
+
import os
|
|
136
137
|
|
|
137
138
|
headers = {
|
|
138
139
|
"Authorization": f"Bearer {self._client._token}",
|
|
@@ -140,7 +141,19 @@ class DeploymentsManager(BaseManager):
|
|
|
140
141
|
"Content-Type": "application/json",
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
# Use streaming API URL if available (bypasses Cloudflare timeout)
|
|
145
|
+
# Otherwise fall back to regular API URL
|
|
146
|
+
streaming_api_url = os.getenv("XENFRA_STREAMING_API_URL")
|
|
147
|
+
if streaming_api_url:
|
|
148
|
+
base_url = streaming_api_url
|
|
149
|
+
elif self._client.api_url == "https://api.xenfra.tech":
|
|
150
|
+
# Production: use non-proxied streaming subdomain
|
|
151
|
+
base_url = "https://stream.xenfra.tech"
|
|
152
|
+
else:
|
|
153
|
+
# Local/dev: use regular API URL
|
|
154
|
+
base_url = self._client.api_url
|
|
155
|
+
|
|
156
|
+
url = f"{base_url}/deployments/stream"
|
|
144
157
|
|
|
145
158
|
with httpx.stream(
|
|
146
159
|
"POST",
|
|
@@ -151,14 +164,18 @@ class DeploymentsManager(BaseManager):
|
|
|
151
164
|
) as response:
|
|
152
165
|
# Check status before consuming stream
|
|
153
166
|
if response.status_code not in [200, 201, 202]:
|
|
154
|
-
# For
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
# For error responses from streaming endpoint, read via iteration
|
|
168
|
+
error_text = ""
|
|
169
|
+
try:
|
|
170
|
+
for chunk in response.iter_bytes():
|
|
171
|
+
error_text += chunk.decode('utf-8', errors='ignore')
|
|
172
|
+
if len(error_text) > 1000: # Limit error message size
|
|
173
|
+
break
|
|
174
|
+
if not error_text:
|
|
175
|
+
error_text = "Unknown error"
|
|
176
|
+
except Exception as e:
|
|
177
|
+
error_text = f"Could not read error response: {e}"
|
|
178
|
+
|
|
162
179
|
raise XenfraAPIError(
|
|
163
180
|
status_code=response.status_code,
|
|
164
181
|
detail=f"Deployment failed: {error_text}"
|
|
@@ -175,13 +192,23 @@ class DeploymentsManager(BaseManager):
|
|
|
175
192
|
current_event = line[6:].strip()
|
|
176
193
|
elif line.startswith("data:"):
|
|
177
194
|
data = line[5:].strip()
|
|
195
|
+
|
|
196
|
+
# Get event type
|
|
197
|
+
event_type = current_event if 'current_event' in locals() else "message"
|
|
198
|
+
|
|
199
|
+
# Skip keep-alive events (used to prevent proxy timeouts)
|
|
200
|
+
if event_type == "keep-alive":
|
|
201
|
+
if 'current_event' in locals():
|
|
202
|
+
del current_event
|
|
203
|
+
continue
|
|
204
|
+
|
|
178
205
|
try:
|
|
179
206
|
# Try to parse as JSON
|
|
180
207
|
data_parsed = json.loads(data)
|
|
181
|
-
yield {"event":
|
|
208
|
+
yield {"event": event_type, "data": data_parsed}
|
|
182
209
|
except json.JSONDecodeError:
|
|
183
210
|
# If not JSON, yield as plain text
|
|
184
|
-
yield {"event":
|
|
211
|
+
yield {"event": event_type, "data": data}
|
|
185
212
|
|
|
186
213
|
# Reset current_event
|
|
187
214
|
if 'current_event' in locals():
|
|
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
|
|
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
|