https://github.com/rtcamp/wp-cloud-atomic-sdk
https://github.com/rtcamp/wp-cloud-atomic-sdk
Last synced: 6 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/rtcamp/wp-cloud-atomic-sdk
- Owner: rtCamp
- License: mit
- Created: 2025-06-16T11:28:50.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-06-25T15:51:39.000Z (7 months ago)
- Last Synced: 2025-06-25T16:53:52.819Z (7 months ago)
- Language: Python
- Size: 74.2 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Python SDK for the WP.cloud Atomic API
[](https://badge.fury.io/py/atomic-sdk)
[](https://opensource.org/licenses/MIT)
This 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.
This allows you to build automation and integrations without writing boilerplate code, focusing instead on your application's logic.
[βΆοΈ Watch the example video: demo.mp4](https://github.com/user-attachments/assets/285f455b-e3ca-4bb0-98dd-d201d8ea0b0b)
For more examples see the [`examples/`](./examples) directory.
## β¨ Features
- **Complete API Coverage**: Access every API resource group through dedicated client objects (e.g., `client.sites`, `client.backups`).
- **Simplified Site Management**: Use clear methods to create, retrieve, list, update, and delete sites.
- **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.
- **Specific Error Handling**: The SDK raises distinct exceptions for different API errors (`NotFoundError`, `InvalidRequestError`), making your code more resilient.
- **Validated Data Models**: API responses are parsed into Pydantic models, providing type-hinting, validation, and simple attribute-based access to data.
- **Intelligent Helpers**: The SDK abstracts away complexities such as building form-data payloads, handling different SSH connection types, and managing API inconsistencies.
This SDK provides clients for:
- π **Sites**: Full lifecycle management.
- ποΈ **Backups**: Create, list, download, and delete backups.
- π **SSH**: Manage site-specific users, client-wide keys, and aliases.
- π **Metrics**: Query detailed performance and visitor analytics.
- π **Tasks**: Run bulk operations across all your sites.
- π **Edge Cache**: Control caching and DDoS protection.
- βοΈ **Servers**: Get information on available datacenters and PHP versions.
- π€ **Client**: Manage account-wide settings like webhooks.
- βοΈ **Email**: Check the email sending blocklist.
- π οΈ **Utility**: Test API connectivity and authentication.
## βοΈ Installation
Until this package is published on PyPI, you can install it locally for development and testing.
**Requirements:** Python 3.7+
1. **Clone the Repository:**
```bash
git clone https://github.com/rtCamp/wp-cloud-atomic-sdk.git
cd wp-cloud-atomic-sdk
```
2. **Create and Activate a Virtual Environment:**
```bash
python3 -m venv venv
source venv/bin/activate
```
3. **Install in Editable Mode:**
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.
```bash
pip install -e ".[dev]"
```
## π Getting Started
First, instantiate the main client with your API key and client identifier. For security, load these from environment variables.
```python
import os
from dotenv import load_dotenv
from atomic_sdk import AtomicClient
# Load credentials from a .env file
load_dotenv()
API_KEY = os.environ.get("ATOMIC_API_KEY")
CLIENT_ID = os.environ.get("ATOMIC_CLIENT_ID")
# Initialize the main client
client = AtomicClient(api_key=API_KEY, client_id_or_name=CLIENT_ID)
```
## π Usage Examples
Once the client is initialized, you can access all API resource groups as attributes (e.g., `client.sites`, `client.backups`).
### 1. Listing All Sites
A common first step is to list all sites associated with your client account.
```python
from atomic_sdk import AtomicAPIError, NotFoundError
try:
sites = client.sites.list()
print(f"Found {len(sites)} sites.")
for site in sites:
print(f"- Site ID: {site['atomic_site_id']}, Domain: {site['domain_name']}")
except NotFoundError:
print("No sites found for this account.")
except AtomicAPIError as e:
print(f"API error {e.status_code}: {e.message}")
```
### 2. Getting a Single Site's Details
Retrieve details for a specific site using either its domain or its Atomic Site ID. The SDK returns a `Site` object with type-hinted attributes.
```python
from atomic_sdk import NotFoundError
from atomic_sdk.models import Site
try:
# Get by site ID
site_details: Site = client.sites.get(site_id=123456789)
print(f"Domain for site 123456789: {site_details.domain_name}")
print(f"PHP Version: {site_details.php_version}")
except NotFoundError:
print("The specified site could not be found.")
```
### 3. Creating a New Site (Asynchronous Job)
Creating a site is an asynchronous operation. The SDK returns a `Job` object that you can use to poll for its status.
```python
import time
from atomic_sdk import InvalidRequestError
from atomic_sdk.models import Job
try:
print("Starting site creation...")
new_site_job: Job = client.sites.create(
domain_name="new-sdk-site.com", # Replace with your actual site domain
admin_user="sdk_admin",
admin_email="admin@new-sdk-site.com",
php_version="8.3"
)
print(f"Site creation job started with ID: {new_site_job.job_id}")
print("Waiting for job to complete...")
# Poll the job status until it's finished
while True:
status = new_site_job.status()
print(f" - Job status: {status["_status"]}")
job_state = status["_status"] if isinstance(status, dict) and "_status" in status else status
if job_state in ("success", "failed", "error"):
final_status = job_state
break
time.sleep(10) # Wait for 10 seconds before polling again
if final_status == "success":
print(f"Site '{new_site_job.domain_name}' was created successfully!")
else:
print(f"Site creation failed with status: {final_status}")
except InvalidRequestError as e:
print(f"Error creating site: {e}")
```
### 4. Managing Site Software
Install, activate, or remove plugins and themes. This is also an asynchronous job.
```python
actions = {
"plugins/akismet/latest": "activate",
"themes/twentytwentyfour/latest": "install",
}
software_job = client.sites.manage_software(
domain="new-sdk-site.com", # Replace with your actual site domain
software_actions=actions
)
print(f"Software management job ({software_job.job_id}) has been queued.")
# You can use software_job.wait() or a polling loop here as well
```
### 5. Purging the Edge Cache
A simple, one-line command to purge a site's edge cache.
```python
client.edge_cache.purge(domain="new-sdk-site.com")
print("Edge cache purge command sent for new-sdk-site.com.")
```
### 6. Error Handling
The SDK uses custom exceptions to make error handling clean and predictable.
```python
from atomic_sdk import AtomicAPIError, NotFoundError
try:
# Attempt to get a site that does not exist
client.sites.get(site_id=999999999)
except NotFoundError:
print("Caught a NotFoundError, as expected.")
except AtomicAPIError as e:
# Catch any other API-related error
print(f"An API error occurred with status {e.status_code}: {e.message}")
```
## π In-Depth Examples
For 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).
## π License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
## Does this interest you?
