or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/python-libmaas@0.6.x

docs

index.md
tile.json

tessl/pypi-python-libmaas

tessl install tessl/pypi-python-libmaas@0.6.0

Python client library for MAAS 2.0+ with sync/async support, providing machine provisioning, network management, and storage configuration.

connection.mddocs/reference/

Connection and Authentication

Establish connections to MAAS servers using various authentication methods and profile-based configuration management.

Capabilities

API Key Authentication

Connect to MAAS server using API key authentication for programmatic access.

from maas.client import connect

def connect(url: str, *, apikey: str | None = None, insecure: bool = False) -> Client:
    """
    Connect to MAAS server using API key authentication.

    Parameters:
        url (str): MAAS server URL ending with /MAAS/ (e.g., 'http://maas.example.com:5240/MAAS/')
        apikey (str, optional): API key in format 'consumer_key:token_key:token_secret'.
                                If not provided, uses default profile.
        insecure (bool, optional): If True, disables SSL certificate verification. Default: False

    Returns:
        Client: High-level client facade object for accessing MAAS resources

    Raises:
        MAASException: If connection fails or URL is invalid
        ConnectError: If server is unreachable or URL is malformed
        
    Note:
        Automatically adapts to execution context (sync/async).
        In async context, returns a coroutine that must be awaited.
    """

Usage:

from maas.client import connect

# Connect with explicit API key
client = connect(
    'http://maas.example.com:5240/MAAS/',
    apikey='consumer_key:token_key:token_secret'
)

# Connect using default profile (no apikey parameter)
client = connect('http://maas.example.com:5240/MAAS/')

# Connect with insecure SSL (for self-signed certificates)
client = connect(
    'https://maas.example.com:5240/MAAS/',
    apikey='key',
    insecure=True
)

Username/Password Authentication

Connect to MAAS server using username and password credentials.

from maas.client import login

def login(url: str, *, username: str | None = None, password: str | None = None, insecure: bool = False) -> Client:
    """
    Connect to MAAS server using username/password authentication.

    Parameters:
        url (str): MAAS server URL ending with /MAAS/
        username (str, optional): MAAS username. If not provided, prompts interactively.
        password (str, optional): MAAS password. If not provided, prompts interactively.
        insecure (bool, optional): If True, disables SSL certificate verification. Default: False

    Returns:
        Client: High-level client facade object for accessing MAAS resources

    Raises:
        MAASException: If authentication fails or URL is invalid
        LoginError: If credentials are invalid
        LoginNotSupported: If server doesn't support password authentication
        PasswordWithoutUsername: If password provided without username
        UsernameWithoutPassword: If username provided without password
        
    Note:
        Automatically adapts to execution context (sync/async).
        In async context, returns a coroutine that must be awaited.
    """

Usage:

from maas.client import login

# Login with explicit credentials
client = login(
    'http://maas.example.com:5240/MAAS/',
    username='admin',
    password='password'
)

# Login with interactive prompts (no username/password provided)
client = login('http://maas.example.com:5240/MAAS/')

Profile-Based Configuration

Store and manage connection profiles for easy access to multiple MAAS servers.

from maas.client.utils.profiles import Profile, ProfileStore, ProfileNotFound

class Profile:
    """
    Configuration profile for MAAS connection.

    Attributes:
        name (str): Profile name
        url (str): MAAS server URL
        credentials (Credentials): API credentials
        description (str): Optional profile description
    """
    def __init__(self, name: str, url: str, credentials: Credentials | None = None, description: str | None = None) -> None: ...

class ProfileStore:
    """Manage storage and retrieval of connection profiles."""

    def load(self, name: str) -> Profile:
        """
        Load profile by name.

        Args:
            name (str): Profile name

        Returns:
            Profile: Loaded profile

        Raises:
            ProfileNotFound: If profile doesn't exist
        """

    def save(self, profile: Profile) -> None:
        """
        Save profile to storage.

        Args:
            profile (Profile): Profile to save
        """

    def delete(self, name: str) -> None:
        """
        Delete profile by name.

        Args:
            name (str): Profile name to delete

        Raises:
            ProfileNotFound: If profile doesn't exist
        """

    def list(self) -> list[str]:
        """
        List all stored profiles.

        Returns:
            list[str]: List of profile names
        """

    def open(self) -> dict:
        """
        Open profile database for editing.

        Returns:
            dict: Profile database
        """

class ProfileNotFound(Exception):
    """Raised when requested profile is not found."""

Connecting with Profiles

Use stored profiles to create API sessions without re-entering credentials.

from maas.client.bones import SessionAPI

class SessionAPI:
    @classmethod
    def fromProfile(cls, profile: Profile) -> SessionAPI:
        """
        Create SessionAPI from a Profile object.

        Args:
            profile (Profile): Profile containing URL, credentials, and description

        Returns:
            SessionAPI: Configured session API instance
        """

    @classmethod
    def fromProfileName(cls, name: str) -> SessionAPI:
        """
        Create SessionAPI from a profile name.

        Args:
            name (str): Name of stored profile to load

        Returns:
            SessionAPI: Configured session API instance

        Raises:
            ProfileNotFound: If profile with given name doesn't exist
        """

Usage:

from maas.client.utils.profiles import Profile, ProfileStore
from maas.client.utils.creds import Credentials
from maas.client.bones import SessionAPI
from maas.client.viscera import Origin

# Create credentials
creds = Credentials(
    consumer_key='key',
    token_key='token',
    token_secret='secret'
)

# Create and save profile
profile = Profile(
    name='production',
    url='http://maas.example.com:5240/MAAS/',
    credentials=creds,
    description='Production MAAS server'
)

store = ProfileStore()
store.save(profile)

# Method 1: Load profile and connect using SessionAPI
loaded_profile = store.load('production')
session = SessionAPI.fromProfile(loaded_profile)

# Method 2: Connect directly by profile name
session = SessionAPI.fromProfileName('production')

# Use with Viscera API (Origin also supports these methods)
origin = Origin.fromProfile(loaded_profile)
# or
origin = Origin.fromProfileName('production')

# Access resources
machines = await origin.Machines.read()
for machine in machines:
    print(machine.hostname)

Credentials Management

Handle OAuth credentials for MAAS API authentication.

from collections import namedtuple
from maas.client.utils.creds import Credentials

Credentials = namedtuple('Credentials', ['consumer_key', 'token_key', 'token_secret'])
from maas.client.utils.auth import obtain_credentials, try_getpass

def obtain_credentials(credentials: str) -> Credentials:
    """
    Parse credentials from string format.

    Args:
        credentials (str): Credentials string in format 'consumer_key:token_key:token_secret'

    Returns:
        Credentials: Parsed credentials namedtuple

    Raises:
        ValueError: If credentials string is malformed
    """

def try_getpass(prompt: str) -> str:
    """
    Safely get password from user with fallback to standard input.

    Args:
        prompt (str): Password prompt text

    Returns:
        str: Password entered by user
    """

Usage:

from maas.client.utils.creds import Credentials
from maas.client.utils.auth import obtain_credentials

# Create credentials directly
creds = Credentials(
    consumer_key='my_consumer_key',
    token_key='my_token_key',
    token_secret='my_token_secret'
)

# Parse from string
creds = obtain_credentials('consumer_key:token_key:token_secret')

# Access credential components
print(creds.consumer_key)
print(creds.token_key)
print(creds.token_secret)

Async Connection Methods

All connection methods support async/await when used in async contexts.

import asyncio
from maas.client import connect, login

async def connect_async() -> Client:
    """Connect to MAAS asynchronously."""
    # Async connection
    client = await connect('http://maas.example.com:5240/MAAS/', apikey='key')
    return client

async def login_async() -> Client:
    """Login to MAAS asynchronously."""
    # Async login
    client = await login('http://maas.example.com:5240/MAAS/', username='admin', password='pass')
    return client

# Run async
client = asyncio.run(connect_async())

URL Validation

Utility functions for validating and normalizing MAAS API URLs.

from maas.client.utils import api_url, ensure_trailing_slash

def api_url(string: str) -> str:
    """
    Validate and normalize MAAS API URL.

    Args:
        string (str): URL to validate

    Returns:
        str: Normalized URL

    Raises:
        ValueError: If URL is invalid
    """

def ensure_trailing_slash(string: str) -> str:
    """
    Ensure string ends with trailing slash.

    Args:
        string (str): String to process

    Returns:
        str: String with trailing slash
    """

OAuth Signing

Low-level OAuth request signing for direct API calls.

from maas.client.utils import OAuthSigner, sign

class OAuthSigner:
    """OAuth 1.0a request signer for MAAS API."""
    
    def __init__(self, consumer_key: str, token_key: str, token_secret: str) -> None: ...
    
    def sign(self, url: str, method: str = 'GET') -> dict: ...

def sign(uri: str, headers: dict, credentials: Credentials) -> dict:
    """
    Sign HTTP request with OAuth credentials.

    Args:
        uri (str): Request URI
        headers (dict): HTTP headers to sign
        credentials (Credentials): OAuth credentials

    Returns:
        dict: Signed headers
    """

Error Handling

Connection Errors

from maas.client import connect
from maas.client.bones.helpers import ConnectError, RemoteError

try:
    client = connect('http://maas.example.com:5240/MAAS/', apikey='key')
except ConnectError as e:
    print(f"Connection failed: {e}")
    # Possible causes:
    # - Invalid URL format
    # - Network connectivity issues
    # - Server not responding
except RemoteError as e:
    print(f"Server error (status {e.status}): {e.content}")
    # Server returned error response
    # Check API key validity

Authentication Errors

from maas.client import login
from maas.client.bones.helpers import (
    LoginError,
    LoginNotSupported,
    PasswordWithoutUsername,
    UsernameWithoutPassword
)

try:
    client = login('http://maas.example.com:5240/MAAS/', username='admin', password='pass')
except LoginNotSupported:
    print("Server requires API key authentication")
    # Use connect() with API key instead
except PasswordWithoutUsername:
    print("Password provided without username")
except UsernameWithoutPassword:
    print("Username provided without password")
except LoginError as e:
    print(f"Login failed: {e}")
    # Check credentials are correct

Types

from collections import namedtuple

Credentials = namedtuple('Credentials', ['consumer_key', 'token_key', 'token_secret'])