Calling your APIs from Python
Azure setup
In order to call your APIs from Python (or any other backend), you should use the Client Credential Flow.
- Navigate to Azure -> Azure Active Directory -> App registrations and find your OpenAPI application registration*
- Navigate over to
Certificate & secrets
- Click
New client secret
- Give it a name and an expiry time
- Click
Add
info
In this example, we used the already created OpenAPI app registration in order to keep it short, but in reality you should create a new app registration for every application talking to your backend. In other words, if someone wants to use your API, they should create their own app registration and their own secret.
info
You can use client certificates too, but we won't cover this here.
- Copy the secret and save it for later.
FastAPI setup
The basic process is to first fetch the access token from Azure, and then call your own API endpoint.
Single- and multi-tenant
my_script.py
import asyncio
from httpx import AsyncClient
from demo_project.core.config import settings
async def main():
async with AsyncClient() as client:
azure_response = await client.post(
url=f'https://login.microsoftonline.com/{settings.TENANT_ID}/oauth2/v2.0/token',
data={
'grant_type': 'client_credentials',
'client_id': settings.OPENAPI_CLIENT_ID, # the ID of the app reg you created the secret for
'client_secret': settings.CLIENT_SECRET, # the secret you created
'scope': f'api://{settings.APP_CLIENT_ID}/.default', # note: NOT .user_impersonation
}
)
token = azure_response.json()['access_token']
my_api_response = await client.get(
'http://localhost:8000/api/v1/hello-graph',
headers={'Authorization': f'Bearer {token}'},
)
print(my_api_response.json())
if __name__ == '__main__':
asyncio.run(main())
B2C
Compared to the above, the only differences are the scope
and url
parameters:
my_script.py
import asyncio
from httpx import AsyncClient
from demo_project.core.config import settings
async def main():
async with AsyncClient() as client:
azure_response = await client.post(
url=f'https://{settings.TENANT_NAME}.b2clogin.com/{settings.TENANT_NAME}.onmicrosoft.com/{settings.AUTH_POLICY_NAME}/oauth2/v2.0/token',
data={
'grant_type': 'client_credentials',
'client_id': settings.OPENAPI_CLIENT_ID, # the ID of the app reg you created the secret for
'client_secret': settings.CLIENT_SECRET, # the secret you created
'scope': f'https://{settings.TENANT_NAME}.onmicrosoft.com/{settings.APP_CLIENT_ID}/.default',
}
)
token = azure_response.json()['access_token']
my_api_response = await client.get(
'http://localhost:8000/api/v1/hello-graph',
headers={'Authorization': f'Bearer {token}'},
)
print(my_api_response.json())
if __name__ == '__main__':
asyncio.run(main())