Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[![CI | Unit Tests](https://github.com/runpod/runpod-python/actions/workflows/CI-pytests.yml/badge.svg)](https://github.com/runpod/runpod-python/actions/workflows/CI-pytests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE)

[Documentation](https://docs.runpod.io) • [Examples](examples/apps) • [Discord](https://discord.gg/pJ3P2DbUUq)
[Documentation](https://docs.runpod.io) • [Examples](examples) • [Discord](https://discord.gg/pJ3P2DbUUq)

</div>

Expand Down
63 changes: 63 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Examples

## Before you start

```bash
pip install runpod
rp login
```

`rp login` stores your API key, and every example picks it up from there. If
`RUNPOD_API_KEY` is set in your environment, the examples use that key
instead.

## Which folder to start with

| Folder | What it shows | Needs |
|---|---|---|
| [`apps/`](apps) | Python functions that run on cloud GPUs and CPUs, started with `rp flash dev` | An account. Start here if you are new. |
| [`serverless/`](serverless) | Handlers for your own serverless worker image | Nothing. They run locally. |
| [`endpoints/`](endpoints) | Sending jobs to an existing serverless endpoint | An endpoint id |
| [`api/`](api) | Creating templates, endpoints, and registry credentials | An account |
| [`rest_wrapper.py`](rest_wrapper.py) | Pod lifecycle: create, stop, resume, terminate | An account. Creates a billable GPU pod. |

## Running the serverless handlers locally

```bash
cd examples/serverless
python simple_handler.py --test_input '{"input": {"name": "world"}}'
```

Or start a local API server and call it:

```bash
python simple_handler.py --rp_serve_api
curl -X POST http://localhost:8000/runsync \
-H "Content-Type: application/json" \
-d '{"input": {"name": "world"}}'
```

Run with no arguments, a handler looks for a `test_input.json` file in the
current directory.

## Getting an endpoint id for `endpoints/`

Each `endpoints/` example has a `YOUR_ENDPOINT_ID` placeholder. To use an
endpoint you already have, list them with `rp endpoint list`. To create one
for trying the examples, run [`api/create_endpoint.py`](api/create_endpoint.py),
which deploys `runpod/mock-worker` and prints the new id.

`endpoints/streaming.py` needs a worker that streams: a generator handler, or
`runpod/mock-worker` started with `--generator`.

## Cost and cleanup

- Endpoints with `workers_min=0` cost nothing while idle. Delete them with
`rp endpoint delete ENDPOINT_ID`.
- Templates stay on your account. Delete them from the Templates page in the
console.
- `rest_wrapper.py` terminates its pod at the end, including when a step
fails.
- `rp flash dev` deletes the endpoints it created when the session ends.
Network volumes created by `apps/` examples are not deleted; list them with
`rp volume list` and remove them with `rp volume delete`.
15 changes: 10 additions & 5 deletions examples/api/create_container_registry_auth.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
""" Example of creating a container registry auth with the Runpod API. """
"""Example of creating a container registry auth with the Runpod API.

Registry credentials let templates pull images from a private registry. The
credential stays on your account after the script exits; delete it with
`rp registry delete NAME`.
"""

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

try:
new_container_registry_auth = runpod.create_container_registry_auth(
name="test-container-registry-auth-name",
username="test-username",
password="test-password",
name="example-registry-auth",
username="YOUR_REGISTRY_USERNAME",
password="YOUR_REGISTRY_PASSWORD",
)

print(new_container_registry_auth)
Expand Down
23 changes: 19 additions & 4 deletions examples/api/create_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
""" Example of creating an endpoint with the Runpod API. """
"""Example of creating an endpoint with the Runpod API.

The endpoint scales to zero workers when idle, so it costs nothing until it
receives requests. It stays on your account after the script exits; delete it
with `rp endpoint delete ENDPOINT_ID`, then delete its template from the
Templates page in the console.
"""

import uuid

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

# Template and endpoint names must be unique on your account.
NAME = f"example-endpoint-{uuid.uuid4().hex[:8]}"

try:

# runpod/mock-worker echoes its input back, which is enough to try the
# examples in examples/endpoints/.
new_template = runpod.create_template(
name="test", image_name="runpod/base:0.4.4", is_serverless=True
name=NAME, image_name="runpod/mock-worker:latest", is_serverless=True
)

print(new_template)

new_endpoint = runpod.create_endpoint(
name="test",
name=NAME,
template_id=new_template["id"],
gpu_ids="AMPERE_16",
workers_min=0,
Expand All @@ -23,6 +36,8 @@
)

print(new_endpoint)
print(f"Endpoint id: {new_endpoint['id']}")
print(f"Delete it with: rp endpoint delete {new_endpoint['id']}")

except runpod.error.QueryError as err:
print(err)
Expand Down
17 changes: 14 additions & 3 deletions examples/api/create_template.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
""" Example of creating a template with the Runpod API. """
"""Example of creating a template with the Runpod API.

The template stays on your account after the script exits. Delete it from
the Templates page in the console when you no longer need it.
"""

import uuid

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

# Template names must be unique on your account.
TEMPLATE_NAME = f"example-template-{uuid.uuid4().hex[:8]}"

try:

new_template = runpod.create_template(name="test", image_name="runpod/base:0.1.0")
new_template = runpod.create_template(
name=TEMPLATE_NAME, image_name="runpod/base:2.0.0-ubuntu2404"
)

print(new_template)

Expand Down
10 changes: 8 additions & 2 deletions examples/api/get_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
""" Get all endpoints from the API """
"""Example of listing your serverless endpoints with the Runpod API."""

import runpod

# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

endpoints = runpod.get_endpoints()

print(endpoints)
# Each entry is the endpoint's full configuration, including its environment
# variables, so print only the id and name here.
for endpoint in endpoints:
print(endpoint["id"], endpoint.get("name"))
14 changes: 7 additions & 7 deletions examples/endpoints/asyncio_job_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
import runpod
from runpod import AsyncioEndpoint, AsyncioJob, http_client

asyncio.set_event_loop_policy(
asyncio.WindowsSelectorEventLoopPolicy()
) # For Windows Users
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

runpod.api_key = "YOUR_API_KEY"
JOB_TIMEOUT = 120 # seconds


async def main():
Expand All @@ -21,7 +20,7 @@ async def main():
async with http_client.AsyncClientSession() as session:
# Invoke API
payload = {}
endpoint = AsyncioEndpoint("ENDPOINT_ID", session)
endpoint = AsyncioEndpoint("YOUR_ENDPOINT_ID", session)
job: AsyncioJob = await endpoint.run(payload)

# Get current job status
Expand All @@ -30,8 +29,9 @@ async def main():
# Print status
print(status)

# Wait until job is completed or failed
output = await job.output()
# Wait until the job completes or fails, up to JOB_TIMEOUT seconds.
# Raises TimeoutError if the job is still running after that.
output = await job.output(timeout=JOB_TIMEOUT)

# Print output
print(output)
Expand Down
4 changes: 2 additions & 2 deletions examples/endpoints/health.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

endpoint = runpod.Endpoint("gwp4kx5yd3nur1")
endpoint = runpod.Endpoint("YOUR_ENDPOINT_ID")

endpoint_health = endpoint.health()

Expand Down
15 changes: 7 additions & 8 deletions examples/endpoints/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

endpoint = runpod.Endpoint("sdxl") # Where "sdxl" is the endpoint ID
endpoint = runpod.Endpoint("YOUR_ENDPOINT_ID")

run_request = endpoint.run(
{"input": {"prompt": "a photo of a horse the size of a Boeing 787"}}
)

# Check the status of the run request
# Check the status of the run request, for example IN_QUEUE or IN_PROGRESS.
print(run_request.status())

# Get the output of the endpoint run request.
print(run_request.output())

# Get the output of the endpoint run request.
# If timeout is greater than 0, this will block until the endpoint run is complete.
# Wait up to 60 seconds for the job to finish, then print its output.
# Raises TimeoutError if the job is still running after that.
# Without a timeout, output() returns immediately, and returns None if the
# job has not finished yet.
print(run_request.output(timeout=60))
10 changes: 7 additions & 3 deletions examples/endpoints/run_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
Example of calling an endpoint using the Runpod Python Language Library.
"""

import requests

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

endpoint = runpod.Endpoint("sdxl") # Where "sdxl" is the endpoint ID
endpoint = runpod.Endpoint("YOUR_ENDPOINT_ID")

try:
# Run the endpoint synchronously, blocking until the endpoint run is complete.
Expand All @@ -17,5 +19,7 @@
)

print(run_request)
except TimeoutError:
except (TimeoutError, requests.exceptions.Timeout):
# TimeoutError: the job was still running when the timeout expired.
# requests.exceptions.Timeout: the HTTP request itself timed out.
print("Job timed out.")
8 changes: 6 additions & 2 deletions examples/endpoints/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

import runpod

# Set your global API key with `runpod config` or uncomment the line below:
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

endpoint = runpod.Endpoint("gwp4kx5yd3nur1")
# This input targets an endpoint running the runpod/mock-worker image started
# with --generator, which yields each item of mock_return with mock_delay
# seconds between them. Replace it with the input your own streaming
# handler expects.
endpoint = runpod.Endpoint("YOUR_ENDPOINT_ID")

run_request = endpoint.run(
{
Expand Down
44 changes: 27 additions & 17 deletions examples/rest_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
"""REST v2 wrapper for the Runpod API."""
"""Create, stop, resume, and terminate a pod with the Runpod API.

This creates a billable GPU pod. The pod is terminated at the end, including
when a step fails.
"""

import time

import runpod

runpod.api_key = "YOUR_RUNPOD_API_KEY"
# Run `rp login` once to store your API key, or uncomment the line below:
# runpod.api_key = "YOUR_RUNPOD_API_KEY"

GPU_TYPE = "NVIDIA GeForce RTX 4090" # see `rp catalog` for other GPU types
WAIT_SECONDS = 10

gpus = runpod.get_gpus()
print(gpus)

gpu = runpod.get_gpu("NVIDIA GeForce RTX 4090")
gpu = runpod.get_gpu(GPU_TYPE)
print(gpu)

pod = runpod.create_pod(
"test",
"example-pod",
"runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404",
"NVIDIA GeForce RTX 4090",
GPU_TYPE,
)
print(pod)
pod_id = pod["id"]

print("Waiting for pod to be created...")
time.sleep(10)
try:
print("Waiting for pod to be created...")
time.sleep(WAIT_SECONDS)

pod = runpod.stop_pod(pod["id"])
print(pod)
print(runpod.stop_pod(pod_id))

print("Waiting for pod to be stopped...")
time.sleep(10)

pod = runpod.resume_pod(pod["id"])
print(pod)
print("Waiting for pod to be stopped...")
time.sleep(WAIT_SECONDS)

print("Waiting for pod to be resumed...")
time.sleep(10)
# Resuming can fail if no GPU of this type is free on the pod's machine.
print(runpod.resume_pod(pod_id))

runpod.terminate_pod(pod["id"])
print("Waiting for pod to be resumed...")
time.sleep(WAIT_SECONDS)
finally:
runpod.terminate_pod(pod_id)
print(f"Terminated pod {pod_id}")
Loading
Loading