Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/platform_ci_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@

- name: Check Azure CLI Availability
run: |
python -m pip install --upgrade pip
pip install --upgrade -r requirements.txt
echo "Current PATH: $PATH"
which az
ls -l $(which az) || echo "az not found in the expected directory"
Expand All @@ -70,6 +72,7 @@
NEWS_ANALYST_MODEL_NAME: ${{ vars.NEWS_ANALYST_MODEL_NAME }}
FINANCIAL_ANALYST_MODEL_NAME: ${{ vars.FINANCIAL_ANALYST_MODEL_NAME }}
REPORT_GENERATOR_MODEL_NAME: ${{ vars.REPORT_GENERATOR_MODEL_NAME }}
APPLICATIONINSIGHTS_CONNECTION_STRING: ${{secrets.APPLICATIONINSIGHTS_CONNECTION_STRING}}
run: |
echo "Verifying Python Path"
which python
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/platform_pr_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@
uses: actions/checkout@v3

- name: Check Azure CLI Availability
working-directory: python
run: |
echo "Current PATH: $PATH"
which az
ls -l $(which az) || echo "az not found in the expected directory"
az --version
python -m pip install --upgrade pip
pip install --upgrade -r requirements.txt

- name: Azure login
uses: azure/login@v2
Expand All @@ -59,9 +62,11 @@
NEWS_ANALYST_MODEL_NAME: ${{ vars.NEWS_ANALYST_MODEL_NAME }}
FINANCIAL_ANALYST_MODEL_NAME: ${{ vars.FINANCIAL_ANALYST_MODEL_NAME }}
REPORT_GENERATOR_MODEL_NAME: ${{ vars.REPORT_GENERATOR_MODEL_NAME }}
APPLICATIONINSIGHTS_CONNECTION_STRING: ${{secrets.APPLICATIONINSIGHTS_CONNECTION_STRING}}
run: |
echo "Verifying Python Path"
which python
echo "Installed Packages:"
echo APPLICATIONINSIGHTS_CONNECTION_STRING=${{ secrets.APPLICATIONINSIGHTS_CONNECTION_STRING}} >> $GITHUB_ENV
pip list
python -u -m sk_financial_analyst.executors.single_item_executor --logging_enabled
12 changes: 12 additions & 0 deletions python/.env_sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,15 @@ AML_RESOURCE_GROUP_NAME=
AML_WORKSPACE_NAME=

SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true
OTEL_SERVICE_NAME="sk-financial-analyst-local"
OTEL_LOGS_EXPORTER="otlp"
OTEL_TRACES_EXPORTER="otlp"
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED="true"
OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
OTEL_EXPORTER_OTLP_INSECURE="true"
OTEL_LOG_LEVEL="INFO"
OTEL_RESOURCE_ATTRIBUTES="service.name=sk-financial-analyst-local"
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318"
# application insights connection string is added if you prefer not using collector.
APPLICATIONINSIGHTS_CONNECTION_STRING=
8 changes: 8 additions & 0 deletions python/common/configurator/config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
import os

import yaml
from azure.monitor.opentelemetry import configure_azure_monitor
from common.configurator.otel import config_otel
from dotenv import load_dotenv


def load_yaml(file_path):
"""Load a YAML file."""
load_dotenv()
connection_string = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")
if connection_string is not None:
print(f"connection string: {connection_string}")
configure_azure_monitor(connection_string=connection_string)
else:
config_otel()
with open(file_path, "r") as stream:
return yaml.safe_load(os.path.expandvars(stream.read()))

Expand Down
5 changes: 4 additions & 1 deletion python/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ flake8==7.1.1
pep8-naming==0.14.1
pytest==8.3.3
pytest-cov==5.0.0
opentelemetry-instrumentation==0.49b2
## otel collector
opentelemetry-instrumentation-openai==0.33.12
opentelemetry-instrumentation-fastapi==0.49b2
opentelemetry-distro==0.49b2
opentelemetry-exporter-otlp==1.28.2
fastapi==0.115.4
uvicorn==0.32.0
pydantic==2.8.2
## set this only when you want to directly instrument using
## application insights without collector
azure-monitor-opentelemetry==1.6.4
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import azure.functions as func
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from azure.monitor.opentelemetry import configure_azure_monitor
from common.configurator import otel
from llm_application.financial_health_analysis import FinancialHealthAnalysis

app = df.DFApp(http_auth_level=func.AuthLevel.FUNCTION)
Expand Down Expand Up @@ -69,6 +71,11 @@ async def generate_report(stock):
structured_report_generator_model = os.environ.get("REPORT_GENERATOR_MODEL_NAME")
aoai_api_version = os.environ.get("AOAI_API_VERSION")

if (os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")) is not None:
configure_azure_monitor()
else:
otel.config_otel()

credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id)
aoai_token = credential.get_token(auth_provider_endpoint).token

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ edgartools
yfinance==0.2.40
semantic-kernel
pydantic==2.8.2
## otel collector
opentelemetry-instrumentation-openai==0.33.12
opentelemetry-instrumentation-fastapi==0.49b2
opentelemetry-distro==0.49b2
opentelemetry-exporter-otlp==1.28.2
## set this only when you want to directly instrument using
## application insights without collector
azure-monitor-opentelemetry==1.6.4
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from azure.ai.ml.entities import Environment
from azure.ai.ml.parallel import RunFunction, parallel_run_function
from azure.identity import DefaultAzureCredential
from azure.monitor.opentelemetry import configure_azure_monitor
from common.configurator import otel
from dotenv import load_dotenv


Expand Down Expand Up @@ -118,7 +120,12 @@ def main():
"""
args = parse_args()
load_dotenv(override=True)

# if application connection string is available, directly use azure monitor connection
# else collector is used.
if (os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")) is not None:
configure_azure_monitor(connection_string=os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING"))
else:
otel.config_otel()
subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID")
resource_group = os.getenv("AML_RESOURCE_GROUP_NAME")
workspace = os.getenv("AML_WORKSPACE_NAME")
Expand Down
12 changes: 8 additions & 4 deletions python/sk_financial_analyst/executors/aml/aml_env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ dependencies:
- azure-identity==1.19.0
- azure-keyvault-secrets==4.9.0
- azure-ai-evaluation==1.0.0b5
- azure-monitor-opentelemetry-exporter==1.0.0b31
- pyyaml==6.0.2
- requests==2.32.3
- edgartools==2.34.2
- python-dotenv==1.0.1
- yfinance==0.2.40
- semantic-kernel==1.11.0
- opentelemetry-api==1.27.0
- opentelemetry-sdk==1.27.0
- opentelemetry-semantic-conventions==0.48b0
## otel collector
- opentelemetry-instrumentation-openai==0.33.12
- opentelemetry-instrumentation-fastapi==0.49b2
- opentelemetry-distro==0.49b2
- opentelemetry-exporter-otlp==1.28.2
## set this only when you want to directly instrument using
## application insights without collector
- azure-monitor-opentelemetry==1.6.4
4 changes: 2 additions & 2 deletions python/sk_financial_analyst/executors/single_item_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from common.configurator import config_reader, otel
from common.configurator import config_reader
from opentelemetry import trace
from opentelemetry.trace import SpanKind
from sk_financial_analyst.llm_application.financial_health_analysis import FinancialHealthAnalysis
Expand All @@ -36,7 +36,7 @@ async def generate_report(config_file, stock_ticker):
config_data = config_reader.load_yaml(config_file)

logger.info("Otel configuration started..")
otel.config_otel()

tracer = trace.get_tracer(__name__)
logger.info("Otel configuration successful..")

Expand Down
9 changes: 5 additions & 4 deletions python/sk_financial_analyst/routes/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from common.configurator import config_reader, otel
from common.configurator import config_reader
from fastapi import APIRouter, FastAPI
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.trace import SpanKind
from sk_financial_analyst.llm_application.financial_health_analysis import FinancialHealthAnalysis

# Load the configuration data
config_data = config_reader.load_yaml("./sk_financial_analyst/config/config.yaml")
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# from llm_application import financial_health_analysis
Expand All @@ -19,7 +21,7 @@
router = APIRouter()

logger.info("Otel configuration started..")
otel.config_otel()

OpenAIInstrumentor().instrument()
FastAPIInstrumentor.instrument_app(app)
tracer = trace.get_tracer(__name__)
Expand All @@ -31,8 +33,7 @@ async def run_financial_health_analysis(stock_ticker: str):
try:
with tracer.start_as_current_span("run_financial_analysis_report", kind=SpanKind.SERVER) as span:
logger.info("Starting finacial report generation..")
# Load the configuration data
config_data = config_reader.load_yaml("./sk_financial_analyst/config/config.yaml")

key_vault_url = os.environ.get("KEY_VAULT_URL")

# Get values from the configuration data
Expand Down