Metadata-Version: 2.4
Name: py-superops
Version: 0.2.9
Summary: Python client library for the SuperOps GraphQL API with async support, type safety, and comprehensive error handling
Project-URL: Homepage, https://github.com/asachs01/py-superops
Project-URL: Documentation, https://py-superops.readthedocs.io
Project-URL: Repository, https://github.com/asachs01/py-superops.git
Project-URL: Issues, https://github.com/asachs01/py-superops/issues
Project-URL: Changelog, https://github.com/asachs01/py-superops/blob/main/CHANGELOG.md
Author-email: Aaron Sachs <aaron@wyre.com>
Maintainer-email: Aaron Sachs <aaron@wyre.com>
License: MIT
License-File: LICENSE
Keywords: api,async,client-library,graphql,msp,psa,rmm,superops
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Systems Administration
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: aiofiles<24.0.0,>=23.0.0
Requires-Dist: aiohttp<4.0.0,>=3.8.0
Requires-Dist: click<9.0.0,>=8.0.0
Requires-Dist: httpx<1.0.0,>=0.24.0
Requires-Dist: pydantic-settings<3.0.0,>=2.0.0
Requires-Dist: pydantic<3.0.0,>=2.0.0
Requires-Dist: rich<14.0.0,>=13.0.0
Requires-Dist: typing-extensions>=4.0.0; python_version < '3.10'
Provides-Extra: dev
Requires-Dist: bandit[toml]>=1.7.0; extra == 'dev'
Requires-Dist: black>=22.0.0; extra == 'dev'
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: cyclonedx-bom>=4.0.0; extra == 'dev'
Requires-Dist: flake8-bandit>=4.1.0; extra == 'dev'
Requires-Dist: flake8-bugbear>=23.0.0; extra == 'dev'
Requires-Dist: flake8-comprehensions>=3.14.0; extra == 'dev'
Requires-Dist: flake8-docstrings>=1.7.0; extra == 'dev'
Requires-Dist: flake8-pytest-style>=1.7.0; extra == 'dev'
Requires-Dist: flake8-simplify>=0.21.0; extra == 'dev'
Requires-Dist: flake8>=5.0.0; extra == 'dev'
Requires-Dist: isort>=5.12.0; extra == 'dev'
Requires-Dist: licensecheck>=2023.1.1; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pip-audit>=2.6.0; extra == 'dev'
Requires-Dist: pip-licenses>=4.3.0; extra == 'dev'
Requires-Dist: pre-commit>=2.20.0; extra == 'dev'
Requires-Dist: pydocstyle[toml]>=6.3.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: python-semantic-release>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.20.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: safety>=3.0.0; extra == 'dev'
Requires-Dist: semgrep>=1.45.0; extra == 'dev'
Requires-Dist: tox>=4.0.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: myst-parser>=0.18.0; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints>=1.19.0; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == 'docs'
Requires-Dist: sphinx>=5.0.0; extra == 'docs'
Provides-Extra: examples
Requires-Dist: aiofiles>=22.1.0; extra == 'examples'
Requires-Dist: asyncio-mqtt>=0.13.0; extra == 'examples'
Requires-Dist: rich>=13.0.0; extra == 'examples'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0.0; extra == 'yaml'
Description-Content-Type: text/markdown

# py-superops

Python client library for the SuperOps GraphQL API.

## Overview

This package provides a comprehensive Python SDK for interacting with the SuperOps GraphQL API, featuring async/await support, comprehensive error handling, rate limiting, and type safety.

## Features

- **Async/await support** for high-performance applications
- **Comprehensive error handling** with custom exception hierarchy
- **Built-in rate limiting** and retry logic
- **Type safety** with full type hint support
- **Configuration management** with environment variable support
- **Authentication handling** with token validation
- **Connection pooling** and resource management

## Installation

```bash
pip install py-superops
```

## Quick Start

### Basic Usage

```python
import asyncio
from py_superops import SuperOpsClient, SuperOpsConfig

async def main():
    # Create configuration
    config = SuperOpsConfig(
        api_key="your-api-key",
        base_url="https://api.superops.com/v1"
    )

    # Create and use the client
    async with SuperOpsClient(config) as client:
        # Test connection
        connection_info = await client.test_connection()
        print(f"Connected: {connection_info['connected']}")

        # Execute a query
        query = '''
        query GetClients {
            clients {
                id
                name
                email
            }
        }
        '''

        response = await client.execute_query(query)
        clients = response['data']['clients']

        for client in clients:
            print(f"Client: {client['name']} ({client['email']})")

if __name__ == "__main__":
    asyncio.run(main())
```

### Configuration from Environment

```python
import os
from py_superops import create_client

# Set environment variable
os.environ["SUPEROPS_API_KEY"] = "your-api-key"

# Create client from environment
client = create_client()
```

### Advanced Configuration

```python
from py_superops import SuperOpsConfig, SuperOpsClient

config = SuperOpsConfig(
    api_key="your-api-key",
    base_url="https://api.superops.com/v1",
    timeout=60.0,
    max_retries=5,
    rate_limit_per_minute=120,
    enable_caching=True,
    cache_ttl=600,
    debug=True
)

async with SuperOpsClient(config) as client:
    # Your code here
    pass
```

## Configuration

The client can be configured through multiple methods:

1. **Direct instantiation**
2. **Environment variables** (prefixed with `SUPEROPS_`)
3. **Configuration files** (JSON or YAML)

### Environment Variables

- `SUPEROPS_API_KEY` - Your SuperOps API key (required)
- `SUPEROPS_BASE_URL` - API base URL (default: https://api.superops.com/v1)
- `SUPEROPS_TIMEOUT` - Request timeout in seconds (default: 30.0)
- `SUPEROPS_MAX_RETRIES` - Maximum request retries (default: 3)
- `SUPEROPS_RATE_LIMIT_PER_MINUTE` - Rate limit (default: 60)
- `SUPEROPS_DEBUG` - Enable debug mode (default: false)

### Configuration File

```yaml
# superops.yaml
api_key: "your-api-key"
base_url: "https://api.superops.com/v1"
timeout: 30.0
max_retries: 3
rate_limit_per_minute: 60
enable_caching: true
cache_ttl: 300
debug: false
```

```python
from py_superops import SuperOpsConfig

config = SuperOpsConfig.from_file("superops.yaml")
```

## Error Handling

The library provides a comprehensive exception hierarchy:

```python
from py_superops import (
    SuperOpsError,
    SuperOpsAPIError,
    SuperOpsAuthenticationError,
    SuperOpsRateLimitError,
    SuperOpsNetworkError,
    SuperOpsValidationError,
)

try:
    response = await client.execute_query(query)
except SuperOpsAuthenticationError:
    print("Authentication failed - check your API key")
except SuperOpsRateLimitError as e:
    print(f"Rate limit exceeded - retry after {e.retry_after} seconds")
except SuperOpsAPIError as e:
    print(f"API error: {e.message} (status: {e.status_code})")
except SuperOpsNetworkError:
    print("Network error - check your connection")
```

## GraphQL Operations

### Queries

```python
query = '''
query GetClients($limit: Int) {
    clients(limit: $limit) {
        id
        name
        email
        sites {
            id
            name
        }
    }
}
'''

variables = {"limit": 10}
response = await client.execute_query(query, variables=variables)
```

### Mutations

```python
mutation = '''
mutation CreateClient($input: ClientInput!) {
    createClient(input: $input) {
        id
        name
        email
    }
}
'''

variables = {
    "input": {
        "name": "New Client",
        "email": "client@example.com"
    }
}

response = await client.execute_mutation(mutation, variables=variables)
```

## Development

### Requirements

- Python 3.8+
- httpx
- pydantic
- pydantic-settings

### Optional Dependencies

- PyYAML (for YAML configuration files)

### Testing

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=py_superops --cov-report=html
```

### Code Quality

```bash
# Format code
black src/ tests/

# Sort imports
isort src/ tests/

# Type checking
mypy src/

# Linting
flake8 src/ tests/
```

## API Documentation

### SuperOpsClient

Main client class for interacting with the SuperOps API.

#### Methods

- `execute_query(query, variables=None, operation_name=None)` - Execute a GraphQL query
- `execute_mutation(mutation, variables=None, operation_name=None)` - Execute a GraphQL mutation
- `test_connection()` - Test API connection and authentication
- `get_schema()` - Get GraphQL schema information
- `close()` - Close HTTP client connections

### SuperOpsConfig

Configuration class for the SuperOps client.

#### Class Methods

- `from_env()` - Load configuration from environment variables
- `from_file(path)` - Load configuration from file

#### Methods

- `validate_config()` - Validate current configuration
- `get_headers()` - Get HTTP headers for requests
- `is_us_datacenter()` - Check if using US datacenter
- `is_eu_datacenter()` - Check if using EU datacenter

### Convenience Functions

- `create_client(**kwargs)` - Create client with minimal configuration
- `get_version()` - Get package version
- `get_package_info()` - Get package metadata

## License

MIT License - see LICENSE file for details.

## Support

For issues and questions:

- GitHub Issues: https://github.com/superops/py-superops/issues
- Documentation: https://py-superops.readthedocs.io
- SuperOps Support: https://support.superops.com

## Changelog

See CHANGELOG.md for version history and changes.
