Authentication
The Renewables.Architect Integrate API can be called either directly by a user, or by a script or software tool. In both cases, a JSON Web Token (JWT) is received from DNV’s Veracity platform and then used in future API requests as a means of identification, but the process of obtaining this token is slightly different in each case.
A token is valid for 60 minutes, after which time a new token needs to be requested with the same process.
Native Flow (User-Driven Authentication)
Section titled “Native Flow (User-Driven Authentication)”This method is ideal for individual users who are manually interacting with the API. It requires the user to have an account with Veracity and be registered as an API user.
How it works:
- Run the provided authentication script.
- A browser window will open, directing you to the Veracity login page.
- Log in using your Veracity credentials.
- Once authenticated, a JWT token is returned.
- Add this token to the Authorization header of future API requests.
import sysfrom msal import PublicClientApplication
app = PublicClientApplication( "9988d241-0027-4791-918b-8888e35f313d", # analysis service client ID authority="https://login.veracity.com/a68572e3-63ce-4bc1-acdc-b64943502e9d/B2C_1A_SignInWithADFSIdp", instance_discovery=False)
result = app.acquire_token_interactive(scopes=[])
if "id_token" in result: print(result["id_token"])else: print(result.get("error")) print(result.get("error_description")) print(result.get("correlation_id"))Client Credentials Flow (App-to-App Authentication)
Section titled “Client Credentials Flow (App-to-App Authentication)”This method is designed for automated systems, shared scripts, or server-to-server communication. No user interaction required at runtime, but app needs to be registered as a client in Veracity by the Renewables.Architect team (contact renewables.architect@dnv.com).
How it works:
- Your application uses a set of client credentials to request a token from Veracity.
- The token is then included in each API request to authenticate the app.
Script Usage
Section titled “Script Usage”To obtain a token using the client credentials flow, use the following command:
> python ./get_token_client_credentials_flow [client_id] [client_secret]Parameters:
Section titled “Parameters:”- client_id: The unique ID assigned to your app when it was registered in Veracity. You can find this in the Settings tab of your app’s page on Veracity.
- client_secret: A secret string generated in the Settings tab of your app’s page. You can only have two active secrets at a time. You can only view a secret once, at the time of generation, please store it securely!
Troubleshooting
Section titled “Troubleshooting”If you encounter an error:
- invalid_grant: This usually means the client ID is incorrect.
- invalid_client: This typically indicates the client secret is incorrect.
import sysimport requestsimport jsonfrom datetime import datetime
try: client_id = sys.argv[1]except IndexError: raise Exception(f"Client ID not present. Please provide the client ID. It can be found by logging into Veracity for Developers and selecting My Projects, then selecting your app and then selecting the Settings tab of your app.")try: client_secret = sys.argv[2]except IndexError: raise Exception(f"Client secret not present. Please provide a client secret. One can be generated by logging into Veracity for Developers and selecting My Projects, then selecting your app and then selecting the Settings tab of your app and clicking regenerate on one of the client secrets.\nWarning this will overwrite the existing secret which will no longer be valid after you regenerate a new one.")
body = { "grant_type": "client_credentials", "client_id": client_id, "scope": "https://dnvglb2cprod.onmicrosoft.com/330ee71f-6d77-47dd-8239-e7a051cbc142/.default", # analysis service "client_secret": client_secret}
response = requests.post("https://login.veracity.com/a68572e3-63ce-4bc1-acdc-b64943502e9d/oauth2/v2.0/token?p=b2c_1a_signinwithadfsidp", data=body, headers={'Content-Type': 'application/x-www-form-urlencoded'})
if response.status_code == 200: token = json.loads(response.text) print(f"access_token = {token['access_token']}") readable_expiry = datetime.fromtimestamp(int(token['expires_on'])).strftime('%Y-%m-%d %H:%M:%S') print(f"expiry time = {readable_expiry}")else: raise Exception("Error:", response.status_code, response.text)