Simple Python Web Service Client
Data Delivery Web service (the API for retrieving time series data)
if __name__ == '__main__':
import requests
import xmltodict # https://pypi.org/project/xmltodict/
import pandas as pd
api_key = 'demo'
dateFrom = '2024-05-01'
dateTo = '2024-05-01'
latitude = 48.61259
longitude = 20.827079
tilt = 40
azimuth = 180
request_xml = f'''<ws:dataDeliveryRequest dateFrom="{dateFrom}" dateTo="{dateTo}"
xmlns="http://geomodel.eu/schema/data/request"
xmlns:ws="http://geomodel.eu/schema/ws/data"
xmlns:geo="http://geomodel.eu/schema/common/geo"
xmlns:pv="http://geomodel.eu/schema/common/pv"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<site id="demo" lat="{latitude}" lng="{longitude}">
<pv:geometry xsi:type="pv:GeometryFixedOneAngle" tilt="{tilt}" azimuth="{azimuth}"/>
<pv:system installedPower="1" installationType="ROOF_MOUNTED">
<pv:module type="CSI"/>
<pv:inverter/>
<pv:losses/>
</pv:system>
</site>
<processing key="GHI DNI DIF GTI TEMP WS WD RH" summarization="HOURLY">
<timeZone>GMT+02</timeZone>
<timestampType>START</timestampType>
</processing>
</ws:dataDeliveryRequest>'''
url = f'https://solargis.info/ws/rest/datadelivery/request?key={api_key}'
headers = {'Content-Type': 'application/xml'}
with requests.post(url, data=request_xml, headers=headers) as response:
if not response.ok:
print(f'Failed API request with code {response.status_code}:\n{response.text}')
else:
datadict = xmltodict.parse(response.text) # transform XML document into Python dictionary
columns = datadict['dataDeliveryResponse']['site']['columns'].split() # get names of columns (GHI, DNI, etc.)
rows = datadict['dataDeliveryResponse']['site']['row'] # get rows or records from XML
rows = rows if isinstance(rows, list) else [rows]
timestamps = [r['@dateTime'] for r in
rows] # use '@dateTime' for sub/hourly data, '@date' for daily data, '@yearMonth' for monthly data
data_values = [r['@values'].split() for r in rows]
# create pandas dataframe from the response data:
df = pd.DataFrame(data_values, index=pd.to_datetime(timestamps), columns=columns)
df = df.apply(pd.to_numeric, errors='coerce') # make numbers from original strings in XML
print(df)
print(df.describe())
# plot the response:
# import matplotlib.pyplot as plt
# df.plot()
# plt.savefig('solargi_api_response.png')
LTA Web service (the API for retrieving long-term average data)
if __name__ == '__main__':
import requests
import xmltodict # https://pypi.org/project/xmltodict/
api_key = 'demo'
latitude = 48.61259
longitude = 20.827079
tilt = 40
azimuth = 180
request_xml = f'''<calculateRequest
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:geo="http://geomodel.eu/schema/common/geo"
xmlns:pv="http://geomodel.eu/schema/common/pv"
xmlns="http://geomodel.eu/schema/ws/pvplanner">
<site lat="{latitude}" lng="{longitude}">
<!-- optional terrain data -->
<geo:terrain elevation="246" azimuth="176" tilt="3.1" />
<!-- optional custom horizon data can override the natural terrain horizon -->
<!--<geo:horizon>11.11:18.0 7.5:15.53 15.0:10.94 352.5:17.29</geo:horizon>-->
<pv:geometry xsi:type="pv:GeometryFixedOneAngle" azimuth="{azimuth}" tilt="{tilt}"/>
<pv:system installedPower="1" installationType="ROOF_MOUNTED" availability="99">
<pv:module type="CSI">
</pv:module>
<pv:inverter>
<pv:efficiency xsi:type="pv:EfficiencyConstant" percent="97.5"/>
</pv:inverter>
<pv:losses dc="5.5" ac="1.5"/>
</pv:system>
</site>
</calculateRequest>'''
url = f'https://solargis.info/ws/rest/pvplanner/calculate?key={api_key}'
headers = {'Content-Type': 'application/xml'}
with requests.post(url, data=request_xml, headers=headers) as response:
if not response.ok:
print(f'Failed API request with code {response.status_code}:\n{response.text}')
else:
datadict = xmltodict.parse(response.text) # transform XML document into Python dictionary
response_dict = datadict['ns3:calculateResponse']
# explore solar and climate data in the response:
climate_data = response_dict['ns3:irradiation']
climate_data_reference = climate_data['ns3:reference'] # general climate data
solar_data_inplane = climate_data['ns3:inplane'] # POA irradiance components
geometry_comparison = climate_data['ns3:comparison'] # comparison of the various geometry options with selected one
optimum_angle = climate_data.get('ns3:optimum') # optimum fixed angle for the selected location
# get PV calculation data:
pv_data = response_dict['ns3:calculation']
pv_data_output = pv_data['ns3:output'] # PV system output total and specific
pv_data_losses = pv_data['ns3:losses'] # PV system losses breakdown
print('Climate data reference:', climate_data_reference)
print('Solar data in-plane:', solar_data_inplane)
print('Geometry comparison:', geometry_comparison)
print('Optimum angle:', optimum_angle)
print('PV data output:', pv_data_output)
print('PV data losses:', pv_data_losses)
, multiple selections available,
Related content
Java client implementation guide
Java client implementation guide
Read with this
Data Delivery WS request / response examples
Data Delivery WS request / response examples
Read with this
TMY API request-response technical description
TMY API request-response technical description
Read with this
Solargis TMY API Technical Guide
Solargis TMY API Technical Guide
Read with this
Solargis API User Guide
Solargis API User Guide
More like this
WS API troubleshooting / FAQ
WS API troubleshooting / FAQ
More like this