Hello,
I've implemented an Azure Function using Python that is supposed to be triggered based on a timer. The main goal of the function is to fetch data from an external API and save the results to OneDrive.
Here's the full code for reference:
import os
import logging
import datetime
import requests
import json
import math
import azure.functions as func
from msal import ConfidentialClientApplication
def main(mytimer: func.TimerRequest) -> None:
logging.info('Python timer trigger function ran at %s', datetime.datetime.utcnow())
url = "https://clm.perfectgym.com.au/Api/v2/odata/members?$count=true&"
perfectgym_client_id = os.getenv('PERFECTGYM_CLIENT_ID')
if not perfectgym_client_id:
logging.error('Missing PERFECTGYM_CLIENT_ID environment variable.')
return
perfectgym_client_secret = os.getenv('PERFECTGYM_CLIENT_SECRET')
if not perfectgym_client_secret:
logging.error('Missing PERFECTGYM_CLIENT_SECRET environment variable.')
return
headers = {
'X-Client-Id': perfectgym_client_id,
'X-Client-Secret': perfectgym_client_secret
}
results = call_api(url, headers)
filename = 'MembersData01.json'
save_to_onedrive(results, filename)
def call_api(url, headers):
results = []
try:
j_response = requests.get(url, headers=headers).json()
count = j_response.get('@odata.count', 0)
except (KeyError, json.JSONDecodeError):
count = 0
logging.error("Error in getting count from API response.")
for i in range(math.ceil(count / 500)):
response = requests.get(url + "$skip=" + str(i*500), headers=headers)
if response.status_code != 200:
logging.error(f"API returned non-200 status code: {response.status_code}")
continue
for v in response.json().get('value', []):
results.append(v)
return results
def save_to_onedrive(json_data, filename):
authority_host_uri = 'https://login.microsoftonline.com'
azure_tenant = os.getenv('AZURE_TENANT_ID')
if not azure_tenant:
logging.error('Missing AZURE_TENANT_ID environment variable.')
return
authority_uri = authority_host_uri + '/' + azure_tenant
resource_uri = 'https://graph.microsoft.com'
azure_client_id = os.getenv('AZURE_CLIENT_ID')
if not azure_client_id:
logging.error('Missing AZURE_CLIENT_ID environment variable.')
return
azure_client_secret = os.getenv('AZURE_CLIENT_SECRET')
if not azure_client_secret:
logging.error('Missing AZURE_CLIENT_SECRET environment variable.')
return
onedrive_user_id = os.getenv('ONEDRIVE_USER_ID')
if not onedrive_user_id:
logging.error('Missing ONEDRIVE_USER_ID environment variable.')
return
app = ConfidentialClientApplication(
azure_client_id,
authority=authority_uri,
client_credential=azure_client_secret,
azure_region="australiasoutheast"
)
scopes = ['https://graph.microsoft.com/.default']
result = app.acquire_token_silent(scopes, account=None)
if not result:
result = app.acquire_token_for_client(scopes)
if "access_token" in result:
token = result['access_token']
onedrive_url = f"https://graph.microsoft.com/v1.0/users/{onedrive_user_id}/drive/root:/z-CLM PG All Data/Members Data/{filename}:/content"
headers = {'Authorization': 'Bearer ' + token}
response = requests.put(onedrive_url, headers=headers, data=json.dumps(json_data, ensure_ascii=False, indent=4))
if response.status_code in [200, 201]: # Handling both 200 and 201 status codes
logging.info('Successfully saved data to OneDrive.')
else:
logging.error(f"Failed to save data to OneDrive: {response.json()}")
else:
logging.error(f"Could not get an access token: {result}")
Issues:
- When I test/run the function in Azure, there is no sign of it working.
- No results are showing in monitoring, not even errors.
What I've tried:
- Checked the CRON expression to ensure the function should be triggered.
- Ensured all required dependencies are installed.
- Made sure all environment variables are correctly set in the Azure Function App settings.
- Checked the Azure Portal "Monitor" and "Logs" section, but no relevant logs found.
- Re-deployed the function.
Questions:
- Are there any issues in the code that might prevent it from running?
- Could there be any configuration-related problems in the Azure portal that might be causing this?
- How can I get more detailed logs or error messages to better understand what's happening?
Any help or guidance would be greatly appreciated. Thank you!