diff --git a/Makefile b/Makefile index aca1cede..9f0a60f9 100644 --- a/Makefile +++ b/Makefile @@ -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: diff --git a/docs/source/index.rst b/docs/source/index.rst index 50f7b688..a81d70d7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -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 -`_. +**PyDo** is the official Python client library for the `DigitalOcean API v2 `_. 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 `_ 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 `_ 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="") + 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 -`_) 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 `_. + +************* +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="") + 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 -`_. -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: \ No newline at end of file + :show-inheritance: