Skip to content
Open
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
53 changes: 24 additions & 29 deletions atomic_sdk/api/sites.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import List, Optional, Literal, Dict, Any, Union

from .base import ResourceClient
from ..exceptions import InvalidRequestError
from ..exceptions import AtomicAPIError, InvalidRequestError
from ..models import Job, Site


Expand All @@ -10,6 +10,21 @@ class SitesClient(ResourceClient):
A client for interacting with the Sites and site-management endpoints.
"""

def _parse_job(self, response_data: Any) -> Job:
"""Parse a job-style response, raising AtomicAPIError on shape mismatch."""
if not isinstance(response_data, dict) or "job_id" not in response_data:
raise AtomicAPIError(
message=(
"Expected a job response (dict with 'job_id'), "
f"got {type(response_data).__name__}: {response_data!r}"
),
status_code=200,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this as-is because issue #11 explicitly requested status_code=200 for malformed job payloads returned from a successful _post() call. Non-2xx responses are still handled earlier by ResourceClient._request; this helper only covers the “HTTP 200 but unexpected data shape” case.

)

job = Job.parse_obj(response_data)
job._client = self._client
return job

# --- Helper for Log Payloads ---
def _build_log_payload(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""Builds the specially-formatted payload for log endpoints."""
Expand Down Expand Up @@ -121,10 +136,7 @@ def create(self, admin_user: str, admin_email: str, domain_name: Optional[str] =

endpoint = f"/create-site/{self._client_id_or_name}"
response_data = self._post(endpoint, data=payload)

job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

def delete(self, site_id: Optional[int] = None, domain: Optional[str] = None) -> Job:
"""
Expand All @@ -140,10 +152,7 @@ def delete(self, site_id: Optional[int] = None, domain: Optional[str] = None) ->
service, identifier = self._get_service_and_identifier(site_id, domain)
endpoint = f"/delete-site/{service}/{identifier}"
response_data = self._post(endpoint)

job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

def update_domain(self, new_domain: str, site_id: Optional[int] = None, domain: Optional[str] = None, keep_old_domain: bool = False) -> Job:
"""
Expand All @@ -163,10 +172,7 @@ def update_domain(self, new_domain: str, site_id: Optional[int] = None, domain:
if keep_old_domain:
endpoint += "/keep"
response_data = self._post(endpoint)

job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

# --- Domain and DNS Management ---

Expand Down Expand Up @@ -260,10 +266,7 @@ def manage_software(self, software_actions: Dict[str, str], site_id: Optional[in
_, identifier = self._get_service_and_identifier(site_id, domain)
endpoint = f"/site-manage-software/atomic/{identifier}"
response_data = self._post(endpoint, data=software_actions)

job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

def set_wordpress_version(self, version: Literal["latest", "previous", "beta"], site_id: Optional[int] = None, domain: Optional[str] = None) -> Job:
"""
Expand All @@ -281,9 +284,7 @@ def set_wordpress_version(self, version: Literal["latest", "previous", "beta"],
_, identifier = self._get_service_and_identifier(site_id, domain)
endpoint = f"/site-wordpress-version/{identifier}/{version}"
response_data = self._post(endpoint)
job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

def update_options(self, options: dict, site_id: Optional[int] = None, domain: Optional[str] = None) -> Job:
"""
Expand All @@ -303,9 +304,7 @@ def update_options(self, options: dict, site_id: Optional[int] = None, domain: O
_, identifier = self._get_service_and_identifier(site_id, domain)
endpoint = f"/update-site-options/atomic/{identifier}"
response_data = self._post(endpoint, data={'options': options})
job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

def update_persistent_data(self, data_to_update: Dict[str, Any], site_id: Optional[int] = None, domain: Optional[str] = None) -> Job:
"""
Expand All @@ -328,9 +327,7 @@ def update_persistent_data(self, data_to_update: Dict[str, Any], site_id: Option
for action, value in actions.items():
payload[f"data[{key}][{action}]"] = value
response_data = self._post(endpoint, data=payload)
job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

# --- Site Metadata and Utilities ---

Expand Down Expand Up @@ -401,9 +398,7 @@ def reset_db_password(self, site_id: Optional[int] = None, domain: Optional[str]
_, identifier = self._get_service_and_identifier(site_id, domain)
endpoint = f"/reset-db-password/atomic/{identifier}"
response_data = self._post(endpoint)
job = Job.parse_obj(response_data)
job._client = self._client
return job
return self._parse_job(response_data)

# --- SSL Management ---

Expand Down
Loading