Resource not found for the segment 'partner'
Describe the bug
I am encountering an error attempting to perform a "List" or "Get" operation for Partner Security Alerts.
https://learn.microsoft.com/en-us/graph/api/partner-security-partnersecurityalert-list-securityalerts?view=graph-rest-beta&tabs=python
Expected behavior
A response object should be returned as indicated in the Microsoft docs:
https://learn.microsoft.com/en-us/graph/api/partner-security-partnersecurityalert-get?view=graph-rest-beta&tabs=python#response-1
{
"id": "d8b202fc-a216-3404-69ef-bdffa445eff6",
"displayName": "Action Required: Virtual machine connecting to crypto currency mining pool Detected",
"description": "Analysis of Azure resource network activity detected the resource was connecting to a crypto currency mining pool. This would often be an indication that your Azure resource is compromised.",
"alertType": "networkConnectionsToCryptoMiningPools",
"status": "active",
"severity": "high",
"confidenceLevel": "medium",
"customerTenantId": "1889e718-414b-4bad-8bbe-c1135bd39a41",
"subscriptionId": "5f6e6521-6e5f-4b0b-80aa-bd44fad7a398",
"valueAddedResellerTenantId": "c296b2ce-8cd1-4346-9e82-d8eccca70d65",
"catalogOfferId": "MS-AZR-0017G",
"detectedDateTime": "2024-01-23T16:03:33.05Z",
"firstObservedDateTime": "2024-01-23T16:03:33.05Z",
"lastObservedDateTime": "2024-01-23T16:03:33.05Z",
"resolvedReason": "fraud",
"resolvedOnDateTime": "2024-02-23T16:03:33.05Z",
"resolvedBy": "[email protected]",
"isTest": false,
"affectedResources": [
{
"resourceId": "/subscriptions/subscription-id/resourceGroups/resourcegroup-name/providers/Microsoft.Compute/virtualMachines/vm-name",
"resourceType": "AzureResource"
}
],
"activityLogs": [
{
"statusFrom": "active",
"statusTo": "investigating",
"updatedBy": "[email protected]",
"updatedDateTime": "2023-08-10T08:47:10.8454142Z"
},
{
"statusFrom": "investigating",
"statusTo": "resolved",
"updatedBy": "[email protected]",
"updatedDateTime": "2023-08-10T08:47:25.2089246Z"
}
],
"additionalDetails": {
"VM_IP": "[ \"vm-ip\"]",
"MiningPool_IP": "[ \"mining-pool-ip\"]",
"ConnectionCount": "5",
"CryptoCurrencyMiningPoolDomainName": "pool-name.com"
}
}
How to reproduce
- Installed the msgraph-beta-sdk using pip
- Attempted to run the below code snippets :
### List all active security alerts
from msgraph_beta import GraphServiceClient
from azure.identity import DefaultAzureCredential
from azure.identity.aio import ClientSecretCredential
from azure.keyvault.secrets import SecretClient
import asyncio
import json
def main():
alerts = asyncio.run(list_security_alerts())
print(alerts)
async def list_security_alerts():
"""Returns a list of all active security alerts"""
credential = DefaultAzureCredential()
secret_client = SecretClient(
vault_url="https://kv-demo-zan-prod-004.vault.azure.net/", credential=credential
)
client_id = secret_client.get_secret(
"clientId"
).value
client_secret = secret_client.get_secret(
"clientSecret"
).value
tenant_id = secret_client.get_secret(
"tenantId"
).value
credentials = ClientSecretCredential(tenant_id, client_id, client_secret)
scopes = ["https://graph.microsoft.com/.default"]
graph_client = GraphServiceClient(credentials=credentials, scopes=scopes)
result = await graph_client.security.partner.security_alerts.get()
active_alerts = [item.id for item in result.value if item.status == "active"]
return active_alerts
if __name__ == "__main__":
main()
### Retrieve individual alert
from msgraph_beta import GraphServiceClient
from azure.identity import DefaultAzureCredential
from azure.identity.aio import ClientSecretCredential
from azure.keyvault.secrets import SecretClient
import asyncio
def main():
alert_id = ""
alert = asyncio.run(get_security_alert(alert_id))
print(alert)
async def get_security_alert(alert_id):
"""Get individual security alert"""
credential = DefaultAzureCredential()
secret_client = SecretClient(
vault_url="https://kv-demo-zan-prod-004.vault.azure.net/", credential=credential
)
client_id = secret_client.get_secret(
"clientId"
).value
client_secret = secret_client.get_secret(
"clientSecret"
).value
tenant_id = secret_client.get_secret(
"tenantId"
).value
credentials = ClientSecretCredential(tenant_id, client_id, client_secret)
scopes = ["https://graph.microsoft.com/.default"]
graph_client = GraphServiceClient(credentials, scopes)
result = await graph_client.security.partner.security_alerts.by_partner_security_alert_id(alert_id).get()
return result
if __name__ == "__main__":
main()
SDK Version
1.25.0
Latest version known to work for scenario above?
No response
Known Workarounds
No response
Debug output
Click to expand log
```Traceback (most recent call last):
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets\list_security_alerts.py", line 48, in
main()
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets\list_security_alerts.py", line 11, in main
alerts = asyncio.run(list_security_alerts())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\asyncio\base_events.py", line 654, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets\list_security_alerts.py", line 40, in list_security_alerts
result = await graph_client.security.partner.security_alerts.get()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets.venv\Lib\site-packages\msgraph_beta\generated\security\partner\security_alerts\security_alerts_request_builder.py", line 69, in get
return await self.request_adapter.send_async(request_info, PartnerSecurityAlertCollectionResponse, error_mapping)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets.venv\Lib\site-packages\kiota_http\httpx_request_adapter.py", line 193, in send_async
await self.throw_failed_responses(response, error_map, parent_span, parent_span)
File "C:\Users\Developer\Partner-Center-Events\CodeSnippets.venv\Lib\site-packages\kiota_http\httpx_request_adapter.py", line 575, in throw_failed_responses
raise exc
msgraph_beta.generated.models.o_data_errors.o_data_error.ODataError:
APIError
Code: 400
message: None
error: MainError(additional_data={}, code='BadRequest', details=None, inner_error=InnerError(additional_data={}, client_request_id='redacted', date=datetime.datetime(2025, 3, 12, 13, 14, 58), odata_type=None, request_id='redacted'), message="Resource not found for the segment 'partner'.", target=None)
</details>
### Configuration
### Configuration
- OS: Windows 11
- architecture: x64
### Other information
_No response_
I've reviewed the logs, the underlying API being referenced by the beta SDK is "https://graph.microsoft.com/v1.0//security/partner/securityAlerts ", the resource has not yet been exposed on V1 hence the error being returned.
I have the same issue with the auditLog ressource with SDK beta 1.29.0
MainError(additional_data={}, code='BadRequest', details=None, inner_error=InnerError(additional_data={}, client_request_id='4e58f936-115d-4673-a674-087464d7471b', date=datetime.datetime(2025, 4, 25, 11, 55, 46), odata_type=None, request_id='63ad068b-9f13-45d7-86d0-f93831f337cc'), message="Resource not found for the segment 'auditLog'.", target=None)
The http client generated inside GraphRequestAdapter is using v1 (it is the default) and not beta and you can't really change it
but you can create a request adapter
from kiota_authentication_azure.azure_identity_authentication_provider import AzureIdentityAuthenticationProvider
from msgraph_core import APIVersion, GraphClientFactory
from msgraph_beta.graph_request_adapter import GraphRequestAdapter, options as graph_reqest_options
auth_provider = AzureIdentityAuthenticationProvider(creds, scopes=scopes)
beta_http_client = GraphClientFactory.create_with_default_middleware(options=graph_reqest_options, api_version=APIVersion.beta)
request_adapter = GraphRequestAdapter(auth_provider, client=beta_http_client)
client = BetaGraphServiceClient(credentials=creds, request_adapter=request_adapter)
Thanks @ericfel, this is awesome. Works like a charm. Only had to make one small change:
client = GraphServiceClient(credentials=creds, request_adapter=request_adapter)
Thanks @ericfel and @AdrianM10, it works very well and it is really better than using with_url to set BETA URL explicitly ;-)