Python SDK client for the Daly Energy REST API
Project description
daly-energy
Python SDK client for the Daly Energy REST API.
Installation
pip install daly-energy
Install the query helpers with pandas support when you want DataFrame input:
pip install "daly-energy[query]"
Quick Start
from dalysdk import DalyClient
client = DalyClient(
workspace_api_key="wk_...",
user_api_key="uk_...",
)
# List locations
locations = client.locations.list()
# Create a project
project = client.projects.create({
"name": "My Solar Project",
"location_index": 1,
})
# Always close when done
client.close()
Or use as a context manager:
with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
projects = client.projects.list()
Saved Energy Model Edit/Rerun
with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
saved = client.energy_models.get_with_inputs(56)
edited = dict(saved["inputs"])
edited["output"] = {"name": "Variant A - Updated"}
client.energy_models.update(56, edited)
queued = client.energy_models.run_saved(56, async_mode=True)
assert queued["energyModelId"] == 56
run_saved() reruns the same saved energy-model row in place rather than
creating a new one. If you need different output controls for the rerun, update
the saved model first and then call run_saved(). The rerun endpoint does not
take a request body override.
Energy-model submissions are async-only. The SDK submits create() and
run_saved() requests as accepted jobs and treats any 2xx response,
including 202 Accepted, as success. Poll client.tasks for completion if
you need finished results.
Energy Model Query Workflows
For modern SDK usage, use client.energy_models.query(...) when you want the
SDK to normalize an inline weather dataset into the canonical API
weatherData payload. Use client.energy_models.create(...) when you already
have the full API request body prepared.
with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
accepted = client.energy_models.query(
{
"locationId": 9,
"blocks": [
{
"name": "Block A",
"inverterDefinition": {"inverterIndex": 1},
"moduleDefinition": {"moduleIndex": 1},
"surfaceDefinition": {
"surfaceType": "fixed_tilt",
"surfaceTilt": 20,
"surfaceAzimuth": 180,
},
"moduleStringingDefinition": {
"modulesPerString": 20,
"stringsPerInverter": 5,
},
}
],
},
[
{
"timestamp": "2024-01-01T00:00:00Z",
"ghi": 0.0,
"dhi": 0.0,
"temp": 15.0,
"wind_speed": 1.2,
},
{
"timestamp": "2024-01-01T01:00:00Z",
"ghi": 10.2,
"dhi": 8.3,
"temp": 14.8,
"wind_speed": 1.1,
},
],
time_step_format="utc",
)
query() accepts weather rows keyed by date, timestamp, or datetime and
normalizes them to the API's canonical weatherData.date array before
submission. If you want to inspect the exact payload before sending it, use
client.energy_models.build_query_payload(...).
If you already have the final API payload, submit it directly:
with DalyClient(workspace_api_key="wk_...", user_api_key="uk_...") as client:
result = client.energy_models.create(
{
"location": {
"latitude": 33.4,
"longitude": -112.0,
"elevation": 337,
"timeZone": -7,
},
"weatherData": {
"date": [
1704067200000,
1704070800000,
1704074400000,
],
"ghi": [0.0, 0.0, 10.2],
"dhi": [0.0, 0.0, 8.3],
"windSpeed": [1.2, 1.1, 0.8],
"temperature": [15.0, 14.8, 14.6],
},
"blocks": [
{
"name": "Block A",
"inverterDefinition": {"inverterIndex": 1},
"moduleDefinition": {"moduleIndex": 1},
"surfaceDefinition": {
"surfaceType": "fixed_tilt",
"surfaceTilt": 20,
"surfaceAzimuth": 180,
},
"moduleStringingDefinition": {
"modulesPerString": 20,
"stringsPerInverter": 5,
},
}
],
},
async_mode=True,
)
Output controls and returned time-series
Use the canonical API output fields directly in the payload you pass to
client.energy_models.create(...):
output.timeSeriesrequests plant-leveltimeSeriesoutput.fullTimeSeriesrequests extended plant-level seriesoutput.blockResultsrequestsblockTimeSeriesoutput.blockIndexfilters the returnedblockTimeSeriesmap to one zero-based blockoutput.lossBreakdownTimestampsimplies block-level results and adds timestamped loss detail underblockTimeSeries[<blockIndex>].lossBreakdownoutput.irradianceLossDetailadds annual detail underlosses.irradianceLossDetail
Important behavior:
output.blockIndexfilters the returned response; it does not trim the submittedblocksarray down to single-block execution.- Returned
blockTimeSerieskeys preserve the API's original zero-based block numbering, including filtered single-block responses. - If you need to change output controls for
run_saved(), update the saved row first withclient.energy_models.update(...). - The SDK no longer assumes inline sync completion for these submissions; use task polling if your workflow needs final outputs.
Legacy query adapters (compatibility only)
client.energy_models.create_legacy_query(...)client.run_energy_model(...)LegacyEnergyModel.run_query(...)
These helpers are provided only for backward compatibility. They preserve the
old block-query controls (block_results, block_results_index) by
translating them into legacy request fields while keeping the full model block
list intact. They are not the recommended modern SDK workflow.
Legacy block-query behavior now follows the current API contract:
block_results_indexmaps to deprecated selected-block compatibility fields- the API treats that selection as filtered
blockTimeSeriesoutput, not reduced execution scope - returned block keys still use the original zero-based block indexes
- compatibility inputs such as
run_async,block_results, andblock_results_indexremain accepted, but they do not restore inline sync execution semantics
LegacyEnergyModel.run_query(...) also keeps legacy method signatures for
compatibility, but it does not apply date/time shaping from
start_date, end_date, or time_step_format; those arguments are accepted
and ignored.
Migration note
If you are migrating from older legacy query code:
- Prefer direct
client.energy_models.create(...)calls with explicit, complete request payloads. - Keep using
LegacyEnergyModel.run_query(...)only as a temporary bridge while removing legacy block-query assumptions. - Do not assume
LegacyEnergyModel.run_query(...)reproduces historical date-window query behavior; validate payload shaping in your own code before request submission.
Resources
The client exposes the following resource namespaces:
client.locations— Location managementclient.projects— Project CRUDclient.modules— PV module libraryclient.inverters— Inverter libraryclient.energy_models— Energy model runsclient.shading_scenes— 3D shading analysisclient.weather_data— Weather data managementclient.tasks— Async task trackingclient.workflows— Multi-step workflow orchestrationclient.workspaces— Workspace management
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file daly_energy-2.0.0.tar.gz.
File metadata
- Download URL: daly_energy-2.0.0.tar.gz
- Upload date:
- Size: 35.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74d477a47a3a80bb4aa484440af6b734de061a6ae2c344eb98a57e97fc6094bf
|
|
| MD5 |
fb3b3dfacef7d641fd16a31b1aba275c
|
|
| BLAKE2b-256 |
3f6018bb0274d1c427566d9a357261bcedb2d90a102e5151e9690f909ce29f59
|
File details
Details for the file daly_energy-2.0.0-py3-none-any.whl.
File metadata
- Download URL: daly_energy-2.0.0-py3-none-any.whl
- Upload date:
- Size: 33.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5c490eedee63a9ced3885e17f19034fb95b60bd3b84cfb680f4284cb5864530
|
|
| MD5 |
634fe530cf11e460b4260bbfe78b834b
|
|
| BLAKE2b-256 |
494a19a4431fb3eacd598c79a0a85f7891c526c85ecbf7348a0eb115a04a6bb8
|