Skip to content

Commit 7515476

Browse files
Merge pull request #77 from runpod/api_functions
Api functions
2 parents 3b39869 + 985a059 commit 7515476

File tree

12 files changed

+231
-38
lines changed

12 files changed

+231
-38
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ Official Python library for RunPod API & SDK.
2222
- [SDK - Serverless Worker](#sdk---serverless-worker)
2323
- [Quick Start](#quick-start)
2424
- [Local Test Worker](#local-test-worker)
25-
- [API Language Library](#api-language-library)
25+
- [API Language Library (GraphQL Wrapper)](#api-language-library-graphql-wrapper)
2626
- [Endpoints](#endpoints)
27-
- [GPU Pod Control](#gpu-pod-control)
27+
- [GPU Cloud (Pods)](#gpu-cloud-pods)
2828
- [Directory](#directory)
2929
- [Community and Contributing](#community-and-contributing)
3030

@@ -79,7 +79,7 @@ You can also test your worker locally before deploying it to RunPod. This is use
7979
python my_worker.py --rp_serve_api
8080
```
8181

82-
## API Language Library
82+
## API Language Library (GraphQL Wrapper)
8383

8484
When interacting with the RunPod API you can use this library to make requests to the API.
8585

@@ -118,7 +118,7 @@ run_request = endpoint.run_sync(
118118
print(run_request )
119119
```
120120

121-
### GPU Pod Control
121+
### GPU Cloud (Pods)
122122

123123
```python
124124
import runpod
@@ -143,7 +143,10 @@ runpod.terminate_pod(pod.id)
143143
```BASH
144144
.
145145
├── docs # Documentation
146+
├── examples # Examples
146147
├── runpod # Package source code
148+
│ ├── api_wrapper # Language library - API (GraphQL)
149+
| ├── cli # Command Line Interface Functions
147150
│ ├── endpoint # Language library - Endpoints
148151
│ └── serverless # SDK - Serverless Worker
149152
└── tests # Package tests
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## Error Handling
2+
3+
The worker is designed to handle errors raised by the handler gracefully. If the handler raises an error, the worker will capture this error and return it as the job output along with the stack trace.
4+
5+
If you want to return a custom error within the handler, this can be accomplished by returning a dictionary with a top-level key of `error` and a value of the error message. The worker will then return this error message as the job output.
6+
7+
### Example
8+
9+
```python
10+
def handler_with_custom_error(job):
11+
if job["id"] == "invalid_job":
12+
return {"error": "Invalid job ID"}
13+
else:
14+
# Handle the job and return the output
15+
return {"output": "Job completed successfully"}
16+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Logging
2+
3+
The worker outputs logs to the console at different points in the workers lifecycle. These logs can be used to debug issues with the worker or handler. There are four logging levels that can be used to control the verbosity of the logs:
4+
5+
0. `NOTSET` - Does not output any logs.
6+
7+
1. `DEBUG` (Default) - Outputs all logs, including debug logs.
8+
9+
2. `INFO` - Outputs all logs except debug logs.
10+
11+
3. `WARNING` - Outputs only warning and error logs.
12+
13+
4. `ERROR` - Outputs only error logs.
14+
15+
### Setting the Logging Level
16+
17+
There are two ways to set the logging level:
18+
19+
1. Set the `RUNPOD_DEBUG_LEVEL` environment variable to one of the above logging levels.
20+
21+
2. Set the `rp_log_level` argument when calling the file with your handler. If this value is set, it will override the `RUNPOD_DEBUG_LEVEL` environment variable.
22+
23+
```python
24+
python worker.py --rp_log_level='INFO'
25+
```

docs/serverless/worker.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,30 @@
11
# The Serverless Worker
22

3-
## Logging
3+
Both RunPod official endpoints as well as custom built endpoints function by means of a worker that fetches available jobs, passes them into a handler and then returns the output.
44

5-
The worker outputs logs to the console at different points in the workers lifecycle. These logs can be used to debug issues with the worker or handler. There are four logging levels that can be used to control the verbosity of the logs:
5+
A worker entry point is a python file containing the command `runpod.serverless.start(config)`. An minimal worker file is shown below:
66

7-
0. `NOTSET` - Does not output any logs.
8-
9-
1. `DEBUG` (Default) - Outputs all logs, including debug logs.
10-
11-
2. `INFO` - Outputs all logs except debug logs.
12-
13-
3. `WARNING` - Outputs only warning and error logs.
14-
15-
4. `ERROR` - Outputs only error logs.
16-
17-
### Setting the Logging Level
18-
19-
There are two ways to set the logging level:
20-
21-
1. Set the `RUNPOD_DEBUG_LEVEL` environment variable to one of the above logging levels.
7+
```python
8+
import runpod
229

23-
2. Set the `rp_log_level` argument when calling the file with your handler. If this value is set, it will override the `RUNPOD_DEBUG_LEVEL` environment variable.
10+
def handler(job):
11+
# Handle the job and return the output
12+
return {"output": "Job completed successfully"}
2413

25-
```python
26-
python worker.py --rp_log_level='INFO'
27-
```
14+
runpod.serverless.start({"handler": handler})
15+
```
2816

29-
## Error Handling
17+
## config
3018

31-
The worker is designed to handle errors raised by the handler gracefully. If the handler raises an error, the worker will capture this error and return it as the job output along with the stack trace.
19+
The `config` parameter is a dictionary containing the following keys:
3220

33-
If you want to return a custom error within the handler, this can be accomplished by returning a dictionary with a top-level key of `error` and a value of the error message. The worker will then return this error message as the job output.
21+
| Key | Type | Description |
22+
|-----------|------------|--------------------------------------------------------------|
23+
| `handler` | `function` | The handler function that will be called with the job input. |
3424

35-
### Example
25+
### handler
3626

37-
```python
38-
def handler_with_custom_error(job):
39-
if job["id"] == "invalid_job":
40-
return {"error": "Invalid job ID"}
41-
else:
42-
# Handle the job and return the output
43-
return {"output": "Job completed successfully"}
44-
```
27+
The handler function can either had a standard return or be a generator function. If the handler is a generator function, it will be called with the job input and the generator will be iterated over until it is exhausted.
4528

4629
## Worker Refresh
4730

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pillow >= 9.5.0
66
py-cpuinfo == 9.0.0
77
python-dotenv >= 1.0.0
88
requests >= 2.31.0
9+
tomli >= 2.0.1
910
tqdm-loggable == 0.1.4
1011
setuptools_scm == 7.1.0
1112

runpod/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
get_gpus, get_gpu,
1010
create_pod, stop_pod, resume_pod, terminate_pod
1111
)
12+
from .cli.config import set_credentials, check_credentials, get_credentials
1213

1314
api_key = None # pylint: disable=invalid-name
1415

runpod/cli/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
''' Allows the CLI to be imported as a module. '''

runpod/cli/config.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'''
2+
runpod | cli | config.py
3+
4+
A collection of functions to set and validate configurations.
5+
Configurations are TOML files located under ~/.runpod/
6+
'''
7+
8+
import os
9+
10+
import tomli as toml
11+
12+
CREDENTIAL_FILE = os.path.expanduser('~/.runpod/credentials.toml')
13+
14+
def set_credentials(api_key: str) -> None:
15+
'''
16+
Sets the user's credentials in ~/.runpod/credentials.toml
17+
18+
Args:
19+
api_key (str): The user's API key.
20+
21+
22+
--- File Structure ---
23+
24+
[default]
25+
api_key = "RUNPOD_API_KEY"
26+
'''
27+
with open(CREDENTIAL_FILE, 'w', encoding="UTF-8") as cred_file:
28+
cred_file.write('[default]\n')
29+
cred_file.write('api_key = "' + api_key + '"\n')
30+
31+
32+
def check_credentials():
33+
'''
34+
Checks if the credentials file exists and is valid.
35+
'''
36+
if not os.path.exists(CREDENTIAL_FILE):
37+
return False, 'Error: ~/.runpod/credentials.toml does not exist.'
38+
39+
# Check for default api_key
40+
try:
41+
config = toml.load(CREDENTIAL_FILE)
42+
43+
if 'default' not in config:
44+
return False, 'Error: ~/.runpod/credentials.toml is missing default section.'
45+
46+
if 'api_key' not in config['default']:
47+
return False, 'Error: ~/.runpod/credentials.toml is missing api_key.'
48+
49+
except (TypeError, ValueError):
50+
return False, 'Error: ~/.runpod/credentials.toml is not a valid TOML file.'
51+
52+
return True, None
53+
54+
55+
def get_credentials(profile='default'):
56+
'''
57+
Returns the credentials for the specified profile from ~/.runpod/credentials.toml
58+
'''
59+
with open(CREDENTIAL_FILE, 'r', encoding="UTF-8") as cred_file:
60+
credentials = toml.load(cred_file)
61+
62+
if profile not in credentials:
63+
return None
64+
65+
return credentials[profile]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ install_requires =
3333
py-cpuinfo >= 9.0.0
3434
python-dotenv >= 1.0.0
3535
requests >= 2.31.0
36+
tomli >= 2.0.1
3637
tqdm-loggable >= 0.1.4
3738
fastapi[all] >= 0.99.0
3839

setup.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@
99
setup(
1010
name='runpod',
1111
use_scm_version=True,
12-
setup_requires=['setuptools_scm']
12+
setup_requires=['setuptools_scm'],
13+
14+
entry_points={
15+
'console_scripts': [
16+
'runpod = runpod.cli:main'
17+
]
18+
}
1319
)

0 commit comments

Comments
 (0)