Skip to content
Merged
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
4 changes: 4 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
paths:
.github/workflows/**/*.{yml,yaml}:
ignore:
- '"paths" section must be sequence node but got alias node with "" tag'
17 changes: 8 additions & 9 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5

permissions:
contents: read

steps:
- name: "Checkout"
uses: actions/checkout@v6
Expand Down Expand Up @@ -52,17 +55,13 @@ jobs:
python -m build

- name: "List Artifacts"
env:
path: ${{ inputs.path }}
working-directory: ${{ inputs.path }}
run: |
echo "::group::ls"
ls -lAhR "${path}"
echo "::endgroup::"
echo "::group::tree"
tree "${path}"
results="$(tree . || ls -lAhR .)"
echo "::group::results"
echo "${results}"
echo "::endgroup::"
results="$(tree "${path}")"
markdown='Artifacts:\n```text\n'"${results}"'\n```'
markdown='Artifacts: `${{ inputs.path }}`\n```text\n'"${results}"'\n```'
echo -e "${markdown}" >> $GITHUB_STEP_SUMMARY

- name: "Upload to Actions"
Expand Down
35 changes: 19 additions & 16 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
default: site

env:
logo: "https://raw.githubusercontent.com/smashedr/repo-images/refs/heads/master/vultr-python/logo128.png"
logo: "https://raw.githubusercontent.com/cssnr/vultr-python/refs/heads/master/.github/assets/logo.svg"
link: ${{ github.event.repository.html_url }}

jobs:
Expand All @@ -22,9 +22,12 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5

permissions:
contents: read

steps:
- name: "Checkout"
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: "Debug CTX github"
continue-on-error: true
Expand All @@ -50,29 +53,29 @@ jobs:
python -m pip install -U pdoc
python -m pip install -e .
python -m pdoc -t docs -o "${{ inputs.path }}" \
--favicon "${{ env.logo }}" \
--logo "${{ env.logo }}" \
--logo-link "${{ env.link }}" \
vultr

- name: "Update Permissions"
- name: "Fix Docs"
working-directory: ${{ inputs.path }}
run: |
chmod -c -R +rX "${{ inputs.path }}" | while read name; do
echo "::notice::Fixed invalid file permissions: ${name}"
done
mv -f vultr.html index.html

#- name: "Update Permissions"
# run: |
# chmod -c -R +rX "${{ inputs.path }}" | while read name; do
# echo "::notice::Fixed invalid file permissions: ${name}"
# done

- name: "List Artifacts"
env:
path: ${{ inputs.path }}
working-directory: ${{ inputs.path }}
run: |
echo "::group::ls"
ls -lAhR "${path}"
echo "::endgroup::"
echo "::group::tree"
tree "${path}"
results="$(tree . || ls -lAhR .)"
echo "::group::results"
echo "${results}"
echo "::endgroup::"
results="$(tree "${path}")"
markdown='Artifacts:\n```text\n'"${results}"'\n```'
markdown='Artifacts: `${{ inputs.path }}`\n```text\n'"${results}"'\n```'
echo -e "${markdown}" >> $GITHUB_STEP_SUMMARY

- name: "Upload Pages Artifact"
Expand Down
28 changes: 14 additions & 14 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

steps:
- name: "Checkout"
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: "Debug event.json"
continue-on-error: true
Expand Down Expand Up @@ -137,19 +137,19 @@ jobs:
echo "::endgroup::"
"${RUNNER_TEMP}/actionlint" -color -verbose -shellcheck= -pyflakes=

#- name: "pytest"
# if: ${{ !cancelled() }}
# id: coverage
# run: |
# coverage run -m pytest
# coverage xml
# coverage report -m

#- name: "codecov"
# if: ${{ !cancelled() && steps.coverage.outcome == 'success' }}
# uses: codecov/codecov-action@v5
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
- name: "pytest"
if: ${{ !cancelled() }}
id: coverage
run: |
coverage run -m pytest
coverage xml
coverage report -m

- name: "codecov"
if: ${{ !cancelled() && steps.coverage.outcome == 'success' }}
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

#- name: "hadolint"
# if: ${{ !cancelled() }}
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
with:
name: "release"

permissions:
contents: read

publish:
name: "Publish"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -107,6 +110,9 @@ jobs:
timeout-minutes: 5
needs: [publish]

permissions:
contents: write

steps:
- name: "Debug"
continue-on-error: true
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: "Test"

on:
workflow_dispatch:
push:
branches: [master]
paths: &paths
- ".github/workflows/test.yaml"
- "src/**"
- "tests/**"
- "pyproject.toml"
pull_request:
paths: *paths

jobs:
build:
name: "Build"
if: ${{ !contains(github.event.head_commit.message, '#notest') }}
uses: ./.github/workflows/build.yaml
with:
name: test

permissions:
contents: read

test:
runs-on: ubuntu-22.04
timeout-minutes: 5
needs: [build]
strategy:
fail-fast: false
matrix:
version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
name: "Test ${{ matrix.version }}"

permissions:
contents: read

steps:
- name: "Checkout"
uses: actions/checkout@v6

- name: "Debug event.json"
if: ${{ !github.event.act }}
continue-on-error: true
run: cat "${GITHUB_EVENT_PATH}"

- name: "Debug CTX github"
if: ${{ !github.event.act }}
continue-on-error: true
env:
GITHUB_CTX: ${{ toJSON(github) }}
run: echo "$GITHUB_CTX"

- name: "Debug Environment"
if: ${{ !github.event.act }}
continue-on-error: true
run: env

- name: "Download Artifact"
uses: actions/download-artifact@v6
with:
name: test
path: dist

- name: "Setup Python ${{ matrix.version }}"
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.version }}
cache: "pip"

- name: "Install ${{ matrix.version }}"
run: |
python -V
python -m pip install -U pip pytest
python -m pip install dist/*.whl

#- name: "Debug ${{ matrix.version }}"
# run: |
# ls -lAhR dist/

- name: "Test ${{ matrix.version }}"
#continue-on-error: ${{ contains('dev', matrix.version) }}
run: |
pytest -s
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prune tests
76 changes: 53 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9b356c4327df41e395c81de1c717ce11)](https://app.codacy.com/gh/cssnr/vultr-python/dashboard)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=cssnr_vultr-python&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=cssnr_vultr-python)
[![Workflow Lint](https://img.shields.io/github/actions/workflow/status/cssnr/vultr-python/lint.yaml?logo=cachet&label=lint)](https://github.com/cssnr/vultr-python/actions/workflows/lint.yaml)
[![GitHub Deployments](https://img.shields.io/github/deployments/cssnr/vultr-python/github-pages?logo=materialformkdocs&logoColor=white&label=github-pages)](https://cssnr.github.io/vultr-python)
[![Workflow Test](https://img.shields.io/github/actions/workflow/status/cssnr/vultr-python/test.yaml?logo=cachet&label=test)](https://github.com/cssnr/vultr-python/actions/workflows/test.yaml)
[![Deployments PyPi](https://img.shields.io/github/deployments/cssnr/vultr-python/pypi?logo=pypi&logoColor=white&label=pypi)](https://pypi.org/project/vultr-python/)
[![Deployments Pages](https://img.shields.io/github/deployments/cssnr/vultr-python/github-pages?logo=materialformkdocs&logoColor=white&label=github-pages)](https://cssnr.github.io/vultr-python/)
[![GitHub Last Commit](https://img.shields.io/github/last-commit/cssnr/vultr-python?logo=github&label=updated)](https://github.com/cssnr/vultr-python/graphs/commit-activity)
[![GitHub Repo Size](https://img.shields.io/github/repo-size/cssnr/vultr-python?logo=bookstack&logoColor=white&label=repo%20size)](https://github.com/cssnr/vultr-python)
[![GitHub Top Language](https://img.shields.io/github/languages/top/cssnr/vultr-python?logo=htmx&logoColor=white)](https://github.com/cssnr/vultr-python?tab=readme-ov-file#readme)
Expand All @@ -19,8 +21,8 @@

# Vultr Python

<a title="Vultr Python" href="https://cssnr.github.io/vultr-python" target="_blank">
<img alt="Vultr Python" align="right" width="128" height="auto" src="https://raw.githubusercontent.com/smashedr/repo-images/refs/heads/master/vultr-python/logo128.png"></a>
<a title="Vultr Python" href="https://cssnr.github.io/vultr-python/" target="_blank">
<img alt="Vultr Python" align="right" width="128" height="auto" src="https://raw.githubusercontent.com/cssnr/vultr-python/refs/heads/master/.github/assets/logo.svg"></a>

- [Install](#Install)
- [Usage](#Usage)
Expand All @@ -31,13 +33,12 @@ Python 3 wrapper for the Vultr API v2.

[![GitHub](https://img.shields.io/badge/github-232925?style=for-the-badge&logo=github)](https://github.com/cssnr/vultr-python?tab=readme-ov-file#readme)
[![PyPi](https://img.shields.io/badge/pypi-006dad?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/vultr-python)
[![Docs](https://img.shields.io/badge/docs-198754?style=for-the-badge&logo=mdbook)](https://cssnr.github.io/vultr-python)
[![Docs](https://img.shields.io/badge/docs-198754?style=for-the-badge&logo=mdbook)](https://cssnr.github.io/vultr-python/)
[![Vultr](https://img.shields.io/badge/vultr-007bfc?style=for-the-badge&logo=vultr)](https://www.vultr.com/api/?ref=6905748)

Vultr API Reference: [https://www.vultr.com/api](https://www.vultr.com/api/?ref=6905748)

> [!TIP]
> This project is not complete, but has many useful functions.
> Please submit a [Feature Request](https://github.com/cssnr/vultr-python/discussions/categories/feature-requests)
> or report any [Issues](https://github.com/cssnr/vultr-python/issues).

Expand All @@ -60,57 +61,86 @@ python -m pip install vultr-python

## Usage

You will need to create an api key and whitelist your IP address.
Most functions do not work without an API Key.
You will need to create an api key and whitelist your IP address for most functions.

- [https://my.vultr.com/settings/#settingsapi](https://my.vultr.com/settings/#settingsapi)

Initialize the class with your API Key or with the `VULTR_API_KEY` environment variable.
Initialize the `Vultr` class with your API Key or use the `VULTR_API_KEY` environment variable.

```python
from vultr import Vultr

vultr = Vultr('VULTR_API_KEY')
vultr = Vultr("VULTR_API_KEY")
```

List plans and get available regions for that plan

```python
plans = vultr.list_plans()
plan = plans[0] # 0 seems to be the basic 5 dollar plan
plans = vultr.list_plans({"type": "vc2"}) # Filter by type
plan = plans[0] # 0 seems to be the base plan
regions = vultr.list_regions()
available = vultr.filter_regions(regions, plan['locations'])
available = vultr.filter_regions(regions, plan["locations"])
```

Get the OS list and filter by name

```python
os_list = vultr.list_os()
ubuntu_lts = vultr.filter_os(os_list, 'Ubuntu 24.04 LTS x64')
ubuntu_lts = vultr.filter_os(os_list, "Ubuntu 24.04 LTS x64")
```

Create a new ssh key from key string

```python
sshkey = vultr.create_key('key-name', 'ssh-rsa AAAA...')
sshkey = vultr.create_key("key-name", "ssh-rsa AAAA...")
vultr.delete_key(sshkey['id'])
```

Create a new instance

```python
hostname = 'my-new-host'
data = {
'region': available[0]['id'],
'plan': plan['id'],
'os_id': ubuntu_lts['id'],
'sshkey_id': [sshkey['id']],
'hostname': hostname,
'label': hostname,
"os_id": ubuntu_lts["id"],
"sshkey_id": [sshkey["id"]],
"hostname": "my-new-host",
"label": "my-new-host",
}
instance = vultr.create_instance(**data)
instance = vultr.create_instance(available[0], plan, **data)
```

Full Documentation: [https://cssnr.github.io/vultr-python](https://cssnr.github.io/vultr-python)
Arbitrary Methods `get`, `post`, `patch`, `put`, `delete`

```python
plans = vultr.get("/plans", {"type": "vc2"})
sshkey = vultr.post("/ssh-keys", name="key-name", ssh_key="ssh-rsa AAAA...")
instance = vultr.patch("/instances/{instance-id}", plan=plans[1]["id"])
database = vultr.put("/databases/{database-id}", tag="new tag")
vultr.delete("/snapshots/{snapshot-id}")
```

Error Handling

```python
>>> instance = vultr.create_instance("atl", "vc2-1c-0.5gb-v6", os_id=2284)
Traceback (most recent call last):
vultr.vultr.VultrException: Error 400: Server add failed: Ubuntu 24.04 LTS x64 requires a plan with at least 1000 MB memory.
```

Using the `VultrException` class

```python
from vultr import VultrException

try:
instance = vultr.create_instance("atl", "vc2-1c-0.5gb-v6", os_id=2284)
except VultrException as error:
print(error.error)
# 'Server add failed: Ubuntu 24.04 LTS x64 requires a plan with at least 1000 MB memory.'
print(error.status)
# 400
```

Full Documentation: [https://cssnr.github.io/vultr-python](https://cssnr.github.io/vultr-python/)

Vultr API Reference: [https://www.vultr.com/api](https://www.vultr.com/api/?ref=6905748)

Expand Down
Loading