Skip to content

Commit b3963a0

Browse files
authored
refactor: update CoderAPI methods for workspace management (#77)
* 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. * fix: improve workspace dormancy messages and clean up router logging - Updated the print statement in CoderAPI to clarify that the workspace was previously dormant before changing its state. - Removed the print statement in the workspace router when starting a workspace to reduce console clutter.
1 parent 64d81c5 commit b3963a0

File tree

1 file changed

+97
-57
lines changed

1 file changed

+97
-57
lines changed

src/backend/coder.py

Lines changed: 97 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,12 @@ 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 was dormant, setting to not dormant")
194+
self.set_workspace_dormancy(workspace_id, False)
195+
230196
# First get the workspace to get its template version
231197
workspace_endpoint = f"{self.coder_url}/api/v2/workspaces/{workspace_id}"
232198
workspace_response = requests.get(workspace_endpoint, headers=self.headers)
@@ -279,3 +245,77 @@ def stop_workspace(self, workspace_id):
279245
response = requests.post(endpoint, headers=headers, json=data)
280246
response.raise_for_status()
281247
return response.json()
248+
249+
def create_workspace(self, user_id, parameter_values=None):
250+
"""
251+
Create a new workspace for a user using a template
252+
253+
Args:
254+
user_id (str, optional): User ID to create the workspace for. Defaults to USER_ID from .env.
255+
name (str, optional): Name for the new workspace. Defaults to a generated name.
256+
template_id (str, optional): Template ID to use. Defaults to TEMPLATE_ID from .env.
257+
parameter_values (list, optional): List of template parameter values. Example:
258+
[{"name": "param_name", "value": "param_value"}]
259+
260+
Returns:
261+
dict: Created workspace data
262+
"""
263+
264+
template_id = self.template_id
265+
266+
if not template_id:
267+
raise ValueError("template_id must be provided or TEMPLATE_ID must be set in environment variables")
268+
269+
name = CODER_WORKSPACE_NAME
270+
271+
# Prepare the request data
272+
data = {
273+
"name": name,
274+
"template_id": template_id
275+
}
276+
277+
# Add rich_parameter_values if provided
278+
if parameter_values:
279+
data["rich_parameter_values"] = parameter_values
280+
281+
# Set headers for JSON content
282+
headers = self.headers.copy()
283+
headers['Content-Type'] = 'application/json'
284+
285+
# Create the workspace
286+
print("Creating workspace for user", user_id)
287+
endpoint = f"{self.coder_url}/api/v2/users/{user_id}/workspaces"
288+
response = requests.post(endpoint, headers=headers, json=data)
289+
290+
response.raise_for_status()
291+
return response.json()
292+
293+
def is_workspace_dormant(self, workspace_id) -> bool:
294+
"""
295+
Check if a workspace is dormant
296+
"""
297+
state = self.get_workspace_metadata(workspace_id)
298+
if state["dormant_at"]:
299+
return True
300+
return False
301+
302+
def set_workspace_dormancy(self, workspace_id, dormant: bool):
303+
"""
304+
Set a workspace to be dormant or not
305+
"""
306+
endpoint = f"{self.coder_url}/api/v2/workspaces/{workspace_id}/dormant"
307+
308+
data = {"dormant": dormant}
309+
headers = self.headers.copy()
310+
headers['Content-Type'] = 'application/json'
311+
response = requests.put(endpoint, headers=headers, json=data)
312+
response.raise_for_status()
313+
return response.json()
314+
315+
316+
if __name__ == "__main__":
317+
coder = CoderAPI()
318+
workspace_id = coder.get_workspace_status_for_user("alex")["id"]
319+
coder.set_workspace_dormancy(workspace_id, True)
320+
state = coder.get_workspace_status_for_user("alex")
321+
print(state)

0 commit comments

Comments
 (0)