Skip to content

Commit d62b8d1

Browse files
committed
add execute command example
1 parent 4de6561 commit d62b8d1

File tree

6 files changed

+388
-3
lines changed

6 files changed

+388
-3
lines changed

.devcontainer/Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
ARG VARIANT="3.9"
2-
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
1+
FROM mcr.microsoft.com/devcontainers/python:3.12
32

43
USER vscode
54

65
RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.35.0" RYE_INSTALL_OPTION="--yes" bash
76
ENV PATH=/home/vscode/.rye/shims:$PATH
87

9-
RUN echo "[[ -d .venv ]] && source .venv/bin/activate" >> /home/vscode/.bashrc
8+
RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc

examples/execute_command.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python
2+
3+
from utils.task import run_command, create_command, delete_command, update_command
4+
from utils.context import get_context_url, get_authenticated_user
5+
from utils.environment import create_environment, get_environment_class, get_environment_class_id
6+
7+
from gitpod import Gitpod
8+
9+
10+
def main() -> None:
11+
"""
12+
Main function to create an environment, start a task, and stream its logs.
13+
"""
14+
# Initialize Gitpod client
15+
client: Gitpod = Gitpod()
16+
17+
# Get context URL and authenticated user
18+
context_url: str = get_context_url()
19+
user = get_authenticated_user(client)
20+
21+
# Get environment class ID and details
22+
environment_class_id: str = get_environment_class_id(client, user)
23+
if not environment_class_id:
24+
raise ValueError("no environment class found, please set the ENVIRONMENT_CLASS_ID environment variable")
25+
environment_class = get_environment_class(client, environment_class_id)
26+
if not environment_class:
27+
raise ValueError("no environment class found, please set the ENVIRONMENT_CLASS_ID environment variable")
28+
29+
print(f"Using repository: {context_url}")
30+
print(f"Using environment class: {environment_class.display_name} ({environment_class.description})")
31+
32+
# Create environment
33+
environment_id: str = create_environment(client, context_url, environment_class)
34+
print(f"\nCreated environment: {environment_id}")
35+
36+
try:
37+
# Define command
38+
reference = "greeting"
39+
name = "Greeting"
40+
description = "Prints a greeting to the console."
41+
command = "echo 'Hello, World!'"
42+
task_id = create_command(client, environment_id, reference, name, description, command)
43+
try:
44+
# Run command with first greeting
45+
run_command(client, environment_id, task_id)
46+
47+
# Update command with second greeting
48+
command = "echo 'Howdy, Partner!'"
49+
update_command(client, task_id, command)
50+
51+
# Run command with second greeting
52+
run_command(client, environment_id, task_id)
53+
finally:
54+
# Clean up command
55+
delete_command(client, task_id)
56+
finally:
57+
# Clean up environment
58+
client.environments.delete(environment_id=environment_id)
59+
print(f"\nDeleted environment: {environment_id}")
60+
61+
62+
if __name__ == "__main__":
63+
main()

examples/utils/context.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
3+
from gitpod import Gitpod
4+
from gitpod.types.user_get_authenticated_user_response import User
5+
6+
7+
def get_context_url() -> str:
8+
"""
9+
Retrieve the context URL from the environment variable or use a default value.
10+
11+
Returns:
12+
str: The context URL.
13+
"""
14+
return os.environ.get("CONTEXT_URL", "https://github.com/gitpod-io/empty")
15+
16+
17+
def get_authenticated_user(client: Gitpod) -> User:
18+
"""
19+
Get the authenticated user using the Gitpod client.
20+
21+
Args:
22+
client (Gitpod): The Gitpod client instance.
23+
24+
Returns:
25+
User: The authenticated user.
26+
"""
27+
return client.users.get_authenticated_user(body={}).user

examples/utils/environment.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import os
2+
from typing import Optional
3+
4+
from gitpod import Gitpod
5+
from gitpod.types.environment_create_params import SpecContentInitializerSpecContextURL
6+
from gitpod.types.environments.class_list_response import ClassListResponse
7+
from gitpod.types.user_get_authenticated_user_response import User
8+
9+
10+
def get_environment_class_id(client: Gitpod, user: User) -> Optional[str]:
11+
"""
12+
Get the most used environment class ID for the given user.
13+
14+
Args:
15+
client (Gitpod): The Gitpod client instance.
16+
user (User): The authenticated user.
17+
18+
Returns:
19+
Optional[str]: The environment class ID or None if not found.
20+
"""
21+
environment_class_id = os.environ.get("ENVIRONMENT_CLASS_ID")
22+
if environment_class_id:
23+
return environment_class_id
24+
25+
class_usage = {}
26+
page = client.environments.list(organization_id=user.organization_id)
27+
while page:
28+
for env in page.environments:
29+
env_class = env.spec.machine.class_
30+
if env_class not in class_usage:
31+
class_usage[env_class] = 0
32+
class_usage[env_class] += 1
33+
if page.pagination and page.pagination.next_token:
34+
page = client.environments.list(token=page.pagination.next_token, organization_id=user.organization_id)
35+
else:
36+
break
37+
38+
sorted_classes = sorted(class_usage.items(), key=lambda item: -item[1])
39+
return sorted_classes[0][0] if sorted_classes else None
40+
41+
42+
def get_environment_class(client: Gitpod, environment_class_id: str) -> Optional[ClassListResponse]:
43+
"""
44+
Get the environment class details for the given environment class ID.
45+
46+
Args:
47+
client (Gitpod): The Gitpod client instance.
48+
environment_class_id (str): The environment class ID.
49+
50+
Returns:
51+
Optional[ClassListResponse]: The environment class details or None if not found.
52+
"""
53+
page = client.environments.classes.list(filter={"enabled": True})
54+
while page:
55+
for cls in page.environment_classes:
56+
if cls.id == environment_class_id:
57+
return cls
58+
if page.pagination and page.pagination.next_token:
59+
page = client.environments.classes.list(token=page.pagination.next_token)
60+
else:
61+
break
62+
return None
63+
64+
65+
def create_environment(client: Gitpod, context_url: str, environment_class: ClassListResponse) -> str:
66+
"""
67+
Create a new environment with the given context URL and environment class.
68+
69+
Args:
70+
client (Gitpod): The Gitpod client instance.
71+
context_url (str): The context URL.
72+
environment_class (ClassListResponse): The environment class details.
73+
74+
Returns:
75+
str: The created environment ID.
76+
"""
77+
resp = client.environments.create(
78+
spec={
79+
"desired_phase": "ENVIRONMENT_PHASE_RUNNING",
80+
"content": {
81+
"initializer": {"specs": [SpecContentInitializerSpecContextURL(context_url={"url": context_url})]}
82+
},
83+
"machine": {"class": environment_class.id},
84+
}
85+
)
86+
return resp.environment.id
87+
88+
89+
def ensure_environment_healthy(client: Gitpod, environment_id: str) -> None:
90+
"""
91+
Ensure the environment is running or will be running and raise an error if it is in an unexpected phase.
92+
93+
Args:
94+
client (Gitpod): The Gitpod client instance.
95+
environment_id (str): The environment ID.
96+
97+
Raises:
98+
RuntimeError: If the environment is in an unexpected phase or has a failure message.
99+
"""
100+
environment = client.environments.retrieve(environment_id=environment_id).environment
101+
print(f"Environment status: {environment.status.phase}")
102+
if environment.status.phase in [
103+
"ENVIRONMENT_PHASE_STOPPING",
104+
"ENVIRONMENT_PHASE_STOPPED",
105+
"ENVIRONMENT_PHASE_DELETING",
106+
"ENVIRONMENT_PHASE_DELETED",
107+
]:
108+
raise RuntimeError(f"Environment {environment_id} is in an unexpected phase: {environment.status.phase}")
109+
elif environment.status.failure_message and len(environment.status.failure_message) > 0:
110+
raise RuntimeError(f"Environment {environment_id} failed: {'; '.join(environment.status.failure_message)}")

examples/utils/logs.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import httpx
2+
3+
4+
async def stream_logs(log_url: str, logs_access_token: str) -> None:
5+
"""
6+
Stream logs from the given log URL using the provided access token.
7+
8+
Args:
9+
log_url (str): The log URL.
10+
logs_access_token (str): The access token for the logs.
11+
"""
12+
async with httpx.AsyncClient() as client:
13+
async with client.stream("GET", log_url, headers={"Authorization": f"Bearer {logs_access_token}"}) as response:
14+
async for line in response.aiter_lines():
15+
if line:
16+
print(line)

0 commit comments

Comments
 (0)