xenfra-sdk 0.1.3__py3-none-any.whl → 0.1.4__py3-none-any.whl

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.
@@ -1,4 +1,6 @@
1
+ import json
1
2
  import logging
3
+ from typing import Iterator
2
4
 
3
5
  # Import Deployment model when it's defined in models.py
4
6
  # from ..models import Deployment
@@ -10,7 +12,7 @@ logger = logging.getLogger(__name__)
10
12
 
11
13
 
12
14
  class DeploymentsManager(BaseManager):
13
- def create(self, project_name: str, git_repo: str, branch: str, framework: str) -> dict:
15
+ def create(self, project_name: str, git_repo: str, branch: str, framework: str, region: str = None, size_slug: str = None) -> dict:
14
16
  """Creates a new deployment."""
15
17
  try:
16
18
  payload = {
@@ -19,6 +21,11 @@ class DeploymentsManager(BaseManager):
19
21
  "branch": branch,
20
22
  "framework": framework,
21
23
  }
24
+ if region:
25
+ payload["region"] = region
26
+ if size_slug:
27
+ payload["size_slug"] = size_slug
28
+
22
29
  response = self._client._request("POST", "/deployments", json=payload)
23
30
  # Safe JSON parsing
24
31
  return safe_json_parse(response)
@@ -87,3 +94,92 @@ class DeploymentsManager(BaseManager):
87
94
  raise # Re-raise API errors
88
95
  except Exception as e:
89
96
  raise XenfraError(f"Failed to get logs for deployment {deployment_id}: {e}")
97
+
98
+ def create_stream(self, project_name: str, git_repo: str, branch: str, framework: str, region: str = None, size_slug: str = None) -> Iterator[dict]:
99
+ """
100
+ Creates a new deployment with real-time SSE log streaming.
101
+
102
+ Yields SSE events as dictionaries with 'event' and 'data' keys.
103
+
104
+ Args:
105
+ project_name: Name of the project
106
+ git_repo: Git repository URL
107
+ branch: Git branch to deploy
108
+ framework: Framework type (fastapi, flask, django)
109
+ region: DigitalOcean region (optional)
110
+ size_slug: DigitalOcean droplet size (optional)
111
+
112
+ Yields:
113
+ dict: SSE events with 'event' and 'data' fields
114
+
115
+ Example:
116
+ for event in client.deployments.create_stream(...):
117
+ if event['event'] == 'log':
118
+ print(event['data'])
119
+ elif event['event'] == 'deployment_complete':
120
+ print("Done!")
121
+ """
122
+ payload = {
123
+ "project_name": project_name,
124
+ "git_repo": git_repo,
125
+ "branch": branch,
126
+ "framework": framework,
127
+ }
128
+ if region:
129
+ payload["region"] = region
130
+ if size_slug:
131
+ payload["size_slug"] = size_slug
132
+
133
+ try:
134
+ # Use httpx to stream the SSE response
135
+ import httpx
136
+
137
+ headers = {
138
+ "Authorization": f"Bearer {self._client.token}",
139
+ "Accept": "text/event-stream",
140
+ "Content-Type": "application/json",
141
+ }
142
+
143
+ url = f"{self._client.api_url}/deployments/stream"
144
+
145
+ with httpx.stream(
146
+ "POST",
147
+ url,
148
+ json=payload,
149
+ headers=headers,
150
+ timeout=600.0, # 10 minute timeout for deployments
151
+ ) as response:
152
+ if response.status_code not in [200, 201, 202]:
153
+ error_text = response.text
154
+ raise XenfraAPIError(
155
+ status_code=response.status_code,
156
+ detail=f"Deployment failed: {error_text}"
157
+ )
158
+
159
+ # Parse SSE events
160
+ for line in response.iter_lines():
161
+ line = line.strip()
162
+ if not line:
163
+ continue
164
+
165
+ # SSE format: "event: eventname" or "data: eventdata"
166
+ if line.startswith("event:"):
167
+ current_event = line[6:].strip()
168
+ elif line.startswith("data:"):
169
+ data = line[5:].strip()
170
+ try:
171
+ # Try to parse as JSON
172
+ data_parsed = json.loads(data)
173
+ yield {"event": current_event if 'current_event' in locals() else "message", "data": data_parsed}
174
+ except json.JSONDecodeError:
175
+ # If not JSON, yield as plain text
176
+ yield {"event": current_event if 'current_event' in locals() else "message", "data": data}
177
+
178
+ # Reset current_event
179
+ if 'current_event' in locals():
180
+ del current_event
181
+
182
+ except httpx.HTTPError as e:
183
+ raise XenfraError(f"HTTP error during streaming deployment: {e}")
184
+ except Exception as e:
185
+ raise XenfraError(f"Failed to create streaming deployment: {e}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: xenfra-sdk
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Xenfra SDK: Core engine and utilities for the Xenfra platform.
5
5
  Author: xenfra-cloud
6
6
  Author-email: xenfra-cloud <xenfracloud@gmail.com>
@@ -18,7 +18,7 @@ xenfra_sdk/privacy.py,sha256=ksGf5L9PVtRP-xZS3T-Gj7MKfexTqIMgbFLoYkIESOE,5662
18
18
  xenfra_sdk/recipes.py,sha256=g_UKQIcdSokYh7zn186mzDTr08P034-KZ1iiDNELyP4,877
19
19
  xenfra_sdk/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  xenfra_sdk/resources/base.py,sha256=C6BuZfhR-oU5ecHSfkGG6ZLU6MHGXUyCWoy1F-yTIf8,84
21
- xenfra_sdk/resources/deployments.py,sha256=JwlsCUKQUyvUF0lYUv6A3n1EkglXoYsICNVssx8E6ec,3428
21
+ xenfra_sdk/resources/deployments.py,sha256=GmgX3F-mr3mDR_vJzidqDmkOhJKiFA9adQmSiBrSdzM,7272
22
22
  xenfra_sdk/resources/intelligence.py,sha256=Y11K6_iXfm2QKTbH1vUmt45MifLoVtZtlHEkqbzmTzs,3418
23
23
  xenfra_sdk/resources/projects.py,sha256=EsCVXmqkhWl_Guz_8WDQDi3kAm1Wyg1rjXcyAigPD6E,3712
24
24
  xenfra_sdk/security.py,sha256=Px887RRb1BUDXaPUrxmQITJ1mHyOyupCJqEDZ78F7Tk,1240
@@ -26,6 +26,6 @@ xenfra_sdk/templates/Dockerfile.j2,sha256=GXc0JiaF-HsxTQS15Gs2fcvsIhA1EHnwapdFVi
26
26
  xenfra_sdk/templates/cloud-init.sh.j2,sha256=NKIwtL9OgnlK2NnYRZI3gWC9aYl6wNPsS6r14g8eHQQ,2290
27
27
  xenfra_sdk/templates/docker-compose.yml.j2,sha256=qMHiatuZlxiYZ1pE_g2ag1M798MvQbeq0cVTVK07jkM,893
28
28
  xenfra_sdk/utils.py,sha256=d8eCjjV32QwqoJa759CEcETnnsjG5qVKDLQ84yYtlus,3898
29
- xenfra_sdk-0.1.3.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
30
- xenfra_sdk-0.1.3.dist-info/METADATA,sha256=0uvLdk5kr1Zts-HDNDqOTPNHJ0R2DkRFjG0Q64l4T0Q,3980
31
- xenfra_sdk-0.1.3.dist-info/RECORD,,
29
+ xenfra_sdk-0.1.4.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
30
+ xenfra_sdk-0.1.4.dist-info/METADATA,sha256=H8i-Gv6K6KGaHbIkdBAqDtS8DXrVl8rD2HFa4IX4vPM,3980
31
+ xenfra_sdk-0.1.4.dist-info/RECORD,,