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?
Related
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
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.
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
I want to create my Pool using Python. I can do this when using an image (Ubuntu Server 16.04) from the marketplace, but I want to use a custom image (but also Ubuntu Server 16.04) -- one which I have prepared with the desired libraries and setup.
This is how I am creating my pool:
new_pool = batch.models.PoolAddParameter(
id=pool_id,
virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
image_reference=image_ref_to_use, # ??
node_agent_sku_id=sku_to_use),
vm_size=_POOL_VM_SIZE,
target_dedicated_nodes=_POOL_NODE_COUNT,
start_task=start_task,
max_tasks_per_node=_CORES_PER_NODE
)
I imaging that I need to use batch.models.ImageReference() to create my image reference... but I do not know how to use it.
Yes, I checked the documentation, which says the following:
A reference to an Azure Virtual Machines Marketplace image or a custom
Azure Virtual Machine image.
It lists the parameters as:
publisher (str)
offer (str)
sku (str)
version (str)
virtual_machine_image_id (str)
However, the parameter virtual_machine_image_id does not exists... In other words, batch.models.ImageReference(virtual_machine_image_id) is not allowed.
How can I use a custom image for my Pool?
UPDATE
So I figured out how to use a custom image... it turns out that no matter how many times I uninstall the azure python libraries and re-install them, the virtual_machine_image_id is never available.
I then went here downloaded the zip. Opened it up, checked the ImageReference class and low-and-behold, the virtual_machine_image_id was available in the __init__ function of the ImageReference class. I then downloaded the python wheel and used pip to install it. Boom it worked.
Or so I thought.
I then had to fight though trying to figure out what the node_agent_sku_id is... only by manually creating a Pool and seeing the Batch Node Agent SKU ID field did I manage to find it.
Now I am struggling with the Authentication...
The error I am getting is:
Server failed to authenticate the request. Make sure the value of
Authorization header is formed correctly including the signature.
AuthenticationErrorDetail: The specified type of authentication
SharedKey is not allowed when external resources of type Compute are
linked.
azure.batch.models.batch_error.BatchErrorException: {'lang':
'en-US', 'value': 'Server failed to authenticate the request. Make
sure the value of Authorization header is formed correctly including
the
signature.\nRequestId:f8c1a3b3-65c4-4efd-9c4f-75c5c253f992\nTime:2017-10-15T20:36:06.7898187Z'}
From the error, I understand that I am not allowed to use SharedKeyCredentials:
credentials = batchauth.SharedKeyCredentials(_BATCH_ACCOUNT_NAME,
_BATCH_ACCOUNT_KEY)
batch_client = batch.BatchServiceClient(
credentials,
base_url=_BATCH_ACCOUNT_URL)
What must I do?
UPDATE 2
OK. User fpark has informed me that I need to use:
from azure.batch import BatchServiceClient
from azure.common.credentials import ServicePrincipalCredentials
credentials = ServicePrincipalCredentials(
client_id=CLIENT_ID,
secret=SECRET,
tenant=TENANT_ID,
resource="https://batch.core.windows.net/"
)
batch_client = BatchServiceClient(
credentials,
base_url=BATCH_ACCOUNT_URL
)
to authenticate. Unfortunately, that the code above is described here and makes no reference to what CLIENT_ID et. al are.
I then managed to find another piece of documentation which appears to be the same thing: https://azure-sdk-for-python.readthedocs.io/en/v2.0.0rc3/resourcemanagementauthentication.html
That page pointed me to another webpage: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal
I followed that tutorial and managed to finally authenticate my application...
NOTE
When creating your application, the tutorial will tell you:
Provide a name and URL for the application. Select either Web app /
API or Native for the type of application you want to create. After
setting the values, select Create.
DO NOT select Native as you will not have the option to get an application key...
Required Minimum Azure Batch SDK
The azure-batch Python SDK v4.0.0 or higher is required. Typically with pip install --upgrade azure-batch you should just get the newest version. If that doesn't work you can add the --force-reinstall option to pip to force it (with --upgrade).
Node Agent Sku Id
Regarding the proper value for node_agent_sku_id, you need to use the list_node_agent_skus operation to see the mapping between operating systems and the node agent skus supported.
Azure Active Directory Authentication Required
Regarding the auth issue, you must use Azure Active Directory authentication to use this feature. It will not work with shared key auth.
Documentation
More information can be found in this guide, including all pre-requisites needed to enable custom images.
I am using azure-batch==9.0.0, and it turns out the docs are not updated as per the package itself. Using id instead of virtual_machine_image_id fixes the problem for me.
I'm a beginner at Python and I've been working to geocode a database using Pandas and Geocoder on Jupyter.
Since the df is a little long (around 3000 rows), I'd like to use Google's Geocoding API.
I've already created a free key, but I have no idea what I'm supposed to do with it. Help?
By the way, my code looks like this:
import geocoder
import pandas as pd
geo = geocoder
df=pd.read_excel('hsp2.xlsx')
df['Coordinates']=df['Address'].apply(geo.google).apply(lambda x: x.latlng if x != None else None)
df.to_csv('output.csv', sep='|', encoding='iso8859_15')
You need to set the environment variable before you import geocoder:
import os
os.environ["GOOGLE_API_KEY"] = "api_key_from_google_cloud_platform"
import geocoder
geo = geocoder.google(address)
latlong = geo.latlng
Note:
As Murmel mentioned in the comments, environment variables containing keys (and in general) should not be set inside of your code.
If you are deploying this somewhere then set up enviroment variables in your configuration file. Or even better, as a secret in something like Kubernetes.
Else set the environment variable in bash with
export GOOGLE_API_KEY=api_key_from_google_cloud_platform
Basically there are 2 options:
passing the API KEY as environment variable:
GOOGLE_API_KEY=YOUR-API-KEY-HERE python your_program.py
passing the API KEY as argument:
geocoder.google('some address', key='YOUR-API-KEY-HERE')
Details
You are using the python library called geocoder, which itself is a wrapper around multiple geocoding services.
If you look at the pypi page of geocoder, you can (ignoring the rendering problems) find the docs for geocoder. In your case you probably want to have a look at the Google related part of the docs.
For basic usage this seams to work even without an API KEY, but you can specify one using 2 variants:
Environment variable: Like Roman already showed. This approach is meant to be used to not have the API KEY in code - for security reasons. (Probably you want to upload your code into a public repository, but without exposing your API KEY to everyone.)
"Key" parameter: You can also provide your API KEY by specifying it using the key parameter, like:
geocoder.google('some address', key='YOUR-API-KEY-HERE')
I am agree with Roman answer. You can use that and it is working. I am bit afraid if I use geocoder in loop then google will definately block my ip address ,so I go through git hub code and found that geocoder get google api key from os.environ.get('GOOGLE_API_KEY'). You can see that in the picture: