Python SDK (Beta)
The Python SDK is an auto-generated client library for the EnergyCAP REST API. It provides typed methods for every API endpoint and handles JSON serialization, so you can work with EnergyCAP data as native Python objects.
Installation
Install from PyPI:
pip install EnergyCapSdk
| Package | EnergyCapSdk |
| Current version | 8.2309.4878 |
| Dependency | msrest >= 0.5.2 |
| Distribution | Universal wheel (py3-none-any) |
Quick Start
1. Create a client and authenticate
from energycap.sdk import EnergyCapApi
# Create the client pointing to your environment
api = EnergyCapApi(base_url="https://app.energycap.com")
# Authenticate with your API key (recommended)
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"
2. Make a request
# Get the first page of meters
meters = api.get_meters(page_size=10, page_number=1)
for meter in meters:
print(f"{meter.meter_id}: {meter.meter_code} — {meter.meter_info}")
Authentication
API key (recommended)
Set the ECI-ApiKey header on the client configuration:
from energycap.sdk import EnergyCapApi
api = EnergyCapApi(base_url="https://app.energycap.com")
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"
See Authentication for how to create and manage API keys.
Credential-based (legacy)
from energycap.sdk import EnergyCapApi, models
api = EnergyCapApi(base_url="https://implement.energycap.com")
# Log in with credentials to get a token
auth_request = models.LoginRequest("datasource", "password", "username")
auth_response = api.login(login_request=auth_request)
# Set the token for subsequent requests
api.config.headers["Authorization"] = "bearer " + auth_response.token
Base URL
Set the base URL to match your organization’s environment:
| Environment | Base URL |
|---|---|
| US East (Production) | https://app.energycap.com |
| US West | https://wce.energycap.com |
| EU | https://app-eu.energycap.com |
| FedRAMP | https://app.fed-energycap.com |
| Implementation | https://implement.energycap.com |
Common Operations
Retrieve a single resource
# Get a specific meter by ID
meter = api.get_meter(meter_id=1234)
print(f"{meter.meter_code}: {meter.meter_info}")
List resources with filters
# Get all electric accounts
accounts = api.get_accounts(filter="commodityCode equals 'ELECTRIC'")
for account in accounts:
print(f"{account.account_id}: {account.account_code}")
See Filters for the full filter syntax.
Create a resource
# Create a new bill
bill_request = models.BillCreateRequest(
account_id=1234,
vendor_id=10,
period_start="2025-01-01",
period_end="2025-01-31",
statement_date="2025-02-05"
)
bill = api.create_bill(body=bill_request)
print(f"Created bill {bill.bill_id}")
Update a resource
# Update an existing account
update_request = models.AccountEditRequest(
account_code="ACCT-001-UPDATED",
account_info="Updated Account Description"
)
account = api.edit_account(account_id=1234, body=update_request)
Delete a resource
api.delete_meter(meter_id=1234)
Pagination
List endpoints return one page of results at a time. Use page_number and page_size parameters to iterate through all records.
Basic iteration
all_meters = []
page = 1
page_size = 500
while True:
meters = api.get_meters(page_size=page_size, page_number=page)
if not meters:
break
all_meters.extend(meters)
# If we got fewer results than page_size, we've reached the last page
if len(meters) < page_size:
break
page += 1
print(f"Retrieved {len(all_meters)} meters")
Using response headers
To access pagination metadata (total pages, total records), use the raw HTTP response:
response = api.get_meters_with_http_info(page_size=500, page_number=1)
meters = response[0] # Response body
status_code = response[1] # HTTP status code
headers = response[2] # Response headers
total_pages = int(headers.get("TotalPages", 1))
total_records = int(headers.get("TotalNumberOfRecords", 0))
print(f"Page 1 of {total_pages} ({total_records} total records)")
See Pagination for more details.
Field Reduction
Reduce response size by requesting only the fields you need:
# Only return meterId, meterCode, and meterInfo
meters = api.get_meters(field="meterId,meterCode,meterInfo")
See Field Reduction for include/exclude modes.
Error Handling
The SDK raises exceptions from the msrest library when the API returns an error:
from msrest.exceptions import HttpOperationError
try:
meter = api.get_meter(meter_id=99999)
except HttpOperationError as e:
print(f"Status: {e.response.status_code}")
print(f"Body: {e.response.text}")
# Common status codes:
# 400 — Bad request (check your parameters)
# 401 — Unauthorized (invalid API key)
# 404 — Resource not found
# 429 — Rate limited (wait and retry)
Handling rate limits
import time
from msrest.exceptions import HttpOperationError
def get_meters_with_retry(api, **kwargs):
try:
return api.get_meters(**kwargs)
except HttpOperationError as e:
if e.response.status_code == 429:
print("Rate limited — waiting 10 seconds...")
time.sleep(10)
return api.get_meters(**kwargs)
raise
Bulk Data Retrieval
Combine pagination, filters, and field reduction for efficient bulk operations:
def get_all_bills_for_account(api, account_id):
"""Retrieve all bills for a given account with minimal fields."""
all_bills = []
page = 1
page_size = 1000
while True:
bills = api.get_bills(
filter=f"accountId equals '{account_id}'",
field="billId,totalCost,totalUse,periodStart,periodEnd",
page_size=page_size,
page_number=page
)
if not bills:
break
all_bills.extend(bills)
if len(bills) < page_size:
break
page += 1
return all_bills
bills = get_all_bills_for_account(api, account_id=1234)
print(f"Found {len(bills)} bills")
for bill in bills:
print(f" Bill {bill.bill_id}: ${bill.total_cost} ({bill.period_start} – {bill.period_end})")
Configuration
Custom timeout
from msrest import Configuration
api = EnergyCapApi(base_url="https://app.energycap.com")
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"
# Set timeout to 5 minutes for large operations
api.config.connection.timeout = 300
Custom session headers
# Add a custom user agent to identify your integration
api.config.headers["User-Agent"] = "MyIntegration/1.0"