How to use Energyworx API
This article explains how to use the Energyworx APIv1.5. This way you can use it for simple calls from your laptop or for any complex integration you may require. Here we'll explain how to authorize yourself or your applications to talk to the API, including some examples in Python.
Authorized requests​
In order to make an authorized call to the API you need 2 elements in the header of each request.
X-NAMESPACE- Either
AuthorizationorX-API-KEY.
Authorization header​
For authorization, you can use either:
- the Bearer token: token exchanged between your browser and the platform on the console interactions.
- a Json Web Token (JWT).
API keys​
API are not recommended this method as not all endpoints support API keys. API keys are unique for each environment and namespace. API keys do not expire as per 24.01. This makes API keys less safe, and therefore, not all endpoints can be called using an API Key.
To request an API key please make a ticket for the service desk.
Examples​
Example of request to the APIv1.5 in python
url = "https://api-xx.energyworx.com/_ah/api/ewx/v1/datasource/get/XXXX/channelProperties"
headers = {
"Authorization": "Bearer ya29.A0AfH6SMCG_OGli0 [the rest]", #only this or 'X-API-KEY is needed.'
#"X-API-KEY": "[your API key]",
"X-NAMESPACE": "[Namespace ID]",
"accept": "application/json"
}
params = {
"query": "SELECT * FROM tags limit 20"
}
response = requests.get(url=url, headers=headers, params=params)
status_code = response.status_code
# user-friendly status code. This can be easily Googled.
if status_code == 200:
status = 'Successful'
elif status_code == 401:
status = 'Unsuccessful: Unauthorized'
elif status_code == '404':
status = 'Unsuccessful: Not Found'
else:
status = 'Unavailable: Other'
print(status) #prints user-friendly status.
print(response.json()) #prints result returned from request in JSON format.
JWT Generation​
Using your own web token can be handy for sparse requests but because of the expiration it won't be helpful for integrating other applications. For this you need to use JWTs. For more information on JWT, see: jwt
Note: these are generated per environment (aka project) not per namespace, like API keys.
Follow these instructions to generate your own JWTs
- Generate private and public key using the following:
openssl ecparam -genkey -name prime256v1 -noout -out private_key_ewx.pemopenssl ec -in private_key_ewx.pem -pubout -out public_key_ewx.pem- In the directory where the public key is stored, copy the public key using the following:
pbcopy < public_key_ewx.pem- Provide the following information to the Energyworx Administrator (must be an individual with an Energyworx domain e-mail):
- The public key that was copied from the previous step
<<\--note: the line breaks (e.g., \n) must be properly reflected here! - The KID
- The user email and user_id for the designated account which the generated JWT will use.
For Energyworx Admin:​
You must navigate to the desired environment to add the individual’s credentials, using the patch call /ewx/v1/admin/configuration/jwt/{provider}
If the provider doesn’t exist, then one must be created. This is done using the following API call: /ewx/v1/admin/configuration/jwt
Once successfully configured, the following logic can be used to generate the credentials:
Please note, this script generates a token that is valid for 1 hour, which is what we recommend for safety reasons. Therefore, you need to incorporate the token generation into your script to avoid “manually” generating the token each time you want to make a call.
import jwt
from datetime import datetime, timedelta
"""
Requires:
pip install pyjwt
pip install cryptography
"""
class JWTService(object):
def __new__(cls, *args, **kwargs):
if hasattr(cls, 'current_class'):
return cls.current_class
cls.JWT_CACHE = {"exp": datetime.utcnow(), "token": None}
# Please share the values of the following 3 parameter with the Energyworx team
cls.kid = "unique-string" #This needs to be whatever your KID is.
cls.user_email = "first.last@domain.org" #User's e-mail
cls.user_id = "first.last" #User's ID
cls.issuer = "string" #The issuer, as specified in enviornment.
cls.current_class = cls
return cls
@classmethod
def get_jwt(cls, private_key_file_path, expiry=3600):
if datetime.utcnow() < (cls.JWT_CACHE.get('exp', datetime.utcnow()) - timedelta(seconds=60)) and cls.JWT_CACHE.get('token'):
return cls.JWT_CACHE.get('token')
jwt_header = {
"kid": cls.kid
}
jwt_payload = {
"sub": cls.user_id,
"email": cls.user_email,
"iss": cls.issuer,
"aud": "energyworx.com",
}
with open(private_key_file_path) as private_key:
issued_date = datetime.utcnow()
expiry_time = issued_date + timedelta(seconds=expiry)
jwt_payload['iat'] = issued_date
jwt_payload['exp'] = expiry_time
generated_jwt_token = jwt.encode(jwt_payload, private_key.read(), algorithm='ES256', headers=jwt_header)
#if generated_jwt_token:
#generated_jwt_token = generated_jwt_token.decode('utf-8')
cls.JWT_CACHE = {'exp': expiry_time, 'token': generated_jwt_token}
return generated_jwt_token
# to validate it works:
print(JWTService().get_jwt('/Users/<PATH>/private_key_ewx.pem'))