mtn-cloud 0.2.2__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/PKG-INFO +2 -1
  2. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/README.md +1 -0
  3. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/api-overview.md +2 -1
  4. mtn_cloud-0.2.5/docs/api-reference/archive-buckets.md +134 -0
  5. mtn_cloud-0.2.5/docs/api-reference/client.md +44 -0
  6. mtn_cloud-0.2.5/docs/api-reference/clouds.md +40 -0
  7. mtn_cloud-0.2.5/docs/api-reference/groups.md +26 -0
  8. mtn_cloud-0.2.5/docs/api-reference/index.md +80 -0
  9. mtn_cloud-0.2.5/docs/api-reference/instance-types.md +62 -0
  10. mtn_cloud-0.2.5/docs/api-reference/instances.md +167 -0
  11. mtn_cloud-0.2.5/docs/api-reference/networks.md +123 -0
  12. mtn_cloud-0.2.5/docs/api-reference/plans.md +41 -0
  13. mtn_cloud-0.2.5/docs/api-reference/storage-buckets.md +69 -0
  14. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/index.md +4 -2
  15. mtn_cloud-0.2.5/docs/stylesheets/extra.css +30 -0
  16. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/_version.py +1 -1
  17. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/.gitignore +0 -0
  18. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/LICENSE +0 -0
  19. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/advanced-cookbook.md +0 -0
  20. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/docstring-style.md +0 -0
  21. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/instances.md +0 -0
  22. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/networking.md +0 -0
  23. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/quickstart.md +0 -0
  24. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/docs/storage.md +0 -0
  25. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/pyproject.toml +0 -0
  26. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/__init__.py +0 -0
  27. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/client.py +0 -0
  28. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/config.py +0 -0
  29. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/exceptions.py +0 -0
  30. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/http.py +0 -0
  31. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/__init__.py +0 -0
  32. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/archive.py +0 -0
  33. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/base.py +0 -0
  34. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/cloud.py +0 -0
  35. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/group.py +0 -0
  36. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/instance.py +0 -0
  37. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/instance_type.py +0 -0
  38. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/network.py +0 -0
  39. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/plan.py +0 -0
  40. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/storage_bucket.py +0 -0
  41. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/user.py +0 -0
  42. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/models/volume.py +0 -0
  43. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/__init__.py +0 -0
  44. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/archive_buckets.py +0 -0
  45. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/base.py +0 -0
  46. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/clouds.py +0 -0
  47. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/groups.py +0 -0
  48. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/instance_types.py +0 -0
  49. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/instances.py +0 -0
  50. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/networks.py +0 -0
  51. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/plans.py +0 -0
  52. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/src/mtn_cloud/resources/storage_buckets.py +0 -0
  53. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/__init__.py +0 -0
  54. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/conftest.py +0 -0
  55. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_archive_buckets.py +0 -0
  56. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_client.py +0 -0
  57. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_clouds.py +0 -0
  58. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_config.py +0 -0
  59. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_exceptions.py +0 -0
  60. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_instance_types.py +0 -0
  61. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_instances.py +0 -0
  62. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_networks.py +0 -0
  63. {mtn_cloud-0.2.2 → mtn_cloud-0.2.5}/tests/test_storage_buckets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtn-cloud
3
- Version: 0.2.2
3
+ Version: 0.2.5
4
4
  Summary: Community Python SDK for MTN Cloud (Morpheus) - Deploy and manage cloud resources with ease
5
5
  Project-URL: Homepage, https://github.com/mahveotm/mtn-cloud-python
6
6
  Project-URL: Documentation, https://github.com/mahveotm/mtn-cloud-python#readme
@@ -80,6 +80,7 @@ pip install mtn-cloud
80
80
  - [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
81
81
  - [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
82
82
  - [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
83
+ - [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
83
84
  - [Docstring Style Standard](https://mahveotm.github.io/mtn-cloud-python/docstring-style/)
84
85
 
85
86
  ## Quick Start
@@ -36,6 +36,7 @@ pip install mtn-cloud
36
36
  - [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
37
37
  - [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
38
38
  - [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
39
+ - [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
39
40
  - [Docstring Style Standard](https://mahveotm.github.io/mtn-cloud-python/docstring-style/)
40
41
 
41
42
  ## Quick Start
@@ -2,6 +2,8 @@
2
2
 
3
3
  This page summarizes the public SDK surface.
4
4
 
5
+ For endpoint-by-endpoint signatures, parameters, return types, and raised exceptions, see [API Reference](./api-reference/index.md).
6
+
5
7
  ## Entry Point
6
8
 
7
9
  ```python
@@ -83,4 +85,3 @@ Resource methods return typed Pydantic models, for example:
83
85
  - `bucket_name` in archive methods means archive bucket name.
84
86
  - `remote_path` means path inside archive storage.
85
87
  - `local_path` / `local_directory` refer to local filesystem paths.
86
-
@@ -0,0 +1,134 @@
1
+ # Resource: `cloud.archive_buckets` (`ArchiveBucketsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[ArchiveBucket]`
4
+
5
+ - Endpoint: `GET /api/archives/buckets`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: archive bucket name filter
9
+ - Returns: `list[ArchiveBucket]`
10
+ - Raises: common API exceptions
11
+
12
+ ### `get(archive_bucket_id: int) -> ArchiveBucket`
13
+
14
+ - Endpoint: `GET /api/archives/buckets/{archive_bucket_id}`
15
+ - Returns: `ArchiveBucket`
16
+ - Raises: common API exceptions
17
+
18
+ ### `get_by_name(name: str) -> ArchiveBucket`
19
+
20
+ - Endpoint sequence:
21
+ - `GET /api/archives/buckets?name=<name>&max=1`
22
+ - Returns: `ArchiveBucket`
23
+ - Raises:
24
+ - common API exceptions
25
+ - `NotFoundError` when no match
26
+
27
+ ### `create(name: str, *, storage_provider_id: int, description=None, visibility="private", is_public=False, account_id=None) -> ArchiveBucket`
28
+
29
+ - Endpoint: `POST /api/archives/buckets`
30
+ - Parameters:
31
+ - `name`: globally unique archive bucket name
32
+ - `storage_provider_id`: linked storage bucket/provider ID
33
+ - `description`: optional description
34
+ - `visibility`: `private` or `public`
35
+ - `is_public`: enable anonymous public URL support
36
+ - `account_id`: optional tenant account override
37
+ - Returns: `ArchiveBucket`
38
+ - Raises: common API exceptions
39
+
40
+ ### `update(archive_bucket_id: int, *, name=None, description=None, visibility=None, is_public=None, account_id=None) -> ArchiveBucket`
41
+
42
+ - Endpoint: `PUT /api/archives/buckets/{archive_bucket_id}`
43
+ - Returns: `ArchiveBucket`
44
+ - Raises: common API exceptions
45
+
46
+ ### `delete(archive_bucket_id: int) -> bool`
47
+
48
+ - Endpoint: `DELETE /api/archives/buckets/{archive_bucket_id}`
49
+ - Returns: `True`
50
+ - Raises: common API exceptions
51
+
52
+ ### `list_files(*, bucket_name: str, remote_path: str | None = None, name: str | None = None, phrase: str | None = None, full_tree: bool | None = None) -> list[ArchiveFile]`
53
+
54
+ - Endpoint: `GET /api/archives/buckets/{bucket_name}/files/{remote_path}`
55
+ - Parameters:
56
+ - `bucket_name`: archive bucket name (not storage provider name)
57
+ - `remote_path`: archive path to list (defaults to `/`)
58
+ - `name`: exact file name filter
59
+ - `phrase`: wildcard phrase filter
60
+ - `full_tree`: include nested paths
61
+ - Returns: `list[ArchiveFile]`
62
+ - Raises: common API exceptions
63
+
64
+ ### `upload_file(*, bucket_name: str, remote_path: str, local_path: str | Path, filename: str | None = None) -> ArchiveFile`
65
+
66
+ - Endpoint: `POST /api/archives/buckets/{bucket_name}/files/{remote_path}` (multipart)
67
+ - Parameters:
68
+ - `bucket_name`: destination archive bucket name
69
+ - `remote_path`: destination directory path
70
+ - `local_path`: local file path to upload
71
+ - `filename`: optional destination filename override
72
+ - Returns: `ArchiveFile`
73
+ - Raises:
74
+ - common API exceptions
75
+ - `FileNotFoundError` if `local_path` does not exist
76
+ - `ValueError` for invalid filename (empty, hidden name, spaces, unsupported chars)
77
+ - `NotFoundError` with enriched message when destination bucket/path does not exist
78
+
79
+ ### `upload_directory(*, bucket_name: str, remote_path: str, local_directory: str | Path, recursive: bool = True, dry_run: bool = False, strict: bool = False) -> ArchiveDirectoryUploadResult`
80
+
81
+ Bulk upload helper with preflight classification.
82
+
83
+ - Endpoint behavior:
84
+ - Local preflight scan/validation
85
+ - Multiple `POST /api/archives/buckets/{bucket_name}/files/{destination_remote_path}` calls for eligible files
86
+ - Parameters:
87
+ - `bucket_name`: destination archive bucket
88
+ - `remote_path`: base destination directory
89
+ - `local_directory`: source directory
90
+ - `recursive`: include nested files
91
+ - `dry_run`: only preflight, no uploads
92
+ - `strict`: abort upload phase if preflight has skipped files
93
+ - Returns: `ArchiveDirectoryUploadResult` with `scanned`, `eligible`, `skipped`, `uploaded`, `failed`, plus per-file details
94
+ - Raises:
95
+ - `FileNotFoundError` if `local_directory` does not exist
96
+ - `NotADirectoryError` if `local_directory` is not a directory
97
+ - Other exceptions are generally captured into `failed_files`/`skipped_files` entries instead of being raised
98
+
99
+ ### `download_file(*, bucket_name: str, remote_path: str, local_path: str | Path | None = None) -> bytes | Path`
100
+
101
+ - Endpoint: `GET /api/archives/download/{bucket_name}/{remote_path}`
102
+ - Parameters:
103
+ - `local_path`: optional save target; when omitted returns bytes in memory
104
+ - Returns:
105
+ - `bytes` when `local_path` is `None`
106
+ - `Path` when written to disk
107
+ - Raises:
108
+ - common API exceptions
109
+ - filesystem exceptions if writing to `local_path` fails
110
+
111
+ ### `copy_file(*, source_bucket_name: str, source_path: str, destination_bucket_name: str, destination_path: str | None = None, destination_filename: str | None = None) -> ArchiveFile`
112
+
113
+ Copy helper implemented as download + upload.
114
+
115
+ - Endpoint sequence:
116
+ - `GET /api/archives/download/{source_bucket_name}/{source_path}`
117
+ - `POST /api/archives/buckets/{destination_bucket_name}/files/{destination_path or "/"}`
118
+ - Returns: copied `ArchiveFile`
119
+ - Raises:
120
+ - common API exceptions
121
+ - any local/file validation exceptions from `download_file(...)` or `upload_file(...)`
122
+
123
+ ### `get_file(archive_file_id: int) -> ArchiveFile`
124
+
125
+ - Endpoint: `GET /api/archives/files/{archive_file_id}`
126
+ - Returns: `ArchiveFile`
127
+ - Raises: common API exceptions
128
+
129
+ ### `delete_file(archive_file_id: int) -> bool`
130
+
131
+ - Endpoint: `DELETE /api/archives/files/{archive_file_id}`
132
+ - Returns: `True`
133
+ - Raises: common API exceptions
134
+
@@ -0,0 +1,44 @@
1
+ # Client: `MTNCloud`
2
+
3
+ ### `MTNCloud(token=None, username=None, password=None, url=None, timeout=None, verify_ssl=True, config=None)`
4
+
5
+ Creates an SDK client and lazy-loads resource managers.
6
+
7
+ - Endpoint: None (constructor does not make API calls)
8
+ - Parameters:
9
+ - `token`: API bearer token (recommended)
10
+ - `username`, `password`: OAuth password-grant alternative
11
+ - `url`: MTN Cloud base console URL, no `/api` needed
12
+ - `timeout`: request timeout in seconds
13
+ - `verify_ssl`: enable/disable TLS certificate validation
14
+ - `config`: explicit `MTNCloudConfig` object (overrides other args)
15
+ - Returns: `MTNCloud`
16
+ - Raises:
17
+ - `pydantic.ValidationError` if config values violate `MTNCloudConfig` constraints
18
+
19
+ ### `whoami() -> User`
20
+
21
+ - Endpoint: `GET /api/whoami`
22
+ - Parameters: none
23
+ - Returns: `User`
24
+ - Raises: common API exceptions
25
+
26
+ ### `ping() -> bool`
27
+
28
+ Connectivity/auth convenience check.
29
+
30
+ - Endpoint sequence:
31
+ - `GET /api/whoami` (via `whoami()`)
32
+ - Parameters: none
33
+ - Returns:
34
+ - `True` if request succeeds
35
+ - `False` for any exception
36
+ - Raises: none (exceptions are swallowed and converted to `False`)
37
+
38
+ ### `close() -> None`
39
+
40
+ - Endpoint: None
41
+ - Parameters: none
42
+ - Returns: `None`
43
+ - Raises: none
44
+
@@ -0,0 +1,40 @@
1
+ # Resource: `cloud.clouds` (`CloudsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, group_id=None, type_code=None, **filters) -> list[Cloud]`
4
+
5
+ - Endpoint: `GET /api/zones`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: cloud/zone name filter
9
+ - `group_id`: mapped to `groupId`
10
+ - `type_code`: mapped to `type` (example: `openstack`)
11
+ - Returns: `list[Cloud]`
12
+ - Raises: common API exceptions
13
+
14
+ ### `list_openstack(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, group_id=None, **filters) -> list[Cloud]`
15
+
16
+ - Endpoint: `GET /api/zones?type=openstack`
17
+ - Returns: OpenStack-only clouds
18
+ - Raises: common API exceptions
19
+
20
+ ### `get(cloud_id: int) -> Cloud`
21
+
22
+ - Endpoint: `GET /api/zones/{cloud_id}`
23
+ - Returns: `Cloud`
24
+ - Raises: common API exceptions
25
+
26
+ ### `get_by_name(name: str) -> Cloud`
27
+
28
+ - Endpoint sequence:
29
+ - `GET /api/zones?name=<name>&max=1`
30
+ - Returns: `Cloud`
31
+ - Raises:
32
+ - common API exceptions
33
+ - `NotFoundError` when no match
34
+
35
+ ### `list_by_group(group_id: int) -> list[Cloud]`
36
+
37
+ - Endpoint: `GET /api/zones?groupId=<group_id>`
38
+ - Returns: `list[Cloud]`
39
+ - Raises: common API exceptions
40
+
@@ -0,0 +1,26 @@
1
+ # Resource: `cloud.groups` (`GroupsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[Group]`
4
+
5
+ - Endpoint: `GET /api/groups`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: group name filter
9
+ - Returns: `list[Group]`
10
+ - Raises: common API exceptions
11
+
12
+ ### `get(group_id: int) -> Group`
13
+
14
+ - Endpoint: `GET /api/groups/{group_id}`
15
+ - Returns: `Group`
16
+ - Raises: common API exceptions
17
+
18
+ ### `get_by_name(name: str) -> Group`
19
+
20
+ - Endpoint sequence:
21
+ - `GET /api/groups?name=<name>&max=1`
22
+ - Returns: `Group`
23
+ - Raises:
24
+ - common API exceptions
25
+ - `NotFoundError` when no match
26
+
@@ -0,0 +1,80 @@
1
+ # API Reference
2
+
3
+ This section documents the public SDK surface in endpoint-first format.
4
+
5
+ ## Sections
6
+
7
+ - [Client (`MTNCloud`)](./client.md)
8
+ - [Instances (`cloud.instances`)](./instances.md)
9
+ - [Instance Types (`cloud.instance_types`)](./instance-types.md)
10
+ - [Networks (`cloud.networks`)](./networks.md)
11
+ - [Clouds (`cloud.clouds`)](./clouds.md)
12
+ - [Groups (`cloud.groups`)](./groups.md)
13
+ - [Plans (`cloud.plans`)](./plans.md)
14
+ - [Storage Buckets (`cloud.storage_buckets`)](./storage-buckets.md)
15
+ - [Archive Buckets (`cloud.archive_buckets`)](./archive-buckets.md)
16
+
17
+ ## Conventions
18
+
19
+ - Base URL: `https://console.cloud.mtn.ng` by default (configurable via `MTN_CLOUD_URL`).
20
+ - API prefix: the SDK automatically appends `/api`.
21
+ - Endpoint examples below are shown as relative API paths, e.g. `GET /api/instances`.
22
+ - All resource managers are accessed from a client instance:
23
+
24
+ ```python
25
+ from mtn_cloud import MTNCloud
26
+
27
+ cloud = MTNCloud(token="...")
28
+ ```
29
+
30
+ ## Common Exceptions
31
+
32
+ All HTTP-backed methods may raise these exceptions based on API response or transport errors:
33
+
34
+ | Exception | When it is raised |
35
+ |---|---|
36
+ | `AuthenticationError` | `401` or missing/invalid credentials |
37
+ | `ForbiddenError` | `403` insufficient permission |
38
+ | `NotFoundError` | `404` resource not found |
39
+ | `ValidationError` | `400` invalid input/payload |
40
+ | `RateLimitError` | `429` too many requests |
41
+ | `ServerError` | `5xx` backend failure |
42
+ | `TimeoutError` | request timeout |
43
+ | `MTNCloudError` | connection errors, unknown status codes, generic request failures |
44
+
45
+ Method-specific local exceptions (for example `FileNotFoundError`) are documented per method.
46
+
47
+ ## Shared `list(...)` Query Arguments
48
+
49
+ Most resource managers implement a `list(...)` variant with these common query controls:
50
+
51
+ | Argument | API Query Key | Notes |
52
+ |---|---|---|
53
+ | `max_results` | `max` | Maximum returned rows |
54
+ | `offset` | `offset` | Pagination offset |
55
+ | `sort` | `sort` | Sort field |
56
+ | `direction` | `direction` | `asc` or `desc` |
57
+ | `phrase` | `phrase` | API-side search phrase |
58
+ | `**filters` | passthrough | Extra endpoint-specific filters |
59
+
60
+ ## Shared Inherited Helper
61
+
62
+ Every resource manager (`instances`, `networks`, `plans`, etc.) inherits:
63
+
64
+ ### `resource.exists(resource_id: int) -> bool`
65
+
66
+ - Endpoint sequence:
67
+ - `GET /api/<resource-path>/{resource_id}`
68
+ - Returns:
69
+ - `True` if found
70
+ - `False` only when `NotFoundError` occurs
71
+ - Raises:
72
+ - Any non-`NotFoundError` common API exception
73
+
74
+
75
+ ## References
76
+
77
+ - MTN Cloud Console: <https://console.cloud.mtn.ng>
78
+ - MTN Cloud Guide: <https://cloud.mtn.ng/documentation>
79
+ - Morpheus API Docs: <https://apidocs.morpheusdata.com/>
80
+ - SDK Source: <https://github.com/mahveotm/mtn-cloud-python>
@@ -0,0 +1,62 @@
1
+ # Resource: `cloud.instance_types` (`InstanceTypesResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort="name", direction="asc", phrase=None, name=None, code=None, category=None, featured=None, **filters) -> list[InstanceType]`
4
+
5
+ - Endpoint: `GET /api/instance-types`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: name filter
9
+ - `code`: code filter
10
+ - `category`: category filter (`os`, `sql`, `web`, `apps`, etc.)
11
+ - `featured`: feature flag filter
12
+ - Returns: `list[InstanceType]`
13
+ - Raises: common API exceptions
14
+
15
+ ### `get(instance_type_id: int) -> InstanceType`
16
+
17
+ - Endpoint: `GET /api/instance-types/{instance_type_id}`
18
+ - Returns: `InstanceType`
19
+ - Raises: common API exceptions
20
+
21
+ ### `get_by_code(code: str) -> InstanceType`
22
+
23
+ - Endpoint sequence:
24
+ - `GET /api/instance-types?code=<code>&max=1`
25
+ - Returns: `InstanceType`
26
+ - Raises:
27
+ - common API exceptions
28
+ - `NotFoundError` when no match
29
+
30
+ ### `get_by_name(name: str) -> InstanceType`
31
+
32
+ - Endpoint sequence:
33
+ - `GET /api/instance-types?name=<name>&max=1`
34
+ - Returns: `InstanceType`
35
+ - Raises:
36
+ - common API exceptions
37
+ - `NotFoundError` when no match
38
+
39
+ ### `list_os() -> list[InstanceType]`
40
+
41
+ - Endpoint: `GET /api/instance-types?category=os`
42
+ - Returns: OS instance types
43
+ - Raises: common API exceptions
44
+
45
+ ### `list_databases() -> list[InstanceType]`
46
+
47
+ - Endpoint: `GET /api/instance-types?category=sql`
48
+ - Returns: database instance types
49
+ - Raises: common API exceptions
50
+
51
+ ### `list_web() -> list[InstanceType]`
52
+
53
+ - Endpoint: `GET /api/instance-types?category=web`
54
+ - Returns: web instance types
55
+ - Raises: common API exceptions
56
+
57
+ ### `list_apps() -> list[InstanceType]`
58
+
59
+ - Endpoint: `GET /api/instance-types?category=apps`
60
+ - Returns: app instance types
61
+ - Raises: common API exceptions
62
+
@@ -0,0 +1,167 @@
1
+ # Resource: `cloud.instances` (`InstancesResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, status=None, cloud_id=None, group_id=None, labels=None, **filters) -> list[Instance]`
4
+
5
+ - Endpoint: `GET /api/instances`
6
+ - Parameters:
7
+ - Shared list args (see [API Reference](./index.md#shared-list-query-arguments))
8
+ - `name`: exact name filter
9
+ - `status`: status filter
10
+ - `cloud_id`: mapped to query `zoneId`
11
+ - `group_id`: mapped to query `siteId`
12
+ - `labels`: list mapped to comma-delimited query `labels`
13
+ - Returns: `list[Instance]`
14
+ - Raises: common API exceptions
15
+
16
+ ### `get(instance_id: int) -> Instance`
17
+
18
+ - Endpoint: `GET /api/instances/{instance_id}`
19
+ - Parameters:
20
+ - `instance_id`: instance numeric ID
21
+ - Returns: `Instance`
22
+ - Raises: common API exceptions
23
+
24
+ ### `get_by_name(name: str) -> Instance`
25
+
26
+ - Endpoint sequence:
27
+ - `GET /api/instances?name=<name>&max=1`
28
+ - Parameters:
29
+ - `name`: instance name
30
+ - Returns: `Instance`
31
+ - Raises:
32
+ - common API exceptions
33
+ - `NotFoundError` when no instance matches
34
+
35
+ ### `create(name: str, *, cloud: str, type: str, group: str, layout: int, plan: int, description=None, environment=None, labels=None, tags=None, copies=1, layout_size=1, resource_pool_id=None, availability_zone=None, security_group="default", os_external_network_id=None, create_user=True, workflow_id=None, shutdown_days=None, expire_days=None, create_backup=None, security_groups=None, ports=None, volumes=None, network_interfaces=None, options=None) -> Instance`
36
+
37
+ - Endpoint sequence:
38
+ - `GET /api/groups?name=<group>&max=1` (resolve group name to `group_id`)
39
+ - `POST /api/instances`
40
+ - Parameters:
41
+ - Required core fields:
42
+ - `name`: new instance name
43
+ - `cloud`: cloud/zone name (example: `MTNNG_CLOUD_AZ_1`)
44
+ - `type`: instance type code (example: `MTN-CS10`)
45
+ - `group`: group/site name (resolved to ID)
46
+ - `layout`: layout ID
47
+ - `plan`: service plan ID
48
+ - Optional metadata:
49
+ - `description`, `environment`, `labels`, `tags`
50
+ - Optional sizing/provisioning:
51
+ - `copies`, `layout_size`
52
+ - Optional MTN/OpenStack-specific provisioning:
53
+ - `resource_pool_id`, `availability_zone`, `security_group`, `os_external_network_id`, `create_user`
54
+ - Optional automation:
55
+ - `workflow_id`, `shutdown_days`, `expire_days`, `create_backup`
56
+ - Optional networking/storage details:
57
+ - `security_groups`, `ports`, `volumes`, `network_interfaces`, `options`
58
+ - Returns: `Instance`
59
+ - Raises:
60
+ - common API exceptions
61
+ - `NotFoundError` when `group` cannot be resolved
62
+
63
+ ### `update(instance_id: int, name=None, description=None, labels=None) -> Instance`
64
+
65
+ - Endpoint: `PUT /api/instances/{instance_id}`
66
+ - Parameters:
67
+ - `instance_id`: target instance ID
68
+ - `name`: replacement name
69
+ - `description`: replacement description
70
+ - `labels`: replacement labels list
71
+ - Returns: `Instance`
72
+ - Raises: common API exceptions
73
+
74
+ ### `delete(instance_id: int, preserve_volumes=False, force=False) -> bool`
75
+
76
+ - Endpoint: `DELETE /api/instances/{instance_id}`
77
+ - Parameters:
78
+ - `instance_id`: target instance ID
79
+ - `preserve_volumes`: adds query `preserveVolumes=on`
80
+ - `force`: adds query `force=on`
81
+ - Returns: `True` on successful deletion request
82
+ - Raises: common API exceptions
83
+
84
+ ### `start(instance_id: int) -> Instance`
85
+
86
+ - Endpoint sequence:
87
+ - `PUT /api/instances/{instance_id}/start`
88
+ - `GET /api/instances/{instance_id}`
89
+ - Returns: refreshed `Instance`
90
+ - Raises: common API exceptions
91
+
92
+ ### `stop(instance_id: int) -> Instance`
93
+
94
+ - Endpoint sequence:
95
+ - `PUT /api/instances/{instance_id}/stop`
96
+ - `GET /api/instances/{instance_id}`
97
+ - Returns: refreshed `Instance`
98
+ - Raises: common API exceptions
99
+
100
+ ### `restart(instance_id: int) -> Instance`
101
+
102
+ - Endpoint sequence:
103
+ - `PUT /api/instances/{instance_id}/restart`
104
+ - `GET /api/instances/{instance_id}`
105
+ - Returns: refreshed `Instance`
106
+ - Raises: common API exceptions
107
+
108
+ ### `suspend(instance_id: int) -> Instance`
109
+
110
+ - Endpoint sequence:
111
+ - `PUT /api/instances/{instance_id}/suspend`
112
+ - `GET /api/instances/{instance_id}`
113
+ - Returns: refreshed `Instance`
114
+ - Raises: common API exceptions
115
+
116
+ ### `resize(instance_id: int, plan_id: int) -> Instance`
117
+
118
+ - Endpoint sequence:
119
+ - `PUT /api/instances/{instance_id}/resize`
120
+ - `GET /api/instances/{instance_id}`
121
+ - Parameters:
122
+ - `plan_id`: new service plan ID
123
+ - Returns: resized `Instance`
124
+ - Raises: common API exceptions
125
+
126
+ ### `wait_for_status(instance_id: int, target_status: str, timeout: int = 300, poll_interval: int = 5) -> Instance`
127
+
128
+ Client-side polling helper.
129
+
130
+ - Endpoint sequence:
131
+ - repeated `GET /api/instances/{instance_id}` until target status or timeout
132
+ - Parameters:
133
+ - `target_status`: desired status string (`running`, `stopped`, etc.)
134
+ - `timeout`: max wait in seconds
135
+ - `poll_interval`: sleep interval between polls
136
+ - Returns: `Instance` once target status matches
137
+ - Raises:
138
+ - common API exceptions from internal `get`
139
+ - `TimeoutError` when timeout is exceeded
140
+ - `RuntimeError` if instance enters `failed` state
141
+
142
+ ### `wait_until_running(instance_id: int, timeout: int = 300) -> Instance`
143
+
144
+ - Endpoint behavior: same as `wait_for_status(..., target_status="running")`
145
+ - Returns: `Instance`
146
+ - Raises: same as `wait_for_status`
147
+
148
+ ### `wait_until_stopped(instance_id: int, timeout: int = 300) -> Instance`
149
+
150
+ - Endpoint behavior: same as `wait_for_status(..., target_status="stopped")`
151
+ - Returns: `Instance`
152
+ - Raises: same as `wait_for_status`
153
+
154
+ ### `get_console(instance_id: int) -> dict[str, Any]`
155
+
156
+ - Endpoint: `GET /api/instances/{instance_id}/console`
157
+ - Returns: raw console payload (`url`, credentials, metadata)
158
+ - Raises: common API exceptions
159
+
160
+ ### `get_history(instance_id: int, max_results: int | None = None) -> list[dict[str, Any]]`
161
+
162
+ - Endpoint: `GET /api/instances/{instance_id}/history`
163
+ - Parameters:
164
+ - `max_results`: maps to query `max`
165
+ - Returns: list from response key `processes`
166
+ - Raises: common API exceptions
167
+
@@ -0,0 +1,123 @@
1
+ # Resource: `cloud.networks` (`NetworksResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, cloud_id=None, **filters) -> list[Network]`
4
+
5
+ - Endpoint: `GET /api/networks`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: network name filter
9
+ - `cloud_id`: mapped to query `zoneId`
10
+ - Returns: `list[Network]`
11
+ - Raises: common API exceptions
12
+
13
+ ### `get(network_id: int) -> Network`
14
+
15
+ - Endpoint: `GET /api/networks/{network_id}`
16
+ - Returns: `Network`
17
+ - Raises: common API exceptions
18
+
19
+ ### `get_by_name(name: str, cloud_id: int | None = None) -> Network`
20
+
21
+ - Endpoint sequence:
22
+ - `GET /api/networks?name=<name>&max=1`
23
+ - Adds `zoneId=<cloud_id>` when provided
24
+ - Returns: `Network`
25
+ - Raises:
26
+ - common API exceptions
27
+ - `NotFoundError` when no match
28
+
29
+ ### `list_by_cloud(cloud_id: int) -> list[Network]`
30
+
31
+ - Endpoint: `GET /api/networks?zoneId=<cloud_id>`
32
+ - Returns: `list[Network]`
33
+ - Raises: common API exceptions
34
+
35
+ ### `create(name: str, *, cloud_id: int, group_id: int, type_id=None, display_name=None, labels=None, description=None, cidr=None, gateway=None, dns_primary=None, dns_secondary=None, vlan_id=None, switch_id=None, pool_id=None, allow_static_override=None, assign_public_ip=None, active=None, dhcp_server=None, network_domain_id=None, search_domains=None, network_proxy_id=None, appliance_url_proxy_bypass=None, no_proxy=None, visibility=None, tenant_ids=None, resource_permission_all=None, resource_permission_site_ids=None) -> Network`
36
+
37
+ - Endpoint: `POST /api/networks`
38
+ - Parameters:
39
+ - Required:
40
+ - `name`: network name
41
+ - `cloud_id`: cloud/zone ID
42
+ - `group_id`: group/site ID
43
+ - Common optional network config:
44
+ - `type_id`, `display_name`, `labels`, `description`, `cidr`, `gateway`
45
+ - `dns_primary`, `dns_secondary`, `vlan_id`, `switch_id`, `pool_id`
46
+ - `allow_static_override`, `assign_public_ip`, `active`, `dhcp_server`
47
+ - `network_domain_id`, `search_domains`, `network_proxy_id`
48
+ - `appliance_url_proxy_bypass`, `no_proxy`, `visibility`
49
+ - `tenant_ids`, `resource_permission_all`, `resource_permission_site_ids`
50
+ - Returns: `Network`
51
+ - Raises: common API exceptions
52
+
53
+ ### `update(network_id: int, *, display_name=None, labels=None, description=None, cidr=None, gateway=None, dns_primary=None, dns_secondary=None, vlan_id=None, switch_id=None, pool_id=None, allow_static_override=None, assign_public_ip=None, active=None, dhcp_server=None, network_domain_id=None, search_domains=None, network_proxy_id=None, appliance_url_proxy_bypass=None, no_proxy=None, visibility=None, tenant_ids=None, resource_permission_all=None, resource_permission_site_ids=None) -> Network`
54
+
55
+ - Endpoint: `PUT /api/networks/{network_id}`
56
+ - Parameters:
57
+ - `network_id`: target network ID
58
+ - Optional fields mirror `create(...)` (except required create-only identifiers)
59
+ - Returns: `Network`
60
+ - Raises: common API exceptions
61
+
62
+ ### `delete(network_id: int) -> bool`
63
+
64
+ - Endpoint: `DELETE /api/networks/{network_id}`
65
+ - Returns: `True`
66
+ - Raises: common API exceptions
67
+
68
+ ### `list_subnets(network_id: int) -> list[Subnet]`
69
+
70
+ - Endpoint: `GET /api/networks/{network_id}/subnets`
71
+ - Returns: `list[Subnet]`
72
+ - Raises: common API exceptions
73
+
74
+ ### `list_types(name=None, code=None, phrase=None, openstack_only=False) -> list[NetworkTypeInfo]`
75
+
76
+ - Endpoint: `GET /api/network-types`
77
+ - Parameters:
78
+ - `name`: exact name filter
79
+ - `code`: exact code filter
80
+ - `phrase`: phrase filter
81
+ - `openstack_only`: client-side filter on returned `is_openstack`
82
+ - Returns: `list[NetworkTypeInfo]`
83
+ - Raises: common API exceptions
84
+
85
+ ### `get_type(type_id: int) -> NetworkTypeInfo`
86
+
87
+ - Endpoint: `GET /api/network-types/{type_id}`
88
+ - Returns: `NetworkTypeInfo`
89
+ - Raises: common API exceptions
90
+
91
+ ### `list_floating_ips(*, phrase=None, ip_address=None, ip_status=None, cloud_id=None, server_id=None) -> list[NetworkFloatingIP]`
92
+
93
+ - Endpoint: `GET /api/networks/floating-ips`
94
+ - Parameters:
95
+ - `phrase`: search phrase
96
+ - `ip_address`: exact IP match
97
+ - `ip_status`: provider status value
98
+ - `cloud_id`: mapped to `zoneId`
99
+ - `server_id`: mapped to `serverId`
100
+ - Returns: `list[NetworkFloatingIP]`
101
+ - Raises: common API exceptions
102
+
103
+ ### `get_floating_ip(floating_ip_id: int) -> NetworkFloatingIP`
104
+
105
+ - Endpoint: `GET /api/networks/floating-ips/{floating_ip_id}`
106
+ - Returns: `NetworkFloatingIP`
107
+ - Raises: common API exceptions
108
+
109
+ ### `allocate_floating_ip(*, network_server_id: int, floating_ip_pool_id: int) -> NetworkFloatingIP`
110
+
111
+ - Endpoint: `POST /api/networks/floating-ips`
112
+ - Parameters:
113
+ - `network_server_id`: backend network server ID
114
+ - `floating_ip_pool_id`: floating IP pool ID
115
+ - Returns: `NetworkFloatingIP`
116
+ - Raises: common API exceptions
117
+
118
+ ### `release_floating_ip(floating_ip_id: int) -> bool`
119
+
120
+ - Endpoint: `PUT /api/networks/floating-ips/{floating_ip_id}/release`
121
+ - Returns: `True`
122
+ - Raises: common API exceptions
123
+
@@ -0,0 +1,41 @@
1
+ # Resource: `cloud.plans` (`PlansResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[ServicePlan]`
4
+
5
+ - Endpoint: `GET /api/service-plans`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: plan name filter
9
+ - Returns: `list[ServicePlan]`
10
+ - Raises: common API exceptions
11
+
12
+ ### `get(plan_id: int) -> ServicePlan`
13
+
14
+ - Endpoint: `GET /api/service-plans/{plan_id}`
15
+ - Returns: `ServicePlan`
16
+ - Raises: common API exceptions
17
+
18
+ ### `get_by_name(name: str) -> ServicePlan`
19
+
20
+ - Endpoint sequence:
21
+ - `GET /api/service-plans?name=<name>&max=1`
22
+ - Returns: `ServicePlan`
23
+ - Raises:
24
+ - common API exceptions
25
+ - `NotFoundError` when no match
26
+
27
+ ### `find(cores=None, memory_gb=None, storage_gb=None) -> ServicePlan | None`
28
+
29
+ Client-side selector for first plan meeting minimum requirements.
30
+
31
+ - Endpoint sequence:
32
+ - `GET /api/service-plans`
33
+ - Parameters:
34
+ - `cores`: minimum CPU cores
35
+ - `memory_gb`: minimum memory in GB
36
+ - `storage_gb`: minimum storage in GB
37
+ - Returns:
38
+ - `ServicePlan` first match
39
+ - `None` if no plan satisfies constraints
40
+ - Raises: common API exceptions
41
+
@@ -0,0 +1,69 @@
1
+ # Resource: `cloud.storage_buckets` (`StorageBucketsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[StorageBucket]`
4
+
5
+ - Endpoint: `GET /api/storage-buckets`
6
+ - Parameters:
7
+ - Shared list args
8
+ - `name`: storage bucket name filter
9
+ - Returns: `list[StorageBucket]`
10
+ - Raises: common API exceptions
11
+
12
+ ### `get(storage_bucket_id: int) -> StorageBucket`
13
+
14
+ - Endpoint: `GET /api/storage-buckets/{storage_bucket_id}`
15
+ - Returns: `StorageBucket`
16
+ - Raises: common API exceptions
17
+
18
+ ### `get_by_name(name: str) -> StorageBucket`
19
+
20
+ - Endpoint sequence:
21
+ - `GET /api/storage-buckets?name=<name>&max=1`
22
+ - Returns: `StorageBucket`
23
+ - Raises:
24
+ - common API exceptions
25
+ - `NotFoundError` when no match
26
+
27
+ ### `create(name: str, *, bucket_name: str, access_key: str, secret_key: str, endpoint: str, storage_server=None, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None, retention_policy_type="none", retention_policy_days=None, retention_provider=None, create_bucket=True) -> StorageBucket`
28
+
29
+ - Endpoint: `POST /api/storage-buckets`
30
+ - Parameters:
31
+ - Required:
32
+ - `name`: storage bucket object name
33
+ - `bucket_name`: underlying S3 bucket/container name
34
+ - `access_key`, `secret_key`, `endpoint`: provider credentials/endpoint
35
+ - Optional target/default flags:
36
+ - `default_backup_target`, `copy_to_store`, `default_deployment_target`, `default_virtual_image_target`
37
+ - Optional retention behavior:
38
+ - `retention_policy_type`: `backup`, `delete`, or `none`
39
+ - `retention_policy_days`, `retention_provider`
40
+ - `storage_server`: optional storage server ID
41
+ - `create_bucket`: create target bucket when missing
42
+ - Returns: `StorageBucket`
43
+ - Raises: common API exceptions
44
+
45
+ ### `create_s3(name: str, *, bucket_name: str, access_key: str, secret_key: str, endpoint: str, storage_server=None, create_bucket=True, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None) -> StorageBucket`
46
+
47
+ Convenience wrapper for S3-backed create.
48
+
49
+ - Endpoint behavior: forwards to `create(...)` then `POST /api/storage-buckets`
50
+ - Returns: `StorageBucket`
51
+ - Raises: same as `create`
52
+
53
+ ### `update(storage_bucket_id: int, *, name=None, bucket_name=None, config=None, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None, retention_policy_type=None, retention_policy_days=None, retention_provider=None, create_bucket=None) -> StorageBucket`
54
+
55
+ - Endpoint: `PUT /api/storage-buckets/{storage_bucket_id}`
56
+ - Parameters:
57
+ - `storage_bucket_id`: target ID
58
+ - Optional updates for name/bucket/config/defaults/retention
59
+ - Returns: `StorageBucket`
60
+ - Raises: common API exceptions
61
+
62
+ ### `delete(storage_bucket_id: int, *, remove_resources: bool = False) -> bool`
63
+
64
+ - Endpoint: `DELETE /api/storage-buckets/{storage_bucket_id}`
65
+ - Parameters:
66
+ - `remove_resources`: when `True`, sends `removeResources=true`
67
+ - Returns: `True`
68
+ - Raises: common API exceptions
69
+
@@ -14,7 +14,8 @@ Use this guide in two ways:
14
14
  4. [Storage](./storage.md)
15
15
  5. [Advanced Cookbook](./advanced-cookbook.md)
16
16
  6. [API Overview](./api-overview.md)
17
- 7. [Docstring Style Standard](./docstring-style.md)
17
+ 7. [API Reference](./api-reference/index.md)
18
+ 8. [Docstring Style Standard](./docstring-style.md)
18
19
 
19
20
  ## Who This Is For
20
21
 
@@ -36,4 +37,5 @@ Use this guide in two ways:
36
37
  3. Networking
37
38
  4. Storage
38
39
  5. API Overview
39
- 6. Advanced Cookbook
40
+ 6. API Reference
41
+ 7. Advanced Cookbook
@@ -0,0 +1,30 @@
1
+ :root {
2
+ --md-primary-fg-color: #005f73;
3
+ --md-primary-fg-color--light: #0a9396;
4
+ --md-primary-fg-color--dark: #004a59;
5
+ --md-accent-fg-color: #ee9b00;
6
+ }
7
+
8
+ [data-md-color-scheme="default"] {
9
+ --md-code-bg-color: #f3f5f7;
10
+ }
11
+
12
+ [data-md-color-scheme="slate"] {
13
+ --md-default-bg-color: #0e1116;
14
+ --md-default-fg-color: #e6edf3;
15
+ --md-code-bg-color: #161b22;
16
+ }
17
+
18
+ .md-typeset h1 {
19
+ font-weight: 700;
20
+ letter-spacing: -0.01em;
21
+ }
22
+
23
+ .md-typeset h2 {
24
+ border-bottom: 1px solid var(--md-default-fg-color--lightest);
25
+ padding-bottom: 0.2rem;
26
+ }
27
+
28
+ .md-typeset code {
29
+ border-radius: 0.25rem;
30
+ }
@@ -1,3 +1,3 @@
1
1
  """Package version metadata."""
2
2
 
3
- __version__ = "0.2.2"
3
+ __version__ = "0.2.5"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes