mtn-cloud 0.1.0__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 (32) hide show
  1. mtn_cloud-0.1.0/.gitignore +121 -0
  2. mtn_cloud-0.1.0/LICENSE +22 -0
  3. mtn_cloud-0.1.0/PKG-INFO +451 -0
  4. mtn_cloud-0.1.0/README.md +410 -0
  5. mtn_cloud-0.1.0/pyproject.toml +117 -0
  6. mtn_cloud-0.1.0/src/mtn_cloud/__init__.py +72 -0
  7. mtn_cloud-0.1.0/src/mtn_cloud/client.py +278 -0
  8. mtn_cloud-0.1.0/src/mtn_cloud/config.py +143 -0
  9. mtn_cloud-0.1.0/src/mtn_cloud/exceptions.py +261 -0
  10. mtn_cloud-0.1.0/src/mtn_cloud/http.py +402 -0
  11. mtn_cloud-0.1.0/src/mtn_cloud/models/__init__.py +54 -0
  12. mtn_cloud-0.1.0/src/mtn_cloud/models/base.py +123 -0
  13. mtn_cloud-0.1.0/src/mtn_cloud/models/cloud.py +107 -0
  14. mtn_cloud-0.1.0/src/mtn_cloud/models/group.py +62 -0
  15. mtn_cloud-0.1.0/src/mtn_cloud/models/instance.py +367 -0
  16. mtn_cloud-0.1.0/src/mtn_cloud/models/network.py +97 -0
  17. mtn_cloud-0.1.0/src/mtn_cloud/models/plan.py +90 -0
  18. mtn_cloud-0.1.0/src/mtn_cloud/models/user.py +84 -0
  19. mtn_cloud-0.1.0/src/mtn_cloud/models/volume.py +60 -0
  20. mtn_cloud-0.1.0/src/mtn_cloud/resources/__init__.py +22 -0
  21. mtn_cloud-0.1.0/src/mtn_cloud/resources/base.py +196 -0
  22. mtn_cloud-0.1.0/src/mtn_cloud/resources/clouds.py +129 -0
  23. mtn_cloud-0.1.0/src/mtn_cloud/resources/groups.py +111 -0
  24. mtn_cloud-0.1.0/src/mtn_cloud/resources/instances.py +505 -0
  25. mtn_cloud-0.1.0/src/mtn_cloud/resources/networks.py +128 -0
  26. mtn_cloud-0.1.0/src/mtn_cloud/resources/plans.py +141 -0
  27. mtn_cloud-0.1.0/tests/__init__.py +3 -0
  28. mtn_cloud-0.1.0/tests/conftest.py +98 -0
  29. mtn_cloud-0.1.0/tests/test_client.py +157 -0
  30. mtn_cloud-0.1.0/tests/test_config.py +119 -0
  31. mtn_cloud-0.1.0/tests/test_exceptions.py +161 -0
  32. mtn_cloud-0.1.0/tests/test_instances.py +244 -0
@@ -0,0 +1,121 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Environments
57
+ .env
58
+ .venv
59
+ env/
60
+ venv/
61
+ ENV/
62
+ env.bak/
63
+ venv.bak/
64
+
65
+ # Spyder project settings
66
+ .spyderproject
67
+ .spyproject
68
+
69
+ # Rope project settings
70
+ .ropeproject
71
+
72
+ # mkdocs documentation
73
+ /site
74
+
75
+ # mypy
76
+ .mypy_cache/
77
+ .dmypy.json
78
+ dmypy.json
79
+
80
+ # Pyre type checker
81
+ .pyre/
82
+
83
+ # pytype static type analyzer
84
+ .pytype/
85
+
86
+ # Cython debug symbols
87
+ cython_debug/
88
+
89
+ # Ruff
90
+ .ruff_cache/
91
+
92
+ # IDE
93
+ .idea/
94
+ .vscode/
95
+ *.swp
96
+ *.swo
97
+ *~
98
+
99
+ # OS
100
+ .DS_Store
101
+ .DS_Store?
102
+ ._*
103
+ .Spotlight-V100
104
+ .Trashes
105
+ ehthumbs.db
106
+ Thumbs.db
107
+
108
+ # Project specific
109
+ *.log
110
+ *.tmp
111
+ .secrets/
112
+ credentials.json
113
+ config.local.yml
114
+
115
+ # Jupyter Notebooks
116
+ .ipynb_checkpoints/
117
+
118
+ # Local development
119
+ .envrc
120
+ .direnv/
121
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marvellous Osuolale
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,451 @@
1
+ Metadata-Version: 2.4
2
+ Name: mtn-cloud
3
+ Version: 0.1.0
4
+ Summary: Community Python SDK for MTN Cloud (Morpheus) - Deploy and manage cloud resources with ease
5
+ Project-URL: Homepage, https://github.com/mahveotm/mtn-cloud-python
6
+ Project-URL: Documentation, https://github.com/mahveotm/mtn-cloud-python#readme
7
+ Project-URL: Repository, https://github.com/mahveotm/mtn-cloud-python
8
+ Project-URL: Issues, https://github.com/mahveotm/mtn-cloud-python/issues
9
+ Author-email: Marvellous Osuolale <m@rvellous.com>
10
+ Maintainer-email: Marvellous Osuolale <m@rvellous.com>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: api,cloud,devops,infrastructure,morpheus,mtn,sdk
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Systems Administration
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: pydantic-settings>=2.0.0
28
+ Requires-Dist: pydantic>=2.0.0
29
+ Requires-Dist: requests>=2.28.0
30
+ Requires-Dist: typing-extensions>=4.5.0
31
+ Requires-Dist: urllib3>=2.0.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
34
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
35
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
36
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
37
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
38
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
39
+ Requires-Dist: types-requests>=2.28.0; extra == 'dev'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # MTN Cloud Python SDK
43
+
44
+ [![PyPI version](https://badge.fury.io/py/mtn-cloud.svg)](https://badge.fury.io/py/mtn-cloud)
45
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
+
48
+ A community-maintained Python SDK for [MTN Cloud](https://console.cloud.mtn.ng) (Morpheus).
49
+
50
+ > **⚠️ Disclaimer:** This is an **unofficial community project** and is not affiliated with, endorsed by, or supported by MTN. This software is provided "as is", without warranty of any kind. Use at your own risk. See the [LICENSE](LICENSE) for full terms.
51
+
52
+ ## Features
53
+
54
+ - 🚀 **Simple, Pythonic API** - Intuitive interface for all cloud operations
55
+ - 📦 **Typed Models** - Full Pydantic models with IDE autocomplete
56
+ - 🔄 **Automatic Retries** - Built-in retry logic with exponential backoff
57
+ - 🔐 **Flexible Auth** - Token or username/password authentication
58
+ - ⚡ **Resource Managers** - Organized access to instances, networks, volumes
59
+ - 🛡️ **Error Handling** - Specific exceptions for different error types
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install mtn-cloud
65
+ ```
66
+
67
+
68
+ ## Quick Start
69
+
70
+ ```python
71
+ from mtn_cloud import MTNCloud
72
+
73
+ # Initialize with token
74
+ cloud = MTNCloud(token="your-api-token")
75
+
76
+ # Or use environment variable MTN_CLOUD_TOKEN
77
+ cloud = MTNCloud()
78
+
79
+ # Check connection
80
+ user = cloud.whoami()
81
+ print(f"Connected as: {user.username}")
82
+
83
+ # List instances
84
+ for instance in cloud.instances.list():
85
+ print(f"{instance.name}: {instance.status} ({instance.primary_ip})")
86
+ ```
87
+
88
+ ## Authentication
89
+
90
+ ### Using API Token (Recommended)
91
+
92
+ ```python
93
+ from mtn_cloud import MTNCloud
94
+
95
+ # Pass token directly
96
+ cloud = MTNCloud(token="your-api-token")
97
+
98
+ # Or set environment variable
99
+ # export MTN_CLOUD_TOKEN="your-api-token"
100
+ cloud = MTNCloud()
101
+ ```
102
+
103
+ ### Using Username/Password
104
+
105
+ ```python
106
+ cloud = MTNCloud(
107
+ username="user@example.com",
108
+ password="your-password"
109
+ )
110
+ ```
111
+
112
+ ### Getting Your API Token
113
+
114
+ 1. Log in to [MTN Cloud Console](https://console.cloud.mtn.ng)
115
+ 2. Go to **User Settings** → **API Access**
116
+ 3. Generate a new access token
117
+
118
+ ## Usage Examples
119
+
120
+ ### Managing Instances
121
+
122
+ ```python
123
+ from mtn_cloud import MTNCloud
124
+ from mtn_cloud.models import InstanceConfig, InstanceVolume, InstanceNetwork
125
+
126
+ cloud = MTNCloud(token="xxx")
127
+
128
+ # List all instances
129
+ instances = cloud.instances.list()
130
+
131
+ # Filter instances
132
+ running = cloud.instances.list(status="running")
133
+ by_name = cloud.instances.list(name="web-server")
134
+
135
+ # Get a specific instance
136
+ instance = cloud.instances.get(123)
137
+ print(f"Name: {instance.name}")
138
+ print(f"Status: {instance.status}")
139
+ print(f"IP: {instance.primary_ip}")
140
+
141
+ # Get instance by name
142
+ instance = cloud.instances.get_by_name("my-app")
143
+
144
+ # Create a new instance
145
+ instance = cloud.instances.create(
146
+ name="web-server-01",
147
+ cloud_id=1,
148
+ group_id=1,
149
+ instance_type_code="MTN-CS10",
150
+ layout_id=327,
151
+ plan_id=6923,
152
+ config=InstanceConfig(
153
+ resource_pool_id="pool-214",
154
+ availability_zone="Lagos-AZ-1-fd1",
155
+ security_group="default",
156
+ ),
157
+ volumes=[
158
+ InstanceVolume(name="root", size=20),
159
+ ],
160
+ network_interfaces=[
161
+ InstanceNetwork(network_id=298, ip_address="192.168.100.50"),
162
+ ],
163
+ labels=["production", "web"],
164
+ )
165
+
166
+ # Wait for instance to be running
167
+ instance = cloud.instances.wait_until_running(instance.id, timeout=300)
168
+
169
+ # Instance actions
170
+ instance.stop()
171
+ instance.start()
172
+ instance.restart()
173
+
174
+ # Or use the resource manager
175
+ cloud.instances.stop(123)
176
+ cloud.instances.start(123)
177
+
178
+ # Resize instance
179
+ cloud.instances.resize(123, plan_id=6924)
180
+
181
+ # Delete instance
182
+ cloud.instances.delete(123)
183
+
184
+ # Force delete with volume preservation
185
+ cloud.instances.delete(123, force=True, preserve_volumes=True)
186
+ ```
187
+
188
+ ### Working with Networks
189
+
190
+ ```python
191
+ # List all networks
192
+ networks = cloud.networks.list()
193
+
194
+ # List networks for a specific cloud
195
+ networks = cloud.networks.list(cloud_id=1)
196
+
197
+ # Get network by ID
198
+ network = cloud.networks.get(298)
199
+ print(f"Network: {network.name}")
200
+ print(f"CIDR: {network.cidr}")
201
+ print(f"Gateway: {network.gateway}")
202
+
203
+ # Get network by name
204
+ network = cloud.networks.get_by_name("my-network")
205
+ ```
206
+
207
+ ### Managing Groups and Clouds
208
+
209
+ ```python
210
+ # List groups
211
+ for group in cloud.groups.list():
212
+ print(f"{group.name}: {group.instance_count} instances")
213
+
214
+ # Get group by name
215
+ group = cloud.groups.get_by_name("MTNNG_CLOUD_AZ_1")
216
+
217
+ # List clouds/zones
218
+ for c in cloud.clouds.list():
219
+ print(f"{c.name}: {c.type_code}")
220
+
221
+ # Get cloud by name
222
+ zone = cloud.clouds.get_by_name("MTNNG_CLOUD_AZ_1")
223
+ ```
224
+
225
+ ### Service Plans
226
+
227
+ ```python
228
+ # List all plans
229
+ plans = cloud.plans.list()
230
+
231
+ for plan in plans:
232
+ print(f"{plan.name}: {plan.cores} cores, {plan.memory_gb}GB RAM")
233
+
234
+ # Find a plan by requirements
235
+ plan = cloud.plans.find(cores=2, memory_gb=4)
236
+ ```
237
+
238
+ ## Error Handling
239
+
240
+ The SDK provides specific exceptions for different error types:
241
+
242
+ ```python
243
+ from mtn_cloud import (
244
+ MTNCloud,
245
+ MTNCloudError,
246
+ AuthenticationError,
247
+ NotFoundError,
248
+ ForbiddenError,
249
+ ValidationError,
250
+ RateLimitError,
251
+ TimeoutError,
252
+ )
253
+
254
+ cloud = MTNCloud(token="xxx")
255
+
256
+ try:
257
+ instance = cloud.instances.get(99999)
258
+ except NotFoundError as e:
259
+ print(f"Instance not found: {e}")
260
+ except AuthenticationError as e:
261
+ print(f"Auth failed: {e}")
262
+ except ForbiddenError as e:
263
+ print(f"Access denied: {e}")
264
+ except ValidationError as e:
265
+ print(f"Invalid request: {e}")
266
+ print(f"Errors: {e.errors}")
267
+ except RateLimitError as e:
268
+ print(f"Rate limited. Retry after: {e.retry_after}s")
269
+ except TimeoutError as e:
270
+ print(f"Request timed out: {e}")
271
+ except MTNCloudError as e:
272
+ print(f"API error: {e}")
273
+ ```
274
+
275
+ ## Configuration
276
+
277
+ ### Environment Variables
278
+
279
+ | Variable | Description | Default |
280
+ |----------|-------------|---------|
281
+ | `MTN_CLOUD_TOKEN` | API access token | - |
282
+ | `MTN_CLOUD_URL` | API base URL | `https://console.cloud.mtn.ng` |
283
+ | `MTN_CLOUD_TIMEOUT` | Request timeout (seconds) | `30` |
284
+ | `MTN_CLOUD_MAX_RETRIES` | Max retry attempts | `3` |
285
+ | `MTN_CLOUD_VERIFY_SSL` | Verify SSL certs | `true` |
286
+
287
+ ### Programmatic Configuration
288
+
289
+ ```python
290
+ from mtn_cloud import MTNCloud, MTNCloudConfig
291
+
292
+ # Using config object
293
+ config = MTNCloudConfig(
294
+ token="xxx",
295
+ timeout=60,
296
+ max_retries=5,
297
+ debug=True,
298
+ )
299
+ cloud = MTNCloud(config=config)
300
+
301
+ # Or pass arguments directly
302
+ cloud = MTNCloud(
303
+ token="xxx",
304
+ timeout=60,
305
+ verify_ssl=False, # Not recommended for production
306
+ )
307
+ ```
308
+
309
+ ## Context Manager
310
+
311
+ Use as a context manager for automatic cleanup:
312
+
313
+ ```python
314
+ with MTNCloud(token="xxx") as cloud:
315
+ instances = cloud.instances.list()
316
+ # Session is automatically closed when exiting
317
+ ```
318
+
319
+ ## Advanced Usage
320
+
321
+ ### Waiting for Instance States
322
+
323
+ ```python
324
+ # Wait for specific status
325
+ instance = cloud.instances.wait_for_status(
326
+ instance_id=123,
327
+ target_status="running",
328
+ timeout=300,
329
+ poll_interval=5,
330
+ )
331
+
332
+ # Convenience methods
333
+ instance = cloud.instances.wait_until_running(123)
334
+ instance = cloud.instances.wait_until_stopped(123)
335
+ ```
336
+
337
+ ### Instance Actions from Instance Object
338
+
339
+ ```python
340
+ # Get instance
341
+ instance = cloud.instances.get(123)
342
+
343
+ # Actions are available directly on the instance
344
+ instance.stop()
345
+ instance.start()
346
+ instance.restart()
347
+ instance.delete()
348
+
349
+ # Refresh data from API
350
+ instance.refresh()
351
+ ```
352
+
353
+ ### Checking Connection
354
+
355
+ ```python
356
+ # Quick connection check
357
+ if cloud.ping():
358
+ print("Connected!")
359
+ else:
360
+ print("Connection failed")
361
+ ```
362
+
363
+ ## API Reference
364
+
365
+ ### MTNCloud
366
+
367
+ Main client class.
368
+
369
+ | Property | Description |
370
+ |----------|-------------|
371
+ | `instances` | Instance resource manager |
372
+ | `networks` | Network resource manager |
373
+ | `groups` | Group resource manager |
374
+ | `clouds` | Cloud/zone resource manager |
375
+ | `plans` | Service plan resource manager |
376
+
377
+ | Method | Description |
378
+ |--------|-------------|
379
+ | `whoami()` | Get current user |
380
+ | `ping()` | Check connection |
381
+ | `close()` | Close HTTP session |
382
+
383
+ ### InstancesResource
384
+
385
+ | Method | Description |
386
+ |--------|-------------|
387
+ | `list(**filters)` | List instances |
388
+ | `get(id)` | Get instance by ID |
389
+ | `get_by_name(name)` | Get instance by name |
390
+ | `create(...)` | Create new instance |
391
+ | `update(id, ...)` | Update instance |
392
+ | `delete(id)` | Delete instance |
393
+ | `start(id)` | Start instance |
394
+ | `stop(id)` | Stop instance |
395
+ | `restart(id)` | Restart instance |
396
+ | `suspend(id)` | Suspend instance |
397
+ | `resize(id, plan_id)` | Resize instance |
398
+ | `wait_for_status(...)` | Wait for status |
399
+ | `wait_until_running(id)` | Wait until running |
400
+ | `wait_until_stopped(id)` | Wait until stopped |
401
+
402
+ ## Development
403
+
404
+ ### Setup
405
+
406
+ ```bash
407
+ git clone https://github.com/mahveotm/mtn-cloud-python
408
+ cd mtn-cloud-python
409
+ pip install -e ".[dev]"
410
+ ```
411
+
412
+ ### Running Tests
413
+
414
+ ```bash
415
+ pytest
416
+ pytest --cov=mtn_cloud
417
+ ```
418
+
419
+ ### Code Quality
420
+
421
+ ```bash
422
+ # Format code
423
+ ruff format src tests
424
+
425
+ # Lint code
426
+ ruff check src tests
427
+
428
+ # Lint and auto-fix
429
+ ruff check src tests --fix
430
+
431
+ # Type checking
432
+ mypy src
433
+ ```
434
+
435
+ ## License
436
+
437
+ MIT License - see [LICENSE](LICENSE) for details.
438
+
439
+ This is an unofficial community project. Not affiliated with MTN.
440
+
441
+ ## Author
442
+
443
+ **Marvellous Osuolale** - [GitHub](https://github.com/mahveotm)
444
+
445
+ ## Links
446
+
447
+ - [MTN Cloud Console](https://console.cloud.mtn.ng)
448
+ - [Morpheus Documentation](https://docs.morpheusdata.com)
449
+ - [GitHub Repository](https://github.com/mahveotm/mtn-cloud-python)
450
+ - [PyPI Package](https://pypi.org/project/mtn-cloud/)
451
+