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
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ lint-tests: install ## Lints the code
test-mocked: install ## Runs the mock test suite
poetry run pytest -rA --tb=short tests/mocked/. $(PYTEST_ARGS)

.PHONY: test-mocked
.PHONY: test-integration
test-integration: install ## Runs the integration test suite
poetry run pytest -rA --tb=short tests/integration/. $(PYTEST_EXCLUDE_MARKS) $(PYTEST_ARGS)

.PHONY: test-mocked
test-integration-single: install ## This command runs a single integration test, e.g. > make test-integration-single test=test_actions
poetry run pytest -rA --tb=short tests/integration/. -k $(test)
.PHONY: test-integration-single
test-integration-single: install ## Runs a single integration test, e.g. > make test-integration-single test=test_actions
poetry run pytest -rA --tb=short tests/integration/. -k $(TEST_FILTER)

.PHONY: docker-build
docker-build:
Expand Down
158 changes: 112 additions & 46 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,79 +1,145 @@
.. PyDo documentation master file, created by
sphinx-quickstart on Mon Nov 7 12:26:30 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. PyDo documentation master file.
.. For a guide on reStructuredText, see: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html

#########################################
:mod:`PyDo` --- DigitalOcean's Python library
#########################################
###################################
Welcome to PyDo's Documentation!
###################################

.. module:: pydo

:mod:`pydo` is a Python client library for DigitalOceans's `HTTP API
<https://docs.digitalocean.com/reference/api/api-reference/>`_.
**PyDo** is the official Python client library for the `DigitalOcean API v2 <https://docs.digitalocean.com/reference/api/api-reference/>`_. It allows you to manage your DigitalOcean resources, like Droplets, Volumes, and SSH Keys, directly from your Python code.

This documentation will guide you through installation, authentication, and basic usage of the library.

.. toctree::
:maxdepth: 2
:caption: Contents:

api_reference

.. note::

This project is actively developed. We encourage you to open an `issue on GitHub <https://github.com/digitalocean/pydo/issues>`_ if you encounter any problems or have suggestions for improvement!

***************
Getting Started
***************

First, let's get the library installed and configured.

Installation
============

Install from PyPI::
PyDo requires Python 3.7 or newer. You can install it from PyPI using pip:

pip install pydo
.. code-block:: bash

pip install pydo

Initialization
Authentication
==============

:mod:`pydo` must be initialized with :meth:`pydo.client`. A
DigitalOcean API Token is required. The token can be passed explicitly to :meth:`pydo.client` or defined as environment variables
``DIGITALOCEAN_TOKEN``.
To use the DigitalOcean API, you need a personal access token.

1. **Generate a Token**: You can generate a token from the `Applications & API page <https://cloud.digitalocean.com/account/api/tokens>`_ in the DigitalOcean control panel.
2. **Set the Token**: You must initialize the ``Client`` with your token. The recommended way is to set it as an environment variable:

.. code-block:: bash

export DIGITALOCEAN_TOKEN="your_api_token_here"

The client will automatically detect and use this variable.

Here's an example of initializing the PyDo Client::
Alternatively, you can pass the token directly when creating the client instance. **Be careful not to expose this token in your source code.**

from pydo import Client
.. code-block:: python

client = Client(token="<DIGITALOCEAN_TOKEN>")
from pydo import Client

# Initialize by reading the environment variable (recommended)
client = Client()

# Or, initialize by passing the token directly
# client = Client(token="your_api_token_here")

.. autofunction:: pydo.Client

Example
===========
Find below a working example for GET a ssh_key (`per this http request
<https://docs.digitalocean.com/reference/api/api-reference/#operation/sshKeys_list>`_) and printing the ID associated with the ssh key. If you'd like to try out this quick example, you can follow these instructions to add ssh keys to your DO account::
***********************
Quickstart: List SSH Keys
***********************

Here is a complete example to list all the SSH keys in your DigitalOcean account.

.. code-block:: python

import os
from pydo import Client

# Assumes your token is set as an environment variable
# DIGITALOCEAN_TOKEN
client = Client()

try:
ssh_keys_resp = client.ssh_keys.list()
print("Successfully fetched SSH keys:")
for key in ssh_keys_resp["ssh_keys"]:
print(f"- ID: {key['id']}, Name: {key['name']}")
# Example output:
# - ID: 123456, Name: my_test_ssh_key

except Exception as e:
print(f"An error occurred: {e}")

For a more comprehensive example that demonstrates creating Droplets and managing Volumes, see our `end-to-end example script <https://github.com/digitalocean/pydo/blob/main/examples/poc_droplets_volumes_sshkeys.py>`_.

*************
Core Concepts
*************

Handling Pagination
===================

API requests that return a list of items are paginated. By default, 25 items are returned per page. You can check the ``links`` attribute in the response to see if there are more pages.

Here's how to iterate through all pages of your SSH keys:

from pydo import Client
.. code-block:: python

client = Client(token="<YOUR-API-TOKEN>")
from urllib.parse import urlparse, parse_qs

ssh_keys_resp = client.ssh_keys.list()
for k in ssh_keys_resp["ssh_keys"]:
print(f"ID: {k['id']}, NAME: {k['name']}, FINGERPRINT: {k['fingerprint']}")
def get_all_ssh_keys(client: Client):
all_keys = []
page = 1
paginated = True

The above code snippet should output the following::
while paginated:
resp = client.ssh_keys.list(per_page=50, page=page)
all_keys.extend(resp["ssh_keys"])

ID: 123456, NAME: my_test_ssh_key, FINGERPRINT: 5c:74:7e:60:28:69:34:ca:dd:74:67:c3:f3:00:7f:fe
ID: 123457, NAME: my_prod_ssh_key, FINGERPRINT: eb:76:c7:2a:d3:3e:80:5d:ef:2e:ca:86:d7:79:94:0d
# Check if a 'next' page URL exists in the response links
if 'next' in resp["links"]["pages"]:
next_url = resp["links"]["pages"]['next']
# Extract the page number from the URL for the next request
page = parse_qs(urlparse(next_url).query)['page'][0]
else:
paginated = False

You can find a more thorough example of using the PyDo client `here
<https://github.com/digitalocean/pydo/blob/main/examples/poc_droplets_volumes_sshkeys.py>`_.
The example walks through the process of creating a droplet with a specified ssh key, creating a volume, and then attaching the volume to the droplet.
return all_keys

Pagination
~~~~~~~~~~~
Below is an example on handling pagination. One must parse the URL to find the next page::
# Usage:
# client = Client()
# all_my_keys = get_all_ssh_keys(client)
# print(f"Found {len(all_my_keys)} total keys.")

resp = self.client.ssh_keys.list(per_page=50, page=page)
pages = resp.links.pages
if 'next' in pages.keys():
parsed_url = urlparse(pages['next'])
page = parse_qs(parsed_url.query)['page'][0]
else:
paginated = False

*************
API Reference
*************

pydo.Client Usage
===========
For a detailed list of all available operations and their parameters, please see the auto-generated API reference.

.. This will be a separate page, e.g., `api_reference.rst`
.. automodule:: pydo.operations
:members:
:undoc-members:
:show-inheritance:
:show-inheritance: