Solved

Environment specific variables (eg. dynamic URL) in AIR


Userlevel 1

Request you to share on how to add environment specific URL(dev/prod/test) in handler.py in AIR. Also need to understand on how to get msal_token (bearer) authorization in AIR functions.

Example:

msal_token = request.headers.get("authorization")

requests.get(sequence_generator_api, headers={"authorization": msal_token})

where sequence_generator_api is environment specific API

icon

Best answer by Murad Sæter 23 August 2022, 13:26

View original

10 replies

Userlevel 4

Hei hei could you clarify a bit more on what this is needed for ? so i can maybe suggest a potential solution ?

Userlevel 1

we want to import api which has different  URL for different environments(prod/dev/test) and also Authorization(msal_token/bearer) is needed to access the api. Need to understand how to implement api dynamically and access it with token. 

Userlevel 4

Ok great looking into this and will get back to you with a response soon!

Userlevel 2

To get environment specific secrets you could create them as a GitHub secret and concatenate the CDF project name to the secret name.

If you have cdf-project-a and cdf-project-b create two secrets in GitHub;

SOME_SECRET_CDF_PROJECT_A and SOME_SECRET_CDF_PROJECT_B 

In config.yaml for your function add a list of secrets under modelSettings/secrets:

modelSettings:
...
secrets:
- SOME_SECRET_CDF_PROJECT_A
- SOME_SECRET_CDF_PROJECT_B

In you handler.py:

def handle(client, data, secrets):
print(f"Hello world from Cognite Functions @ {datetime.now()}!")
some_secret = secrets[f"some-secret-{client.config.project}"]
# use secret

The token used against CDF can be fetched using client.config.token(). Please notice that the scope is CDF specific and might not work againt a 3rd party service requiring a different scope.

Userlevel 1

Function deployment fails with below error:

  config.yaml: Project name itself is having more than 15 characters. 

Any solution for this?

Userlevel 2

You shouldn’t add _SECRET unless you also update the code. In any case it will be too long so it could be worked around by creating a map in the handler.py:

Create secrets in config.yaml+GitHub- COUNT_API_PROD, COUNT_API_TEST

In handler.py:

secret_map = {"count-api-accenture-operations-twin":"count-api-prod"}

def handle(client, data, secrets):
print(f"Hello world from Cognite Functions @ {datetime.now()}!")
some_secret = secrets[secret_map[f"some-secret-{client.config.project}"]]
# use secret


 

 

Userlevel 1

Hi @Murad Sæter Thank you, dynamic url is successfully set in the github secrets and was able to access in handle. Regarding token, we do not need cdf token, so we can not use client.config.token(). In our scenario, we need to use msal_token (authorization from azure), we have our app registered and service principle created, let me know if you can help us to get msal_token using client secrets.

Example: (we are still not sure how to get msal_token)

app = ConfidentialClientApplication(
    client_id="{client_id}",
    client_credential="{client_credential}",
    authority="https://login.microsoftonline.com/{tenant_id}")

app.acquire_token_for_client(["{scope}"], claims_challenge=None)

 

 

Userlevel 2

Your code it correct, the token will be in the result from app.acquire_token_for_client

Complete code:

import msal
app = msal.ConfidentialClientApplication(
client_id="<client id>", authority="https://login.microsoftonline.com/<tenantid>",
client_credential="<secret>"
)

result = app.acquire_token_for_client(scopes=["<scope>"])
token = result['access_token']

 

Userlevel 1

Thanks @Murad Sæter for confirming. I was able to get token and authorize the URL.

  1. Is it possible to use client_id, secret_name, tenant_id given in project properties from repoconfig.yaml in handle.py? or jst like client.config.token()? 
  2.  Let me know if only possible way is to add all parameters used in msal.ConfidentialClientApplication in github secrets only?
    1. if yes, secret_name (which might be client_secret stored in github secret) given in project properties in repoconfig.yaml, is already having length more than 15 characters.
Userlevel 2
  1. No. You will only get the token from the client.
  2. You can name it with shorter name and use the mapping described in my previous answer.

Reply