{"id":29140521,"url":"https://github.com/rtcamp/wp-cloud-atomic-sdk","last_synced_at":"2025-07-22T12:33:45.443Z","repository":{"id":301194597,"uuid":"1002939556","full_name":"rtCamp/wp-cloud-atomic-sdk","owner":"rtCamp","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-25T15:51:39.000Z","size":76,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-25T16:53:52.819Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rtCamp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-16T11:28:50.000Z","updated_at":"2025-06-25T15:51:43.000Z","dependencies_parsed_at":"2025-06-25T17:03:58.231Z","dependency_job_id":null,"html_url":"https://github.com/rtCamp/wp-cloud-atomic-sdk","commit_stats":null,"previous_names":["rtcamp/wp-cloud-atomic-sdk"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rtCamp/wp-cloud-atomic-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtCamp%2Fwp-cloud-atomic-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtCamp%2Fwp-cloud-atomic-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtCamp%2Fwp-cloud-atomic-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtCamp%2Fwp-cloud-atomic-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rtCamp","download_url":"https://codeload.github.com/rtCamp/wp-cloud-atomic-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtCamp%2Fwp-cloud-atomic-sdk/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266496309,"owners_count":23938706,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-30T17:06:47.584Z","updated_at":"2025-07-22T12:33:45.411Z","avatar_url":"https://github.com/rtCamp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Python SDK for the WP.cloud Atomic API\n\n[![PyPI version](https://badge.fury.io/py/atomic-sdk.svg)](https://badge.fury.io/py/atomic-sdk)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nThis SDK provides a direct and efficient Python interface for the [WP.cloud Atomic API](https://wp.cloud/docs/api/). It handles the underlying complexities of authentication, API requests, and asynchronous job polling, providing a clean, object-oriented interface for managing your hosting resources.\n\nThis allows you to build automation and integrations without writing boilerplate code, focusing instead on your application's logic.\n\n[▶️ Watch the example video: demo.mp4](https://github.com/user-attachments/assets/285f455b-e3ca-4bb0-98dd-d201d8ea0b0b)\n\nFor more examples see the [`examples/`](./examples) directory.\n\n## ✨ Features\n\n-   **Complete API Coverage**: Access every API resource group through dedicated client objects (e.g., `client.sites`, `client.backups`).\n-   **Simplified Site Management**: Use clear methods to create, retrieve, list, update, and delete sites.\n-   **Asynchronous Job Handling**: Long-running operations return a `Job` object. You can poll it or use the built-in `.wait()` method to block until completion.\n-   **Specific Error Handling**: The SDK raises distinct exceptions for different API errors (`NotFoundError`, `InvalidRequestError`), making your code more resilient.\n-   **Validated Data Models**: API responses are parsed into Pydantic models, providing type-hinting, validation, and simple attribute-based access to data.\n-   **Intelligent Helpers**: The SDK abstracts away complexities such as building form-data payloads, handling different SSH connection types, and managing API inconsistencies.\n\nThis SDK provides clients for:\n-   📂 **Sites**: Full lifecycle management.\n-   🗄️ **Backups**: Create, list, download, and delete backups.\n-   🔑 **SSH**: Manage site-specific users, client-wide keys, and aliases.\n-   📊 **Metrics**: Query detailed performance and visitor analytics.\n-   🚀 **Tasks**: Run bulk operations across all your sites.\n-   🌐 **Edge Cache**: Control caching and DDoS protection.\n-   ⚙️ **Servers**: Get information on available datacenters and PHP versions.\n-   👤 **Client**: Manage account-wide settings like webhooks.\n-   ✉️ **Email**: Check the email sending blocklist.\n-   🛠️ **Utility**: Test API connectivity and authentication.\n\n## ⚙️ Installation\n\nUntil this package is published on PyPI, you can install it locally for development and testing.\n\n**Requirements:** Python 3.7+\n\n1.  **Clone the Repository:**\n    ```bash\n    git clone https://github.com/rtCamp/wp-cloud-atomic-sdk.git\n    cd wp-cloud-atomic-sdk\n    ```\n\n2.  **Create and Activate a Virtual Environment:**\n    ```bash\n    python3 -m venv venv\n    source venv/bin/activate\n    ```\n\n3.  **Install in Editable Mode:**\n    Install the package with its development dependencies. The `-e` flag links the installation to your source code, so any changes you make are immediately available.\n    ```bash\n    pip install -e \".[dev]\"\n    ```\n\n## 🚀 Getting Started\n\nFirst, instantiate the main client with your API key and client identifier. For security, load these from environment variables.\n\n```python\nimport os\nfrom dotenv import load_dotenv\nfrom atomic_sdk import AtomicClient\n\n# Load credentials from a .env file\nload_dotenv()\nAPI_KEY = os.environ.get(\"ATOMIC_API_KEY\")\nCLIENT_ID = os.environ.get(\"ATOMIC_CLIENT_ID\")\n\n# Initialize the main client\nclient = AtomicClient(api_key=API_KEY, client_id_or_name=CLIENT_ID)\n```\n\n## 📝 Usage Examples\n\nOnce the client is initialized, you can access all API resource groups as attributes (e.g., `client.sites`, `client.backups`).\n\n### 1. Listing All Sites\n\nA common first step is to list all sites associated with your client account.\n\n```python\nfrom atomic_sdk import AtomicAPIError, NotFoundError\n\ntry:\n    sites = client.sites.list()\n    print(f\"Found {len(sites)} sites.\")\n    for site in sites:\n        print(f\"- Site ID: {site['atomic_site_id']}, Domain: {site['domain_name']}\")\nexcept NotFoundError:\n    print(\"No sites found for this account.\")\nexcept AtomicAPIError as e:\n    print(f\"API error {e.status_code}: {e.message}\")\n```\n\n### 2. Getting a Single Site's Details\n\nRetrieve details for a specific site using either its domain or its Atomic Site ID. The SDK returns a `Site` object with type-hinted attributes.\n\n```python\nfrom atomic_sdk import NotFoundError\nfrom atomic_sdk.models import Site\n\ntry:\n    # Get by site ID\n    site_details: Site = client.sites.get(site_id=123456789)\n    print(f\"Domain for site 123456789: {site_details.domain_name}\")\n    print(f\"PHP Version: {site_details.php_version}\")\n\nexcept NotFoundError:\n    print(\"The specified site could not be found.\")\n```\n\n### 3. Creating a New Site (Asynchronous Job)\n\nCreating a site is an asynchronous operation. The SDK returns a `Job` object that you can use to poll for its status.\n\n```python\nimport time\nfrom atomic_sdk import InvalidRequestError\nfrom atomic_sdk.models import Job\n\ntry:\n    print(\"Starting site creation...\")\n    new_site_job: Job = client.sites.create(\n        domain_name=\"new-sdk-site.com\", # Replace with your actual site domain\n        admin_user=\"sdk_admin\",\n        admin_email=\"admin@new-sdk-site.com\",\n        php_version=\"8.3\"\n    )\n\n    print(f\"Site creation job started with ID: {new_site_job.job_id}\")\n    print(\"Waiting for job to complete...\")\n\n    # Poll the job status until it's finished\n    while True:\n        status = new_site_job.status()\n        print(f\"  - Job status: {status[\"_status\"]}\")\n\n        job_state = status[\"_status\"] if isinstance(status, dict) and \"_status\" in status else status\n\n        if job_state in (\"success\", \"failed\", \"error\"):\n            final_status = job_state\n            break\n\n        time.sleep(10) # Wait for 10 seconds before polling again\n\n    if final_status == \"success\":\n        print(f\"Site '{new_site_job.domain_name}' was created successfully!\")\n    else:\n        print(f\"Site creation failed with status: {final_status}\")\n\nexcept InvalidRequestError as e:\n    print(f\"Error creating site: {e}\")\n```\n\n### 4. Managing Site Software\n\nInstall, activate, or remove plugins and themes. This is also an asynchronous job.\n\n```python\nactions = {\n    \"plugins/akismet/latest\": \"activate\",\n    \"themes/twentytwentyfour/latest\": \"install\",\n}\n\nsoftware_job = client.sites.manage_software(\n    domain=\"new-sdk-site.com\", # Replace with your actual site domain\n    software_actions=actions\n)\n\nprint(f\"Software management job ({software_job.job_id}) has been queued.\")\n# You can use software_job.wait() or a polling loop here as well\n```\n\n### 5. Purging the Edge Cache\n\nA simple, one-line command to purge a site's edge cache.\n\n```python\nclient.edge_cache.purge(domain=\"new-sdk-site.com\")\nprint(\"Edge cache purge command sent for new-sdk-site.com.\")\n```\n\n### 6. Error Handling\n\nThe SDK uses custom exceptions to make error handling clean and predictable.\n\n```python\nfrom atomic_sdk import AtomicAPIError, NotFoundError\n\ntry:\n    # Attempt to get a site that does not exist\n    client.sites.get(site_id=999999999)\nexcept NotFoundError:\n    print(\"Caught a NotFoundError, as expected.\")\nexcept AtomicAPIError as e:\n    # Catch any other API-related error\n    print(f\"An API error occurred with status {e.status_code}: {e.message}\")\n```\n\n## 📚 In-Depth Examples\n\nFor detailed, runnable scripts covering every feature of the API—from managing backups to running bulk WP-CLI tasks—please see the [`examples/`](./examples) directory and its comprehensive [`README.md`](./examples/README.md).\n\n## 📄 License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Does this interest you?\n\n\u003ca href=\"https://rtcamp.com/\"\u003e\u003cimg src=\"https://rtcamp.com/wp-content/uploads/sites/2/2019/04/github-banner@2x.png\" alt=\"Join us at rtCamp, we specialize in providing high performance enterprise WordPress solutions\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtcamp%2Fwp-cloud-atomic-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frtcamp%2Fwp-cloud-atomic-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtcamp%2Fwp-cloud-atomic-sdk/lists"}