Skip to main content

Community Python SDK for MTN Cloud (Morpheus) - Deploy and manage cloud resources with ease

Project description

MTN Cloud Python SDK

PyPI version Tests Python 3.10+ License: MIT

A Python SDK for MTN Cloud (Morpheus).

⚠️ Disclaimer: Unofficial community project. Not affiliated with MTN Nigeria.

Features

  • 🚀 Simple, Pythonic API - Intuitive interface for all cloud operations
  • 📦 Typed Models - Full Pydantic models with IDE autocomplete
  • 🔄 Automatic Retries - Built-in retry logic with exponential backoff
  • 🔐 Flexible Auth - Token or username/password authentication
  • Resource Managers - Organized access to instances, networks, groups
  • 🛡️ Error Handling - Specific exceptions for different error types

Installation

pip install mtn-cloud

Quick Start

from mtn_cloud import MTNCloud

cloud = MTNCloud(token="your-api-token")

# Check connection
user = cloud.whoami()
print(f"Connected as: {user.username}")

# List instances
for instance in cloud.instances.list():
    print(f"{instance.name}: {instance.status} ({instance.primary_ip})")

Authentication

# Using token (recommended)
cloud = MTNCloud(token="your-api-token")

# Or via environment variable
# export MTN_CLOUD_TOKEN="your-api-token"
cloud = MTNCloud()

# Using username/password
cloud = MTNCloud(username="user@example.com", password="your-password")

Getting your API token: MTN Cloud Console → User Icon (top right) → User Settings → API Access


Creating an Instance

from mtn_cloud import MTNCloud
from mtn_cloud.models import InstanceVolume, InstanceNetwork

cloud = MTNCloud(token="your-api-token")

instance = cloud.instances.create(
    name="my-server",
    cloud="MTNNG_CLOUD_AZ_1",
    type="MTN-CS10",                     # Instance type code
    group="MTNNG_CLOUD_AZ_1",            # Group name (resolved to ID automatically)
    layout=327,                          # Layout ID for MTN-CS10
    plan=6775,                           # Service plan ID (G2S2: 2 cores, 2GB RAM)
    resource_pool_id="pool-214",
    availability_zone="Lagos-AZ-1-fd1",
    security_group="default",
    os_external_network_id="public-network-01",
    volumes=[
        InstanceVolume(
            name="root",
            size=20,                     # Size in GB
            storage_type=11,
            datastore_id="auto",
        ),
    ],
    network_interfaces=[
        InstanceNetwork(
            network_id="network-298",
            ip_address="192.168.100.50",  # Optional: static IP
        ),
    ],
    labels=["production", "web"],
)

print(f"Instance created: {instance.name} (ID: {instance.id})")

# Wait for instance to be running
instance = cloud.instances.wait_until_running(instance.id, timeout=300)
print(f"Instance is now: {instance.status}")
print(f"IP Address: {instance.primary_ip}")

Reference Data

Groups

groups = cloud.groups.list()
for group in groups:
    print(f"{group.name} (ID: {group.id})")

group = cloud.groups.get_by_name("MTNNG_CLOUD_AZ_1")
Name ID
MTNNG_CLOUD_AZ_1 621

Instance Types

instance_types = cloud.instance_types.list()
for it in instance_types:
    print(f"{it.code}: {it.name} (Layout ID: {it.default_layout_id})")

# Get by code
centos = cloud.instance_types.get_by_code("MTN-CS10")
print(f"Layout ID: {centos.default_layout_id}")

# List by category
os_types = cloud.instance_types.list_os()
db_types = cloud.instance_types.list_databases()
web_types = cloud.instance_types.list_web()
app_types = cloud.instance_types.list_apps()
View all instance types
Category Code Name Layout ID
OS MTN-CS10 CentOS Stream 10 327
OS MTN-CS9 CentOS Stream 9 394
OS MTN-U24.04LTS Ubuntu Server 24.04.3LTS 309
OS MTN-U22.04LTS Ubuntu Server 22.04.5LTS 325
OS MTN-D12 Debian 12 283
OS MTN-D13 Debian 13 330
OS MTN-RL9 Rocky Linux 9.6 395
OS MTN-RL10 Rocky Linux 10 397
OS MTN-F42 Fedora 42 392
OS MTN-F43 Fedora 43 393
OS MTN-WINSVR2019 Windows Server 2019 (BYOL) 300
OS MTN-WINSVR2022 Windows Server 2022 (BYOL) 301
Database MTN-MySQL01 MySQL Single-Node 375
Database MTN-Postgres01 PostgreSQL Single-Node 333
Web MTN-APACHEWS Apache Web Server 372
Web MTN-NGINXWS Nginx Web Server 374
Apps MTN-LAMP01 LAMP Stack Server 379
Apps MTN-LEMP01 LEMP Stack Server 380
Apps MK8S-M Kubernetes Master 386
Apps MK8S-W Kubernetes Worker 387
Network MTN-WGVPN-01 WireGuard SSL VPN 364

Service Plans

Note: The Service Plans API is restricted. Use the reference below.

Naming Convention:

  • G{cores}S{ram} - General Purpose (e.g., G2S4 = 2 cores, 4GB RAM)
  • Ge{cores}{tier}{ram} - General Enterprise (e.g., Ge32M64 = 32 cores, 64GB RAM)
  • Tiers: S (Standard), M (Medium), L (Large)
View all service plans
Plan ID Cores RAM (GB) Category
G1S1 6772 1 1 General
G1S2 6773 1 2 General
G1S4 6774 1 4 General
G2S2 6775 2 2 General
G2S4 6776 2 4 General
G2S8 6777 2 8 General
G2S16 6778 2 16 General
G4S4 6779 4 4 General
G4S8 6780 4 8 General
G4S16 6781 4 16 General
G4S32 6782 4 32 General
G8S8 6783 8 8 General
G8S16 6784 8 16 General
G8S32 6785 8 32 General
G8S64 6786 8 64 General
Ge16S16 6787 16 16 Enterprise
Ge16S32 6788 16 32 Enterprise
Ge16S48 6789 16 48 Enterprise
Ge16S64 6790 16 64 Enterprise
Ge32M32 6791 32 32 Enterprise
Ge32M64 6792 32 64 Enterprise
Ge32M72 6793 32 72 Enterprise
Ge32M128 6794 32 128 Enterprise
Ge64L64 6795 64 64 Enterprise
Ge64L128 6796 64 128 Enterprise
Ge64L256 6797 64 256 Enterprise
Ge64L384 6798 64 384 Enterprise
Ge96L128 6799 96 128 Enterprise
Ge96L256 6800 96 256 Enterprise
Ge96L384 6801 96 384 Enterprise

Networks

networks = cloud.networks.list()
for network in networks:
    print(f"{network.name} (ID: {network.id})")

network = cloud.networks.get(298)
print(f"Network: {network.name}")
print(f"CIDR: {network.cidr}")
print(f"Gateway: {network.gateway}")

network = cloud.networks.get_by_name("my-network")

Configuration Values

Parameter Example Description
cloud "MTNNG_CLOUD_AZ_1" Cloud/Zone name
resource_pool_id "pool-214" Resource pool identifier
availability_zone "Lagos-AZ-1-fd1" Availability zone
security_group "default" Security group (default always exists)
os_external_network_id "public-network-01" External network for floating IP
storage_type 11 Storage type ID

Managing Instances

# List all instances
instances = cloud.instances.list()

# Filter instances
running = cloud.instances.list(status="running")
by_name = cloud.instances.list(name="web-server")

# Get a specific instance
instance = cloud.instances.get(123)
print(f"Name: {instance.name}")
print(f"Status: {instance.status}")
print(f"IP: {instance.primary_ip}")

# Get instance by name
instance = cloud.instances.get_by_name("my-app")

# Instance actions
instance.stop()
instance.start()
instance.restart()

# Or use the resource manager
cloud.instances.stop(123)
cloud.instances.start(123)

# Resize instance
cloud.instances.resize(123, plan_id=6776)  # Upgrade to G2S4

# Delete instance
cloud.instances.delete(123)

# Force delete with volume preservation
cloud.instances.delete(123, force=True, preserve_volumes=True)

Working with Instance Types

# List all instance types
instance_types = cloud.instance_types.list()
for it in instance_types:
    print(f"{it.code}: {it.name} (Layout ID: {it.default_layout_id})")

# Get instance type by code
centos = cloud.instance_types.get_by_code("MTN-CS10")
print(f"ID: {centos.id}")
print(f"Name: {centos.name}")
print(f"Code: {centos.code}")
print(f"Description: {centos.description}")
print(f"Default Layout ID: {centos.default_layout_id}")

# Access layouts
for layout in centos.layouts:
    print(f"  Layout: {layout.id} - {layout.name}")

Error Handling

from mtn_cloud import (
    MTNCloud,
    MTNCloudError,
    AuthenticationError,
    NotFoundError,
    ForbiddenError,
    ValidationError,
    RateLimitError,
    TimeoutError,
)

cloud = MTNCloud(token="xxx")

try:
    instance = cloud.instances.get(99999)
except NotFoundError as e:
    print(f"Instance not found: {e}")
except AuthenticationError as e:
    print(f"Auth failed: {e}")
except ForbiddenError as e:
    print(f"Access denied: {e}")
except ValidationError as e:
    print(f"Invalid request: {e}")
except RateLimitError as e:
    print(f"Rate limited. Retry after: {e.retry_after}s")
except TimeoutError as e:
    print(f"Request timed out: {e}")
except MTNCloudError as e:
    print(f"API error: {e}")

Configuration

Environment Variables

Variable Description Default
MTN_CLOUD_TOKEN API access token -
MTN_CLOUD_URL API base URL https://console.cloud.mtn.ng
MTN_CLOUD_TIMEOUT Request timeout (seconds) 30
MTN_CLOUD_MAX_RETRIES Max retry attempts 3
MTN_CLOUD_VERIFY_SSL Verify SSL certs true

Programmatic Configuration

from mtn_cloud import MTNCloud, MTNCloudConfig

config = MTNCloudConfig(
    token="your-token",
    timeout=60,
    max_retries=5,
    verify_ssl=True,
)

cloud = MTNCloud(config=config)

API Limitations

Endpoint Status Workaround
/api/service-plans ❌ Blocked See Service Plans
/api/zones (Clouds) ❌ Blocked Use MTNNG_CLOUD_AZ_1

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE for details.

This is an unofficial community project. Not affiliated with MTN.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mtn_cloud-0.1.11.tar.gz (34.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mtn_cloud-0.1.11-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

File details

Details for the file mtn_cloud-0.1.11.tar.gz.

File metadata

  • Download URL: mtn_cloud-0.1.11.tar.gz
  • Upload date:
  • Size: 34.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mtn_cloud-0.1.11.tar.gz
Algorithm Hash digest
SHA256 d242978819414741db82d200553968411fbe9349c7722393817c4959de94da10
MD5 5136d01f2e50c4cbf79c5fa11f99ecc4
BLAKE2b-256 645cc463d8c22cb0a0072dfc2fefea56d92bbec129325a974e9b1edb1b0fb941

See more details on using hashes here.

Provenance

The following attestation bundles were made for mtn_cloud-0.1.11.tar.gz:

Publisher: publish.yml on mahveotm/mtn-cloud-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mtn_cloud-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: mtn_cloud-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 40.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mtn_cloud-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 82a28c29b1596477fe33d03d33a877e82029a04ed9b8db39049dea8aee12c800
MD5 92250a8ef4bc96a75033b46a2de1e3fe
BLAKE2b-256 af4fe97d1d58ffb9a39a5ae72bfb8b2ce4f2f6deb1d779ca9f7242c9e9ac6c17

See more details on using hashes here.

Provenance

The following attestation bundles were made for mtn_cloud-0.1.11-py3-none-any.whl:

Publisher: publish.yml on mahveotm/mtn-cloud-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page