0

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.

3
  • did you install all the necessary modules (you clearly didnt install apt_pkg)? why are you using az cli and not Azure Python SDK? did you auth the cli before running this "code"? nothing gets returned because you need to auth most likely Commented Jun 15, 2019 at 7:50
  • You have exposed your credentials (user and password) in your upper code snippet. Make sure to remove them! Commented Jun 15, 2019 at 7:54
  • thanks mc51 i forgot to remove it. Hi Gleb, I authenticated azure cli before running the cmd using az login. and then ran python script. I installed apt_pkg twice. Not sure it still gives me the same error Also I've the requirement of running the cli code as most of the engineers in my team are familiar with azure cli. and also wrapping with azure cli with python works for them Commented Jun 15, 2019 at 8:34

1 Answer 1

2

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.

enter image description here

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.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks peter for doing regress testing, I've also resolved the same issue by removing shell = True, I'm not sure what is wrong there with shell = true but on Linux it is creating issues. Thanks once again. I'm marking this as answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.