I'm getting below error when i run python script on Ubuntu 16.04.
It works fine on Windows when I run the same code but not sure which package is not installed properly.
import subprocess
import json
#one vnet and one subnet in the resourcegroup.
def get_vnet_name(resourcegroup):
get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
a=get_vnet.stdout.decode('utf-8')
d=json.loads(a)
for item in d:
vname=item["name"]
subnets=item["subnets"]
for i in subnets:
subnetname=i["name"]
return vname,subnetname
def create_vm(vm_resourcegroup,vm_name, vm_image,vm_username, vm_passowrd,vm_vnet,vm_subnet, vm_size):
create_vm_command=["az","vm","create","--resource-group",vm_resourcegroup,"--name",vm_name,"--image",vm_image, "--admin-username", vm_username,"--admin-password",vm_passowrd,"--vnet-name",vm_vnet,"--subnet",vm_subnet,"--size", vm_size]
create_vm=subprocess.run(create_vm_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
return
if __name__=="__main__":
rscgroup_name="vm-test-group"
avm_name="testvm1"
avm_image="Win2019Datacenter"
avm_username="myuser"
avm_password="mypassword"
avm_size="Standard_D2_V3"
vault_name = "aqrahkeyvault"
certificate_name = "staticwebsite"
avm_vnet,avm_subnet=get_vnet_name(rscgroup_name)
create_vm(rscgroup_name,avm_name,avm_image,avm_username,avm_password,avm_vnet,avm_subnet,avm_size)
Below is the error which I'm getting related to json.decoder :
root@linuxvm:/home/azureuser# python3.6 test2.py
Traceback (most recent call last):
File "test2.py", line 32, in <module>
avm_vnet,avm_subnet=get_vnet_name(rscgroup_name)
File "test2.py", line 9, in get_vnet_name
d=json.loads(a)
File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 2 column 6 (char 6)
I've tried installing python and that did not resolve the issue.
I tried to reproduce your issue and successfully find out the reason. Actually, your script is correct basically, but you may not consider for a case that the az
command not return any result to stdout
.
For example, there is a non-existing resource group in my subscription, such as non-exist-rg
. If I pass it as the value of parameter --resource-group
, the script below will return error information to stderr
, the stdout
value is b''
.
import subprocess
resourcegroup = 'non-exist-rg'
get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
The result of stdout
& stderr
as below.
>>> get_vnet.stdout
b''
>>> get_vnet.stderr
b"ERROR: Resource group 'non-exist-rg' could not be found.\r\n"
So if you pass the stdout
value to json.loads
function, it will throw the same issue as yours, json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
, because json.loads
can not process empty content. And in here, the decode
function for the bytes
value of stdout
or stderr
is not necessary for json.loads
which can received bytes
value as the figure below.
So to fix it, the solution is to check the stdout
value whether be empty or the stderr
value whether be not empty.
def get_vnet_name(resourcegroup):
get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
# decode for stdout is not necessary
# a=get_vnet.stdout.decode('utf-8')
vname,subnetname = '', ''
if get_vnet.stdout == b'':
d=json.loads(get_vnet.stdout)
for item in d:
vname=item["name"]
subnets=item["subnets"]
for i in subnets:
subnetname=i["name"]
return vname,subnetname
Then, you need to check the vname
& subnetname
values before invoke create_vm
method.
Hope it helps.