Skip to main content

A Python GraphQL client library for Slipper Energy Management

Project description

SlipperPy

A Python GraphQL client library for Slipper Energy Management systems.

Features

  • 🚀 Async/await support with httpx
  • 🔒 Type-safe with Pydantic models
  • 📝 Full GraphQL query and mutation support
  • 🔄 WebSocket subscription support (planned)
  • 🧪 Comprehensive test coverage
  • 📚 Well-documented API
  • ⚡ Energy consumption tracking
  • 💰 Electricity price monitoring
  • 🏠 Home management
  • 📱 Device management

Installation

pip install slipperpy

For development dependencies:

pip install slipperpy[dev]

Quick Start

import asyncio
from slipperpy import SlipperClient

async def main():
    client = SlipperClient("https://api.slipper.no/graphql")
    
    # Step 1: Request SMS verification code
    success = await client.request_sms_code("+47123456789")
    if success:
        print("SMS code sent!")
        
        # Step 2: Get the SMS code from user input
        sms_code = input("Enter SMS code: ")
        
        # Step 3: Login with SMS code
        token = await client.login_with_sms_code("+47123456789", int(sms_code))
        print(f"Logged in successfully!")
    
    # Get current user
    user = await client.get_current_user()
    print(f"Welcome, {user.first_name}!")
    
    # Get all homes
    homes = await client.get_homes()
    for home in homes:
        print(f"Home: {home.name} at {home.street} {home.street_number}")
    
    # Get consumption data for the first home
    if homes:
        from datetime import datetime, timedelta
        end_date = datetime.now()
        start_date = end_date - timedelta(days=7)
        
        consumptions = await client.get_consumptions(
            home_id=homes[0].id,
            start=start_date,
            end=end_date,
            granularity="DAY"
        )
        
        for consumption in consumptions:
            print(f"Date: {consumption.date}, kWh: {consumption.kwh}, Cost: {consumption.cost}")

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

Advanced Usage

Authentication

SMS Login (Primary Method)

client = SlipperClient("https://api.slipper.no/graphql")

# Step 1: Request SMS code
success = await client.request_sms_code("+47123456789")
if success:
    print("SMS code sent to your phone")

# Step 2: Enter the code you received via SMS
sms_code = input("Enter SMS code: ")

# Step 3: Complete login
token = await client.login_with_sms_code("+47123456789", int(sms_code))
print("Logged in successfully!")

Alternative: Combined SMS Method

# Request SMS code
result = await client.login_with_sms("+47123456789")
print(result["message"])  # "SMS code requested"

# Login with SMS code (after receiving it)
result = await client.login_with_sms("+47123456789", code=123456)
if result["success"]:
    print("Logged in!")

Phone and Password Login (if available)

# Only use if your account supports password login
token = await client.login_with_phone_and_password("+47123456789", "password")

Using Existing Token

client = SlipperClient("https://api.slipper.no/graphql")
client.set_auth_token("your-existing-jwt-token")

Home Management

# Get all homes
homes = await client.get_homes()

# Get a specific home
home = await client.get_home("home-id")

# Get archived homes
archived_homes = await client.get_homes(archived=True)

Energy Consumption

from datetime import datetime, timedelta

# Get consumption for the last month
end_date = datetime.now()
start_date = end_date - timedelta(days=30)

consumptions = await client.get_consumptions(
    home_id="your-home-id",
    start=start_date,
    end=end_date,
    granularity="DAY"  # Options: HOUR, DAY, MONTH
)

for consumption in consumptions:
    print(f"Date: {consumption.date}")
    print(f"Consumption: {consumption.kwh} kWh")
    print(f"Cost: {consumption.cost} NOK")
    print(f"Tax: {consumption.tax} NOK")
    print("---")

Electricity Prices

from datetime import datetime, timedelta

# Get electricity prices for tomorrow
start_date = datetime.now() + timedelta(days=1)
end_date = start_date + timedelta(days=1)

prices = await client.get_electricity_prices(
    start=start_date,
    end=end_date,
    granularity="HOUR",
    area="NO1",  # Norwegian price area
    forecast=True
)

for price in prices:
    print(f"Time: {price.date}, Price: {price.price} øre/kWh")

Plan Management

# Get all available electricity plans
plans = await client.get_plans()

# Get plans from a specific provider
plans = await client.get_plans(provider_id="provider-id")

# Get only active plans
active_plans = await client.get_plans(active=True)

for plan in plans:
    print(f"Plan: {plan.name}")
    print(f"Provider: {plan.provider}")
    print(f"Price per kWh: {plan.price_per_kwh}")
    print(f"Fixed fee: {plan.fixed_fee}")

Provider Information

# Get all electricity providers
providers = await client.get_providers()

for provider in providers:
    print(f"Provider: {provider.name}")
    print(f"Website: {provider.website}")
    print(f"Phone: {provider.phone}")

User Management

# Get current user information
user = await client.get_current_user()
print(f"User: {user.first_name} {user.last_name}")
print(f"Email: {user.email}")

# Update user information
success = await client.update_user(
    first_name="New Name",
    email="new.email@example.com"
)

Raw GraphQL Queries

# Execute custom GraphQL queries
query = """
query CustomQuery($homeId: ID!) {
    home(id: $homeId) {
        id
        name
        estimatedYearlyConsumption
        currentPlan {
            name
            pricePerKwh
        }
    }
}
"""

result = await client.execute(query, {"homeId": "your-home-id"})
print(result.data)

Error Handling

from slipperpy.exceptions import GraphQLError, NetworkError, AuthenticationError

try:
    homes = await client.get_homes()
except AuthenticationError:
    print("Authentication failed - please log in")
except NetworkError as e:
    print(f"Network error: {e.message}")
except GraphQLError as e:
    print(f"GraphQL error: {e.message}")

Context Manager

async with SlipperClient("https://api.slipper.no/graphql") as client:
    await client.login_with_phone("+47123456789", "password")
    homes = await client.get_homes()
    # Client is automatically closed when exiting the context

Data Models

The library provides typed Pydantic models for all GraphQL types:

  • HomeType - Represents a home/property
  • UserType - Represents a user account
  • ConsumptionType - Energy consumption data
  • ElectricityPriceType - Electricity price information
  • PlanType - Electricity plans/tariffs
  • ProviderType - Electricity providers
  • DeviceType - User devices (mobile, web, etc.)
  • And many more...

Development

Setup

git clone https://github.com/yourusername/slipperpy.git
cd slipperpy
pip install -e .[dev]

Running Tests

pytest

Code Formatting

black src tests
isort src tests

Type Checking

mypy src/slipperpy

License

MIT License - see LICENSE file for details.

Contributing

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

API Documentation

For complete API documentation, see the GraphQL schema or explore the typed models in the source code.

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

slipperpy-0.1.0.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

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

slipperpy-0.1.0-py3-none-any.whl (16.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for slipperpy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ede4e3ba46f5edf28d30f444186c47b2b4d51105162a88cc76cd9d3647f5a7bf
MD5 0a69bb83350e89392bb67c84727b481f
BLAKE2b-256 0d44e14b088af222ea2a7d415fce84e668edb53badfd39373d79467b7f3fcb6a

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for slipperpy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d718c79a1a5f9a9b0dc9eff4064fdecd9ed15fddb75bccd1586be1a24915ec5a
MD5 ad351a427bd364898e6e72a93f2a03c1
BLAKE2b-256 8e27e7f2e20f277ba0f9c4d078e5d7f1a0d1b3b0e25f9f0452df1d4f32b00cb9

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