Skip to main content

Python API client for NinjaRMM (NinjaOne)

Project description

NinjaPy - Python API Client for NinjaRMM (NinjaOne)

PyPI version Python Support License: MIT

A comprehensive Python API client for NinjaRMM (NinjaOne) with support for all major endpoints including device management, organization management, policy control, and more.

Features

  • Complete API Coverage: ~70% of NinjaRMM API endpoints implemented with ongoing development
  • OAuth2 Authentication: Secure token-based authentication with automatic refresh
  • Type Safety: Full type hints and runtime type checking
  • Error Handling: Comprehensive exception handling with detailed error messages
  • Rate Limiting: Built-in retry logic and rate limit handling
  • Async Ready: Designed with future async support in mind

Installation

Install NinjaPy using pip:

pip install ninjapy

For development features:

pip install ninjapy[dev]

Quick Start

Authentication Setup

First, you'll need to set up OAuth2 credentials in your NinjaRMM instance:

  1. Log into your NinjaOne dashboard
  2. Go to AdministrationAppsAPI
  3. Create a new API Application
  4. Note down your Client ID, Client Secret, and Token URL
  5. Set appropriate scopes: monitoring, management, control

Basic Usage

from ninjapy import NinjaRMMClient

# Initialize the client
client = NinjaRMMClient(
    token_url="https://app.ninjarmm.com/oauth/token",
    client_id="your_client_id",
    client_secret="your_client_secret", 
    scope="monitoring management control"
)

# Get all organizations
organizations = client.get_organizations()
print(f"Found {len(organizations)} organizations")

# Get devices for a specific organization
if organizations:
    org_id = organizations[0]["id"]
    devices = client.get_organization_devices(org_id)
    print(f"Organization {org_id} has {len(devices)} devices")

# Get device details
if devices:
    device_id = devices[0]["id"]
    device_details = client.get_device(device_id)
    print(f"Device: {device_details['displayName']}")
    
    # Get device alerts
    alerts = client.get_device_alerts(device_id)
    if alerts:
        print(f"Device has {len(alerts)} active alerts")

Context Manager Usage

# Recommended: Use as a context manager for automatic cleanup
with NinjaRMMClient(
    token_url="https://app.ninjarmm.com/oauth/token",
    client_id="your_client_id", 
    client_secret="your_client_secret",
    scope="monitoring management control"
) as client:
    # Perform operations
    organizations = client.get_organizations()
    
    # Client will automatically close when exiting the context

Device Management

# Search for devices
search_results = client.search_devices("server", page_size=50)

# Get device activities
activities = client.get_device_activities(
    device_id=123,
    start_time=1640995200,  # Unix timestamp
    activity_type="SCRIPT_EXECUTION"
)

# Reboot a device
client.reboot_device(device_id=123, mode="GRACEFUL")

# Enable maintenance mode
client.enable_maintenance_mode(device_id=123, duration=3600)  # 1 hour

# Run a script on a device
job = client.run_device_script(
    device_id=123,
    script_id=456,
    parameters={"param1": "value1"}
)

Organization Management

# Create a new organization
new_org = client.create_organization(
    name="New Client Organization",
    description="Created via API",
    locations=[{
        "name": "Main Office",
        "address": "123 Business St, City, State"
    }]
)

# Update organization settings
client.update_organization(
    org_id=new_org["id"],
    name="Updated Organization Name",
    node_approval_mode="MANUAL"
)

# Get organization custom fields
custom_fields = client.get_organization_custom_fields(new_org["id"])

Policy Management

# List all policies
policies = client.list_policies()

# Create a custom field policy condition
condition = client.create_custom_fields_policy_condition(
    policy_id=123,
    display_name="Server Memory Check",
    match_all=[{
        "fieldName": "totalMemory",
        "operator": "GREATER_THAN", 
        "value": "8192"
    }]
)

Error Handling

from ninjapy.exceptions import NinjaRMMAuthError, NinjaRMMAPIError

try:
    organizations = client.get_organizations()
except NinjaRMMAuthError:
    print("Authentication failed - check your credentials")
except NinjaRMMAPIError as e:
    print(f"API error: {e.message} (Status: {e.status_code})")
    print(f"Details: {e.details}")
except Exception as e:
    print(f"Unexpected error: {e}")

API Coverage

✅ Fully Implemented (70%+)

  • Organizations: CRUD operations, locations, policies, custom fields
  • Devices: CRUD, maintenance, patch management, scripting, custom fields
  • Policies: Conditions, overrides, assignments
  • Queries: Comprehensive reporting endpoints
  • Activities: Device and system activity logs
  • Alerts: Alert management and reset functionality
  • Webhooks: Configuration and management
  • Document Management: Basic document operations

🚧 Partially Implemented

  • Ticketing: Basic ticket operations (creation, limited management)
  • Backup Management: Usage reporting, basic job querying

⏳ Planned for Future Releases

  • Tag Management: Asset tagging system
  • Knowledge Base: Article and folder management
  • Checklists: Template and organization checklist management
  • Related Items: Entity relationships and attachments
  • Vulnerability Scanning: Scan groups and data management
  • Advanced Backup: Integrity checks, comprehensive job management

Configuration

Environment Variables

You can configure the client using environment variables, which is the recommended approach for production applications and keeps sensitive credentials out of your code.

Quick Setup with .env Files

  1. Copy the example file:

    cp .env.example .env
    
  2. Edit .env with your credentials:

    # NinjaRMM API Configuration
    NINJA_TOKEN_URL=https://app.ninjarmm.com/oauth/token
    NINJA_CLIENT_ID=your_actual_client_id
    NINJA_CLIENT_SECRET=your_actual_client_secret
    NINJA_SCOPE=monitoring management control
    NINJA_BASE_URL=https://api.ninjarmm.com
    
  3. Use in your code:

    import os
    from ninjapy import NinjaRMMClient
    
    # Option 1: Use python-dotenv to automatically load .env file
    from dotenv import load_dotenv
    load_dotenv()
    
    client = NinjaRMMClient(
        token_url=os.getenv("NINJA_TOKEN_URL"),
        client_id=os.getenv("NINJA_CLIENT_ID"), 
        client_secret=os.getenv("NINJA_CLIENT_SECRET"),
        scope=os.getenv("NINJA_SCOPE"),
        base_url=os.getenv("NINJA_BASE_URL")
    )
    
    # Option 2: Direct environment variables (without .env file)
    # Set via shell: export NINJA_CLIENT_ID="your_id"
    client = NinjaRMMClient(
        token_url=os.getenv("NINJA_TOKEN_URL"),
        client_id=os.getenv("NINJA_CLIENT_ID"),
        client_secret=os.getenv("NINJA_CLIENT_SECRET"),
        scope=os.getenv("NINJA_SCOPE", "monitoring management control")
    )
    
  4. Run the example:

    # Install optional dependency for .env support
    pip install python-dotenv
    
    # Run the example script
    python example_with_env.py
    

Environment Variables Reference

Variable Required Description Example
NINJA_TOKEN_URL ✅ Yes OAuth2 token endpoint https://app.ninjarmm.com/oauth/token
NINJA_CLIENT_ID ✅ Yes OAuth2 client ID from NinjaRMM Admin > Apps > API abc123...
NINJA_CLIENT_SECRET ✅ Yes OAuth2 client secret from NinjaRMM Admin > Apps > API def456...
NINJA_SCOPE ✅ Yes Space-separated OAuth2 scopes monitoring management control
NINJA_BASE_URL ❌ No API base URL (defaults to US region) https://api.ninjarmm.com

Regional Endpoints

🇺🇸 United States (Default):

  • Token URL: https://app.ninjarmm.com/oauth/token
  • Base URL: https://api.ninjarmm.com

🇪🇺 Europe:

  • Token URL: https://eu.ninjarmm.com/oauth/token
  • Base URL: https://eu-api.ninjarmm.com

🌊 Oceania:

  • Token URL: https://oc.ninjarmm.com/oauth/token
  • Base URL: https://oc-api.ninjarmm.com

Security Note: Never commit your .env file to version control! The .gitignore file already excludes it.

Custom Base URL

For different NinjaRMM instances or API versions:

client = NinjaRMMClient(
    token_url="https://your-instance.ninjarmm.com/oauth/token",
    client_id="your_client_id",
    client_secret="your_client_secret",
    scope="monitoring management control",
    base_url="https://your-instance.ninjarmm.com"  # Custom base URL
)

Advanced Usage

Pagination

Many endpoints support pagination. Use the built-in iterator for easy handling:

# Iterate through all organizations automatically
for org in client.iter_organizations(page_size=100):
    print(f"Processing organization: {org['name']}")
    
    # Process devices for each organization
    devices = client.get_organization_devices(org["id"])
    for device in devices:
        print(f"  - Device: {device['displayName']}")

Filtering and Querying

# Use device filters for targeted queries
windows_servers = client.get_devices(
    org_filter="organization_id=123",
    expand="references"  # Include detailed reference data
)

# Query specific device information
patch_data = client.query_os_patches(
    device_filter="node_class=WINDOWS_SERVER",
    status="PENDING",
    page_size=50
)

Development

Setting up for Development

# Clone the repository
git clone https://github.com/yourusername/ninjapy.git
cd ninjapy

# Install in development mode
pip install -e .[dev]

# Run tests
pytest

# Run linting
black ninjapy/
flake8 ninjapy/
mypy ninjapy/

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=ninjapy --cov-report=html

# Run specific test files
pytest tests/test_auth.py
pytest tests/test_client.py

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Disclaimer

This is an unofficial Python client for the NinjaRMM (NinjaOne) API. It is not affiliated with, endorsed by, or officially connected to NinjaRMM or NinjaOne in any way.

Support

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

ninjapy-0.1.0.tar.gz (31.5 kB view details)

Uploaded Source

Built Distribution

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

ninjapy-0.1.0-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file ninjapy-0.1.0.tar.gz.

File metadata

  • Download URL: ninjapy-0.1.0.tar.gz
  • Upload date:
  • Size: 31.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for ninjapy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0ac4afc89368a82cde61ac50d99b1fd9d21e232aacbfe9f1403a474af11e6fac
MD5 42a8ce581f4f0d223bac264f69916082
BLAKE2b-256 c7862626e74ef98805638b77b3cc97624b461c76f55ab1cb80cc2fa051e6f360

See more details on using hashes here.

File details

Details for the file ninjapy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ninjapy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for ninjapy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5534c2962c45961eb2b25d6109c42e0d46a5dbcca8d60a86a5c8da6f9bfebf01
MD5 70786fd7c4deae7e8cea63705dd45a92
BLAKE2b-256 3f939170d5f170824ab8a928d604ca2c0f289ca34ad150b7dc1cb52b138e7264

See more details on using hashes here.

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