-
Notifications
You must be signed in to change notification settings - Fork 3k
Sandraho/add app insights #40327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Sandraho/add app insights #40327
Changes from all commits
281bd37
d3af774
7d7a1de
48e37b8
edcaced
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,15 @@ | |
EvaluationsOperations, | ||
TelemetryOperations, | ||
) | ||
from azure.identity import DefaultAzureCredential | ||
from azure.identity import DefaultAzureCredential | ||
from azure.mgmt.applicationinsights import ApplicationInsightsManagementClient | ||
from azure.mgmt.applicationinsights.v2020_02_02_preview.models import ApplicationInsightsComponent | ||
from azure.mgmt.authorization import AuthorizationManagementClient | ||
from azure.mgmt.authorization.models import RoleAssignmentCreateParameters | ||
from azure.mgmt.applicationinsights.v2020_02_02_preview.operations._components_operations import ComponentsOperations | ||
|
||
import uuid | ||
from .operations._patch import _SyncCredentialWrapper, InferenceOperations | ||
|
||
if TYPE_CHECKING: | ||
|
@@ -66,6 +75,9 @@ def __init__( # pylint: disable=super-init-not-called,too-many-statements | |
kwargs3 = kwargs.copy() | ||
|
||
self._user_agent: Optional[str] = kwargs.get("user_agent", None) | ||
self._create_app_insights: Optional[bool] = kwargs.get("create_app_insights", None) | ||
if self._create_app_insights: | ||
self.create_app_insights(subscription_id, resource_group_name, project_name, credential) | ||
|
||
# For getting AppInsights connection string from the AppInsights resource. | ||
# The AppInsights resource URL is not known at this point. We need to get it from the | ||
|
@@ -259,6 +271,55 @@ def from_connection_string(cls, conn_str: str, credential: "AsyncTokenCredential | |
credential, | ||
**kwargs, | ||
) | ||
|
||
@classmethod | ||
def create_app_insights(cls, subscription_id, resource_group_name, resource_name, location, principal_id, credential=None) -> Self: | ||
"""Create an Application Insights resource and assign RBAC roles. | ||
:param resource_group_name: The name of the resource group. | ||
:type resource_group_name: str | ||
:param resource_name: The name of the Application Insights resource. | ||
:type resource_name: str | ||
:param location: The location of the resource. | ||
:type location: str | ||
:return: The connection string of the Application Insights resource. | ||
:rtype: str | ||
""" | ||
# Use provided credential or create a new one | ||
credential = credential or DefaultAzureCredential() | ||
|
||
# Create Application Insights resource | ||
client = ApplicationInsightsManagementClient(credential, subscription_id) | ||
app_insights_component = ApplicationInsightsComponent( | ||
location=location, | ||
application_type="web", | ||
kind="web" | ||
) | ||
client.components.create_or_update(resource_group_name, resource_name, app_insights_component) | ||
|
||
# Retrieve the connection string | ||
component = client.components.get(resource_group_name, resource_name) | ||
connection_string = component.connection_string | ||
|
||
# Assign RBAC roles | ||
role_definition = '3913510d-42f4-4e42-8a64-420c390055eb' # Monitoring Metrics Publisher | ||
authorization_client = AuthorizationManagementClient(credential, subscription_id) | ||
role_definition_id = f"/subscriptions/{subscription_id}/providers/Microsoft.Authorization/roleDefinitions/{role_definition}" | ||
scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/microsoft.insights/components/{resource_name}" | ||
role_assignment_name = str(uuid.uuid4()) # Generate a unique role assignment name | ||
|
||
role_assignment_params = RoleAssignmentCreateParameters( | ||
role_definition_id=role_definition_id, | ||
principal_id=principal_id | ||
) | ||
authorization_client.role_assignments.create( | ||
scope=scope, | ||
role_assignment_name=role_assignment_name, | ||
parameters=role_assignment_params | ||
) | ||
if not connection_string: | ||
raise ValueError("Connection string cannot be None") | ||
credential = DefaultAzureCredential() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to redefine the credential value here from the value above? |
||
return cls.from_connection_string(connection_string, credential) | ||
|
||
def upload_file(self, file_path: Union[Path, str, PathLike]) -> Tuple[str, str]: | ||
"""Upload a file to the Azure AI Foundry project. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,16 @@ | |
from azure.core.credentials import TokenCredential | ||
from azure.core.exceptions import ResourceNotFoundError | ||
from azure.core.tracing.decorator_async import distributed_trace_async | ||
from azure.identity import DefaultAzureCredential | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to add all of these dependencies that aren't used in the code? |
||
from azure.core.tracing.decorator import distributed_trace | ||
from azure.mgmt.applicationinsights import ApplicationInsightsManagementClient | ||
from azure.mgmt.applicationinsights.v2018_05_01_preview.models import ApplicationInsightsComponent | ||
from azure.identity import DefaultAzureCredential | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double import of this from above. |
||
from azure.mgmt.applicationinsights import ApplicationInsightsManagementClient | ||
from azure.mgmt.applicationinsights.models import ApplicationInsightsComponent | ||
from azure.mgmt.authorization import AuthorizationManagementClient | ||
from azure.mgmt.authorization.models import RoleAssignmentCreateParameters | ||
import uuid | ||
|
||
from ... import models as _models | ||
from ..._vendor import FileType | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,16 @@ | |
) | ||
|
||
from azure.core.exceptions import ResourceNotFoundError | ||
from azure.identity import DefaultAzureCredential | ||
from azure.core.tracing.decorator import distributed_trace | ||
from azure.mgmt.applicationinsights import ApplicationInsightsManagementClient | ||
from azure.mgmt.applicationinsights.v2018_05_01_preview.models import ApplicationInsightsComponent | ||
from azure.identity import DefaultAzureCredential | ||
from azure.mgmt.applicationinsights import ApplicationInsightsManagementClient | ||
from azure.mgmt.applicationinsights.models import ApplicationInsightsComponent | ||
from azure.mgmt.authorization import AuthorizationManagementClient | ||
from azure.mgmt.authorization.models import RoleAssignmentCreateParameters | ||
import uuid | ||
|
||
from .. import models as _models | ||
from .._vendor import FileType | ||
|
@@ -797,7 +806,15 @@ def get_connection_string(self) -> str: | |
) | ||
|
||
if not get_workspace_response.properties.application_insights: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same as the function above |
||
raise ResourceNotFoundError("Application Insights resource was not enabled for this Project.") | ||
# raise ResourceNotFoundError("Application Insights resource was not enabled for this Project.") | ||
# instead or raising resource not found, create resource. may need to refactor depending on if | ||
# we want this to be client choice to create the app insights in case resource doesnt exist | ||
# or just do this automatically | ||
self._outer_instance.telemetry.create_application_insights_if_not_exists( | ||
resource_group_name=get_workspace_response.properties.resourceGroupName, | ||
resource_name="your_resource_name", | ||
location="your_location" | ||
) | ||
|
||
# Make a GET call to the Application Insights resource URL to get the connection string | ||
app_insights_respose: GetAppInsightsResponse = self._get_app_insights( | ||
|
@@ -808,6 +825,7 @@ def get_connection_string(self) -> str: | |
|
||
return self._connection_string | ||
|
||
|
||
# TODO: what about `set AZURE_TRACING_GEN_AI_CONTENT_RECORDING_ENABLED=true`? | ||
# TODO: This could be a class method. But we don't have a class property AIProjectClient.telemetry | ||
def enable(self, *, destination: Union[TextIO, str, None] = None, **kwargs) -> None: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double import?