Get resource group name from resource object Azure SDK Python - python

Just wondering if there is a simple way to get the resource group name from an Azure resource object i.e. Disk, Snapshot object
Currently I use the resource URI and derive the resource group from that:
# ID example: '/subscriptions/123/resourceGroups/MyRG/providers/Microsoft.Compute/disks/disk-a
resource_group = [value for value in str(disk.id).split("/") if value][3]
Output
>> MyRG
I can't seem to see a way to do something like:
disk.resource_group

Looking at the MSDN, I don't believe there is a resource_group property.
What I usually do is create a method(similar to what you have done) to fetch the resource group from a resource ID:
def get_resource_group_from_id(resource_id):
return resource_id.lstrip("/").split("/")[3]
Then I just use this method everywhere I need to get the resource group:
from azure.mgmt.compute import ComputeManagementClient
from azure.common.client_factory import get_client_from_cli_profile
compute_client = get_client_from_cli_profile(ComputeManagementClient)
for disk in compute_client.disks.list():
resource_group = get_resource_group_from_id(resource_id=disk.id)
However, I'm not a fan of this since I'm used to just fetching this directly from the resource.
You could raise a Feature Request with azure-sdk-for-python to get this property included in the objects. Azure PowerShell and Azure CLI include this property, so I don't see why Azure Python SDK shouldn't include it.
Another option could be to include a resource_group tag, then you can fetch it directly from the resource.

Below is the Azure SDK for python:
https://learn.microsoft.com/en-us/python/api/overview/azure/?view=azure-python
I think your needs need to be specific to a specific service, And in general, a large range can be specific to a small range, but the specific objects of each service do not seem to define a method to obtain the corresponding resource group. I think your idea may not be realized.

Related

GET and POST Function App Function/Host Keys Using Python (Azure Government)

I am attempting to retrieve and add function/host keys for an Azure Government function app via Python. I am currently working with the information from this question and the corresponding API page. While these are not specific to Azure Government, I would think the process would be similar after updating the URLs to the Azure Government versions. However, I am receiving the error "No route registered for '/api/functions/admin/token'" when running the jwt part of the given code. Is this approach feasible for what I am trying to do?
I also found somewhere that I instead might want to try a GET request like this:
resp = requests.get("https://management.usgovcloudapi.net/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Web/sites/<function-app-name>/functions/admin/masterkey?api-version=20XX-XX-XX", headers={"Authorization": f"Bearer {something}"})
This gives me the error "{"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}", though. If this is indeed the correct approach, then what format should the Bearer token take?
Bit late answering but it may be useful for someone else in the future, it took me a while to find out how to do this.
If you want to retrieve the keys of a specific function within a function app then you can use list_function_keys() function from the Python SDK
Working with the Az management API directly may be a bit annoying and since the Azure CLI is written in Python whatever operation you do with the CLI you can do it directly in a Python script.
Here's an example of how you can retrieve the keys
from azure.identity import DefaultAzureCredential
from azure.mgmt.web import WebSiteManagementClient
# Your subscription ID
SUB_ID = "00000000-0000-0000-0000-000000000000"
fn_name = "some_function" # Name of your function
app_name = "some_app" # Name of your site/function app
rg_name = "some_rg" # Resource group name to which the function belongs
web_client = WebSiteManagementClient(subscription_id=SUB_ID, credential=DefaultAzureCredential())
keys = web_client.web_apps.list_function_keys(rg_name, app_name, fn_name)
# Your keys will be accessible in the additional_properties param
print(keys.additional_properties)
Hope it helps! I'm new on Azure so if I'm doing something wrong, please don't hesitate to point out my mistake and share your correction

Google Cloud Storage - How to retrieve a file's owner via Python?

I'm trying to access to a blob uploaded on a bucket of Google Cloud Storage via Python official client (google-cloud-storage).
I'm managing into retrieving the owner of the file (the one who uploaded it), and I'm not finding something useful on internet.
I've tried using the client with something like:
client(project='project').get_bucket('bucket').get_blob('blob')
But the blob properties like "owner" are empty!
So I tried using a Cloud Function and accessing to event and context.
In the Google documentation (https://cloud.google.com/storage/docs/json_api/v1/objects#resource) it is reported the structure of an event and it seems to have the owner propriety. But when I print or try to access it I obtain an error because it is not set.
Can someone help me? I just need to have the user email... thanks in advance!
EDIT:
It doesn't seem to be a permission error, because I obtain the correct results testing the API from the Google site: https://cloud.google.com/storage/docs/json_api/v1/objects/get?apix_params=%7B%22bucket%22%3A%22w3-dp-prod-technical-accounts%22%2C%22object%22%3A%22datagovernance.pw%22%2C%22projection%22%3A%22full%22%7D
By default, owner and ACL are not fetched by get_blob. You will have to explicitly fetch this info:
blob = client(project='project').get_bucket('bucket').get_blob('blob')
blob.reload(projection='full')
Note that if you use uniform bucket-level ACLs owner doesn't have any meaning and will be unset even with the above change.
EDIT: this is actually not the most efficient option because it makes an extra unnecessary call to GCS. The most efficient option is:
blob = Blob('bucket', 'blob')
blob.reload(projection='full', client=client)

listing the azure locations that support virtual network

I'd like to create virtual networks in every location in Azure that can support them, using Azure python SDK.
In the code below I'm limiting only to location germanynorth, but that is just to help reproduce the issue.
from azure.common.client_factory import get_client_from_auth_file
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.subscription import SubscriptionClient
from azure.mgmt.network import NetworkManagementClient
get_client_from_auth_file(ComputeManagementClient)
for location in get_client_from_auth_file(SubscriptionClient).subscriptions.list_locations(get_subscription_id()):
if location.name == 'germanynorth':
get_client_from_auth_file(NetworkManagementClient).virtual_networks.create_or_update(
resource_group_name=RESOURCE_GROUP_NAME,
virtual_network_name='test-network',
parameters={'location': location.name, 'address_space': {'address_prefixes': ['10.0.0.0/16']}, }
)
When running this I get the error:
msrestazure.azure_exceptions.CloudError: Azure Error: LocationNotAvailableForResourceType
Message: The provided location 'germanynorth' is not available for resource type 'Microsoft.Network/virtualNetworks'. List of available regions for the resource type is 'westus,eastus,northeurope,westeurope,eastasia,southeastasia,northcentralus,southcentralus,centralus,eastus2,japaneast,japanwest,brazilsouth,australiaeast,australiasoutheast,centralindia,southindia,westindia,canadacentral,canadaeast,westcentralus,westus2,ukwest,uksouth,koreacentral,koreasouth,francecentral,australiacentral,southafricanorth,uaenorth,switzerlandnorth,germanywestcentral,norwayeast'.
Very helpfully, the error includes a list of all the regions where virtualNetworks could be created, but of course this list will change over time.
What API in Azure can I use to figure out what locations (regions?) support virtual networks?
Thanks!
You can use Azure resource providers and types. You can refer the Microsoft article on the resource provider.
PowerShell script to get all supported azure regions to create Azure key Vault.
$locations = (((Get-AzResourceProvider -ProviderNamespace Microsoft.KeyVault)| Where-Object RegistrationState -eq "Registered").ResourceTypes | Where-Object ResourceTypeName -eq vaults).Locations
I actually figured out my own bounty.
https://learn.microsoft.com/en-us/rest/api/resources/providers/get
"Gets the specified resource provider."
I don't think this describes what it actually does, which is why I didn't find it. I had to just basically test a bunch of APIs to see what returned what.
This API will return a list of available locations for the provided resource type (in your subscription).
I just wish it didn't only return a list (East US) but also with the with a short code (code:location), for example (eastus:East US).
So to answer the actual question, if you can't use your python library for this, an option would be to use this REST API:
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Network?api-version=2021-04-01
Your list of locations will be under the json path: {response}.resourceTypes[0].locations, where resourceType eq "virtualNetworks"
To actually get the locationCode (short location code) you can query this API:
https://learn.microsoft.com/en-us/rest/api/resources/subscriptions/list-locations
then map your location from above with this response to get the short code ('East US' -> 'eastus'), which can be used in other rest APIs to create for example a virtual network.
There is an API with which we can list out all the available location under a given subscription id (I am not sure if there is an equivalent version of this API that can filter by resource type) -
API -
GET https://management.azure.com/subscriptions/{subscriptionId}/locations?api-version=2020-01-01
Quoting the documentation
This operation provides all the locations that are available for resource providers; however, each resource provider may support a subset of this list.
Perhaps, you can iterate through the list of available locations in your subscription and put it in a try/except block to create Vnet against all available regions in your subscription?
EDIT: Apologies, I realized it late, you are already iterating through the list of locations under your subscription id. I guess it's a matter of writing the code beneath the for loop in a try/except block, wherein you can except that particular error type and continue with your loop?

How to properly lazy load images from a blob container?

I'm willing to implement a lazy loading approach to load images stored in an "images" folder inside an azure storage account.
I have a container in my flutter app where whenever the user scrolls down the bottom new 10 images will be loaded from the storage based on the most recent(timestamp).
I looked into this sample retrieved from: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-storage-blob/12.0.0b5/index.html#id20
from azure.storage.blob.aio import ContainerClient
container = ContainerClient.from_connection_string(conn_str="my_connection_string", container_name="my_container")
blob_list = []
async for blob in container.list_blobs():
blob_list.append(blob)
print(blob_list)
But it's not what I need.I am looking for a way to make a get request that will retrieve me new set of images whenever the function is invoked..
Thankful for suggestions!
I was able to implement a lazy loading approach by using the marker continuation object
Example:
mark=req.params.get('NextMarker')
entit = table_service.query_entities('UserRequests','PartitionKey eq \'' + emailAddress + '\'',num_results=21,select= '..', marker=mark)
Dict = {"NextMarker": entit.next_marker}
return json.dumps(Dict)
This way I am able to send the marker in the http get request every time to get the second batch.
I hope this helps someone one day!
If you want to list blobs by blob creation time, unfortunately, it is not supported by Azure list blobs API(SDKs are based on APIs). Blob creation time belongs to blob properties, and as the official doc indicates, blob properties can't be set as a request param.
So if you want to fetch all new images for each request, maybe you should get a blob list first and sort them yourself and cut out the items that you need. There will be some extra codes that you need to write. But if you use Azure PowerShell to do that, you can implement the whole process easier. You can refer to this similar requirement.

How to delete a particular resource from resource group in Azure using python

I am using azure.mgmt.resource for deleting a resource group from azure but can i delete a particular resource without deleting a resource group?
If you can't use the specific client of the resource type as explained in another answer, you can use one of the two generic delete in the azure-mgmt-resource package and the ResourceManagementClient:
delete_by_id
delete
Note that the ApiVersion asked is the one from the resource you want to delete. Please look at the RestAPI documentation to get an ApiVersion depending of the resource type you want to delete. For instance, you can get the ApiVersion of Storage in that page:
https://learn.microsoft.com/rest/api/storagerp/
For example, If you are deleting a VM in a resource group
Delete VM
print('\nDelete VM')
async_vm_delete = compute_client.virtual_machines.delete(GROUP_NAME, VM_NAME)
async_vm_delete.wait()
Azure-Samples/resource-manager-python-resources-and-groups
Manage Azure resources and resource groups with Python:
Additional information: Click here

Categories