From c60e8f4c8262a2de6c96b2f7bfb3add83c437643 Mon Sep 17 00:00:00 2001 From: Diya Date: Thu, 9 Oct 2025 20:46:18 +0530 Subject: [PATCH 1/2] Update index.rst 1.Improved Structure and Flow: The document is reorganized into logical sections (Getting Started, Quickstart, Core Concepts, API Reference) to guide the user from installation to more advanced topics. A toctree has also been added to support a multi-page documentation site. 2.Enhanced Introduction: The introduction is now more welcoming, immediately clarifies that PyDo is the official DigitalOcean library, and includes a note directive to encourage community contributions via GitHub issues. 3.Clearer Authentication Instructions: The "Authentication" section now provides a direct link to the DigitalOcean token generation page and explicitly recommends using environment variables for better security, showing both methods for clarity. 4.Refined Quickstart Example: The main example is now a complete, self-contained script with proper imports and a try...except block. This allows new users to copy, paste, and run the code immediately. 5.Created "Core Concepts" Section: Advanced topics like Pagination have been moved out of the quickstart and into a new "Core Concepts" section. The pagination example itself has been improved by wrapping it in a reusable function, making it more practical. 6.Improved Code Blocks: All shell and Python code now uses explicit code-block directives (e.g., bash, python) to enable proper syntax highlighting. --- docs/source/index.rst | 158 ++++++++++++++++++++++++++++++------------ 1 file changed, 112 insertions(+), 46 deletions(-) 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: From a3c6ed8b66a45d87ef3059ba50635310aa13c7b9 Mon Sep 17 00:00:00 2001 From: Diya Date: Wed, 15 Oct 2025 22:40:31 +0530 Subject: [PATCH 2/2] Update Makefile Corrected a critical issue where multiple test targets (test-mocked, test-integration, test-integration-single) were incorrectly declared with the same .PHONY name, causing make to run the wrong command. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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: