Skip to content

Commit 3b0ec22

Browse files
committed
refactor: update CoderAPI methods for workspace management
- Renamed and modified the method to retrieve all templates to `_get_all_templates`, ensuring clarity in its purpose. - Added a new method `get_workspace_metadata` to fetch metadata for a specific workspace. - Implemented `is_workspace_dormant` and `set_workspace_dormancy` methods to manage workspace states effectively. - Refactored the `create_workspace` method to streamline workspace creation logic. - Updated the workspace router to print the response when starting a workspace, enhancing debugging capabilities.
1 parent 64d81c5 commit 3b0ec22

File tree

2 files changed

+99
-57
lines changed

2 files changed

+99
-57
lines changed

src/backend/coder.py

Lines changed: 98 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import os
21
import requests
32
from config import CODER_API_KEY, CODER_URL, CODER_TEMPLATE_ID, CODER_DEFAULT_ORGANIZATION, CODER_WORKSPACE_NAME
43

@@ -24,71 +23,24 @@ def __init__(self):
2423
'Coder-Session-Token': self.api_key
2524
}
2625

27-
def get_users(self):
26+
def _get_all_templates(self):
2827
"""
29-
Get all users from the Coder API
28+
Get all templates from the Coder API
3029
"""
31-
endpoint = f"{self.coder_url}/api/v2/users"
30+
endpoint = f"{self.coder_url}/api/v2/templates"
3231
response = requests.get(endpoint, headers=self.headers)
33-
response.raise_for_status() # Raise exception for 4XX/5XX responses
34-
return response.json()['users']
35-
36-
37-
def create_workspace(self, user_id, parameter_values=None):
38-
"""
39-
Create a new workspace for a user using a template
40-
41-
Args:
42-
user_id (str, optional): User ID to create the workspace for. Defaults to USER_ID from .env.
43-
name (str, optional): Name for the new workspace. Defaults to a generated name.
44-
template_id (str, optional): Template ID to use. Defaults to TEMPLATE_ID from .env.
45-
parameter_values (list, optional): List of template parameter values. Example:
46-
[{"name": "param_name", "value": "param_value"}]
47-
48-
Returns:
49-
dict: Created workspace data
50-
"""
51-
52-
template_id = self.template_id
53-
54-
if not template_id:
55-
raise ValueError("template_id must be provided or TEMPLATE_ID must be set in environment variables")
56-
57-
name = CODER_WORKSPACE_NAME
58-
59-
# Prepare the request data
60-
data = {
61-
"name": name,
62-
"template_id": template_id
63-
}
64-
65-
# Add rich_parameter_values if provided
66-
if parameter_values:
67-
data["rich_parameter_values"] = parameter_values
68-
69-
# Set headers for JSON content
70-
headers = self.headers.copy()
71-
headers['Content-Type'] = 'application/json'
72-
73-
# Create the workspace
74-
print("Creating workspace for user", user_id)
75-
endpoint = f"{self.coder_url}/api/v2/users/{user_id}/workspaces"
76-
response = requests.post(endpoint, headers=headers, json=data)
77-
7832
response.raise_for_status()
7933
return response.json()
34+
8035

81-
82-
83-
84-
def _get_all_templates(self):
36+
def get_users(self):
8537
"""
86-
Get all templates from the Coder API
38+
Get all users from the Coder API
8739
"""
88-
endpoint = f"{self.coder_url}/api/v2/templates"
40+
endpoint = f"{self.coder_url}/api/v2/users"
8941
response = requests.get(endpoint, headers=self.headers)
90-
response.raise_for_status()
91-
return response.json()
42+
response.raise_for_status() # Raise exception for 4XX/5XX responses
43+
return response.json()['users']
9244

9345
def get_user_by_email(self, email):
9446
"""
@@ -186,6 +138,14 @@ def ensure_user_exists(self, user_info):
186138
new_user = self.create_user(username, email, name)
187139
return new_user, True
188140

141+
142+
def get_workspace_metadata(self, workspace_id):
143+
"""
144+
Get the metadata of a workspace
145+
"""
146+
endpoint = f"{self.coder_url}/api/v2/workspaces/{workspace_id}"
147+
response = requests.get(endpoint, headers=self.headers)
148+
return response.json()
189149

190150
def get_workspace_status_for_user(self, username):
191151
"""
@@ -227,6 +187,14 @@ def start_workspace(self, workspace_id):
227187
Returns:
228188
dict: Response from the API
229189
"""
190+
191+
# First check if the workspace is dormant
192+
if self.is_workspace_dormant(workspace_id):
193+
print("Workspace is dormant, setting to not dormant")
194+
self.set_workspace_dormancy(workspace_id, False)
195+
else:
196+
print("Workspace is not dormant")
197+
230198
# First get the workspace to get its template version
231199
workspace_endpoint = f"{self.coder_url}/api/v2/workspaces/{workspace_id}"
232200
workspace_response = requests.get(workspace_endpoint, headers=self.headers)
@@ -279,3 +247,76 @@ def stop_workspace(self, workspace_id):
279247
response = requests.post(endpoint, headers=headers, json=data)
280248
response.raise_for_status()
281249
return response.json()
250+
251+
def create_workspace(self, user_id, parameter_values=None):
252+
"""
253+
Create a new workspace for a user using a template
254+
255+
Args:
256+
user_id (str, optional): User ID to create the workspace for. Defaults to USER_ID from .env.
257+
name (str, optional): Name for the new workspace. Defaults to a generated name.
258+
template_id (str, optional): Template ID to use. Defaults to TEMPLATE_ID from .env.
259+
parameter_values (list, optional): List of template parameter values. Example:
260+
[{"name": "param_name", "value": "param_value"}]
261+
262+
Returns:
263+
dict: Created workspace data
264+
"""
265+
266+
template_id = self.template_id
267+
268+
if not template_id:
269+
raise ValueError("template_id must be provided or TEMPLATE_ID must be set in environment variables")
270+
271+
name = CODER_WORKSPACE_NAME
272+
273+
# Prepare the request data
274+
data = {
275+
"name": name,
276+
"template_id": template_id
277+
}
278+
279+
# Add rich_parameter_values if provided
280+
if parameter_values:
281+
data["rich_parameter_values"] = parameter_values
282+
283+
# Set headers for JSON content
284+
headers = self.headers.copy()
285+
headers['Content-Type'] = 'application/json'
286+
287+
# Create the workspace
288+
print("Creating workspace for user", user_id)
289+
endpoint = f"{self.coder_url}/api/v2/users/{user_id}/workspaces"
290+
response = requests.post(endpoint, headers=headers, json=data)
291+
292+
response.raise_for_status()
293+
return response.json()
294+
295+
def is_workspace_dormant(self, workspace_id) -> bool:
296+
"""
297+
Check if a workspace is dormant
298+
"""
299+
state = self.get_workspace_metadata(workspace_id)
300+
if state["dormant_at"]:
301+
return True
302+
return False
303+
304+
def set_workspace_dormancy(self, workspace_id, dormant: bool):
305+
"""
306+
Set a workspace to be dormant or not
307+
"""
308+
endpoint = f"{self.coder_url}/api/v2/workspaces/{workspace_id}/dormant"
309+
data = {"dormant": dormant}
310+
headers = self.headers.copy()
311+
headers['Content-Type'] = 'application/json'
312+
response = requests.put(endpoint, headers=headers, json=data)
313+
response.raise_for_status()
314+
return response.json()
315+
316+
317+
if __name__ == "__main__":
318+
coder = CoderAPI()
319+
workspace_id = coder.get_workspace_status_for_user("alex")["id"]
320+
coder.set_workspace_dormancy(workspace_id, True)
321+
state = coder.get_workspace_status_for_user("alex")
322+
print(state)

src/backend/routers/workspace_router.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ async def start_workspace(
6969

7070
try:
7171
response = coder_api.start_workspace(workspace.id)
72+
print(response)
7273
return JSONResponse(content=response)
7374
except Exception as e:
7475
print(f"Error starting workspace: {str(e)}")

0 commit comments

Comments
 (0)