Skip to content

Commit

Permalink
Merge pull request #186 from runpod/release-prep
Browse files Browse the repository at this point in the history
Release prep
  • Loading branch information
justinmerrell authored Oct 28, 2023
2 parents 6c750f6 + 30c9116 commit c4ae05a
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 12 deletions.
13 changes: 13 additions & 0 deletions .github/tape_collection/cli_config.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Output docs/cli/demos/config.gif

Set FontSize 20
Set Width 1000
Set Height 150
Set Padding 20

Type "runpod config"
Enter

Sleep 4s

Type "<Paste your RunPod API Key here>"
11 changes: 11 additions & 0 deletions .github/tape_collection/cli_help.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Output docs/cli/demos/help.gif

Set FontSize 20
Set Width 1000
Set Height 500
Set Padding 20

Type "runpod --help"
Enter

Sleep 6s
16 changes: 16 additions & 0 deletions .github/tape_collection/cli_ssh.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Output docs/cli/demos/ssh.gif

Set FontSize 20
Set Width 1000
Set Height 200
Set Padding 20

Type "runpod ssh add-key"
Enter

Sleep 4s

Type "y"
Enter

Sleep 4s
43 changes: 43 additions & 0 deletions .github/workflows/vhs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: vhs
on:
push:
# paths:
# - vhs.tape

workflow_dispatch:

jobs:
vhs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install runpod
run: |
pip install .
# runpod --help
- uses: charmbracelet/vhs-action@v1
with:
path: ".github/tape_collection/cli_help.tape"

# runpod config
- uses: charmbracelet/vhs-action@v1
with:
path: ".github/tape_collection/cli_config.tape"

# runpod ssh
- uses: charmbracelet/vhs-action@v1
with:
path: ".github/tape_collection/cli_ssh.tape"

# Add gifs to commit
- uses: stefanzweifel/git-auto-commit-action@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
commit_message: Update generated VHS GIF
commit_user_name: vhs-action 📼
commit_user_email: [email protected]
commit_author: vhs-action 📼 <[email protected]>
file_pattern: "*.gif"
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

### Added

- BETA: CLI DevEx functionality to create development projects.
- `test_output` can be passed in as an arg to compare the results of `test_input`
- Generator/Streaming handlers supported with local testing
- [BETA] CLI DevEx functionality to create development projects.

## Release 1.3.0 (10/12/23)

Expand Down
Binary file added docs/cli/demos/config.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cli/demos/help.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cli/demos/ssh.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions docs/cli/start_here.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# [BETA] | RunPod Python CLI Reference

Note: This CLI is not the same as runpodctl and provides a different set of features.

## Getting Started

![runpod --help](demos/help.gif)

### Configure

![runpod config](demos/config.gif)

Store your RunPod API key by running `runpod config`. Optionally you can also call the command with your API key `runpod config YOUR_API_KEY` or include the `--profile` to save multiple keys (stored under "default" profile is not specified) Credentials are stored in `~/.runpod/config.toml`.

![runpod ssh add-key](demos/ssh.gif)

Add a SSH key to you account by running `runpod ssh add-key`. To specify and existing key pass in `--key` or `--key-file` to use a file. Keys are stored in `~/.runpod/ssh/`. If no key is specified a new one will be generated and stored.
29 changes: 21 additions & 8 deletions runpod/cli/groups/project/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import tomlkit
from tomlkit import document, comment, table, nl

from runpod import get_pod
from runpod import get_pod, __version__
from runpod.cli.utils.ssh_cmd import SSHConnection
from .helpers import get_project_pod, copy_template_files, attempt_pod_launch, load_project_config
from ...utils.rp_sync import sync_directory
Expand All @@ -33,17 +33,30 @@ def create_new_project(project_name, runpod_volume_id, python_version, # pylint:

copy_template_files(template_dir, project_folder)

# Replace placeholders in requirements.txt
requirements_path = os.path.join(project_folder, "builder/requirements.txt")
with open(requirements_path, 'r', encoding='utf-8') as requirements_file:
requirements_content = requirements_file.read()

if "dev" in __version__:
requirements_content = requirements_content.replace(
'<<RUNPOD>>', 'git+https://github.com/runpod/runpod-python.git')
else:
requirements_content = requirements_content.replace(
'<<RUNPOD>>', f'runpod=={__version__}')

with open(requirements_path, 'w', encoding='utf-8') as requirements_file:
requirements_file.write(requirements_content)

# If there's a model_name, replace placeholders in handler.py
if model_name:
handler_path = os.path.join(project_name, "handler.py")
if os.path.exists(handler_path):
with open(handler_path, 'r', encoding='utf-8') as file:
handler_content = file.read()

handler_path = os.path.join(project_name, "src/handler.py")
with open(handler_path, 'r', encoding='utf-8') as file:
handler_content = file.read()
handler_content = handler_content.replace('<<MODEL_NAME>>', model_name)

with open(handler_path, 'w', encoding='utf-8') as file:
file.write(handler_content)
with open(handler_path, 'w', encoding='utf-8') as file:
file.write(handler_content)
else:
project_folder = os.getcwd()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# List your python dependencies here. See https://pip.pypa.io/en/stable/user_guide/#requirements-files
# Required Python packages get listed here, one per line.
# Reccomended to lock the version number to avoid unexpected changes.

runpod==1.3.0
# You can also install packages from a git repository, e.g.:
# git+https://github.com/runpod/runpod-python.git
# To learn more, see https://pip.pypa.io/en/stable/reference/requirements-file-format/

<<RUNPOD>>
23 changes: 22 additions & 1 deletion tests/test_cli/test_cli_groups/test_project_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def test_create_runpod_toml(self, mock_open_file, mock_exists):
with patch("runpod.cli.groups.project.functions.copy_template_files"):
create_new_project("test_project", "volume_id", "3.8")
toml_file_location = os.path.join(os.getcwd(), "test_project", "runpod.toml")
mock_open_file.assert_called_once_with(toml_file_location, 'w', encoding="UTF-8") # pylint: disable=line-too-long
mock_open_file.assert_called_with(toml_file_location, 'w', encoding="UTF-8") # pylint: disable=line-too-long
assert mock_exists.called

@patch('runpod.cli.groups.project.functions.get_project_pod')
Expand All @@ -89,6 +89,27 @@ def test_existing_project_pod(self, mock_get_pod):
launch_project()
mock_print.assert_called_with('Project pod already launched. Run "runpod project start" to start.') # pylint: disable=line-too-long

@patch("os.path.exists", return_value=True)
@patch("builtins.open", new_callable=mock_open, read_data="<<RUNPOD>> placeholder")
def test_update_requirements_file(self, mock_open_file, mock_exists):
""" Test that placeholders in requirements.txt are replaced correctly. """
with patch("runpod.cli.groups.project.functions.__version__", "dev"), \
patch("runpod.cli.groups.project.functions.copy_template_files"):
create_new_project("test_project", "volume_id", "3.8")
assert mock_open_file.called
assert mock_exists.called

@patch("os.path.exists", return_value=True)
@patch("builtins.open", new_callable=mock_open, read_data="<<RUNPOD>> placeholder")
def test_update_requirements_file_non_dev(self, mock_open_file, mock_exists):
""" Test that placeholders in requirements.txt are replaced for non-dev versions. """
with patch("runpod.cli.groups.project.functions.__version__", "1.0.0"), \
patch("runpod.cli.groups.project.functions.copy_template_files"):
create_new_project("test_project", "volume_id", "3.8")
assert mock_open_file.called
assert mock_exists.called


class TestLaunchProject(unittest.TestCase):
""" Test the launch_project function. """

Expand Down

0 comments on commit c4ae05a

Please sign in to comment.