Facing `UnboundLocalError: local variable 'post_properties' referenced before assignment` while creating schema from open API
SUMMARY
I am trying to generate schema from Open API json (Nutanix subnet API) and it gives me UnboundLocalError: local variable 'post_properties' referenced before assignment error.
Error is coming from : https://github.com/ansible-community/ansible.content_builder/blob/1a8071e914aa1f25a84670b320c2295736a00818/roles/module_openapi_security/templates/doc_generator.py#L904
ISSUE TYPE
- Bug Report
COMPONENT NAME
module_openapi
ANSIBLE VERSION
ansible [core 2.15.6]
config file = None
configured module search path = ['/Users/pradeep.bhati/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
ansible collection location = /Users/pradeep.bhati/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.9.18 (main, Nov 2 2023, 17:01:24) [Clang 14.0.0 (clang-1400.0.29.202)] (/usr/local/opt/[email protected]/bin/python3.9)
jinja version = 3.0.3
libyaml = True
CONFIGURATION
CONFIG_FILE() = None
OS / ENVIRONMENT
Mac OS Monterey
STEPS TO REPRODUCE
Create build.yaml and manifest.yaml as per below files. Download open api yaml from https://developers.nutanix.com/api/v1/namespaces/networking/versions/v4.0.b1/yaml and convert it using https://editor-next.swagger.io/ to json format.
build.yaml
---
- hosts: localhost
gather_facts: yes
roles:
- ansible.content_builder.run
manifest.yaml
---
collection:
path: /Users/pradeep.bhati/work/codebase/codegen/content_builder
namespace: nutanix
name: ncp
plugins:
- type: module_openapi
name: subnets
module_version: 1.0.0
rm_swagger_json: /Users/pradeep.bhati/Downloads/openapi3_0.json
api_object_path: /networking/v4.0.b1/config/subnets
resource: subnets
unique_key: ""
author: "[email protected]"
Error:
~/work/codebase/codegen/content_builder ❯ ansible-playbook build.yaml -e manifest_file=manifest.yaml ansible1 12:05:08 PM
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [localhost] *********************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************
ok: [localhost]
TASK [ansible.content_builder.run : Validate task input against defined schema] ******************************************************************************
ok: [localhost]
TASK [ansible.content_builder.run : Load settings from manifest file] ****************************************************************************************
ok: [localhost]
TASK [Start scaffolding] *************************************************************************************************************************************
TASK [ansible.content_builder.init : Create the collection directory structure] ******************************************************************************
ok: [localhost] => (item=plugins/modules)
ok: [localhost] => (item=plugins/module_utils)
ok: [localhost] => (item=plugins/module_utils/common/)
ok: [localhost] => (item=plugins/plugin_utils)
ok: [localhost] => (item=plugins/lookup)
ok: [localhost] => (item=plugins/filter)
ok: [localhost] => (item=plugins/action)
ok: [localhost] => (item=plugins/inventory)
ok: [localhost] => (item=plugins/cache)
ok: [localhost] => (item=plugins/test)
ok: [localhost] => (item=docs)
ok: [localhost] => (item=meta)
ok: [localhost] => (item=tests)
TASK [ansible.content_builder.init : Touch the __init__.py in each directory] ********************************************************************************
ok: [localhost] => (item=plugins/modules)
ok: [localhost] => (item=plugins/module_utils)
ok: [localhost] => (item=plugins/module_utils/common/)
ok: [localhost] => (item=plugins/plugin_utils)
ok: [localhost] => (item=plugins/lookup)
ok: [localhost] => (item=plugins/filter)
ok: [localhost] => (item=plugins/action)
ok: [localhost] => (item=plugins/inventory)
ok: [localhost] => (item=plugins/cache)
ok: [localhost] => (item=plugins/test)
ok: [localhost] => (item=docs)
ok: [localhost] => (item=meta)
ok: [localhost] => (item=tests)
TASK [ansible.content_builder.init : Add license file to collection (default is gpl-3.0)] ********************************************************************
ok: [localhost]
TASK [ansible.content_builder.init : Add readme to collection] ***********************************************************************************************
ok: [localhost] => (item={'source': 'README.md.j2', 'destination': '/Users/pradeep.bhati/work/codebase/codegen/content_builder/README.md'})
ok: [localhost] => (item={'source': 'galaxy.yaml.j2', 'destination': '/Users/pradeep.bhati/work/codebase/codegen/content_builder/galaxy.yml'})
TASK [ansible.content_builder.init : Create the collection directory structure] ******************************************************************************
ok: [localhost] => (item=plugins/modules)
ok: [localhost] => (item=plugins/action)
ok: [localhost] => (item=tests)
TASK [ansible.content_builder.scaffold_plugins : Scaffold the specified plugins] *****************************************************************************
included: /Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/scaffold_plugins/tasks/template.yml for localhost => (item={'type': 'module_openapi', 'name': 'subnets', 'module_version': '1.0.0', 'rm_swagger_json': '/Users/pradeep.bhati/Downloads/openapi3_0.json', 'api_object_path': '/networking/v4.0.b1/config/subnets', 'resource': 'subnets', 'unique_key': '', 'author': '[email protected]'})
TASK [ansible.content_builder.scaffold_plugins : Debug message] **********************************************************************************************
ok: [localhost] => {
"msg": "Scaffolding subnets of type module_openapi"
}
TASK [ansible.content_builder.scaffold_plugins : Set facts] **************************************************************************************************
ok: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Set path to main plugin file for generic plugins] ***********************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Set path to main plugin file for specialized plugins] *******************************************************
ok: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Load docstring (if specified)] ******************************************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Load examples from example file (if specified)] *************************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Check to see if the plugin file exists] *********************************************************************
ok: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Check if documentation string can be found] *****************************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Extract documentation from plugin (for existing plugin)] ****************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Fail if no docstring could be found] ************************************************************************
skipping: [localhost]
TASK [ansible.content_builder.scaffold_plugins : Extract examples from plugin (for existing plugin)] *********************************************************
skipping: [localhost]
TASK [Start scaffolding specialized plugin] ******************************************************************************************************************
TASK [Generate security content] *****************************************************************************************************************************
TASK [ansible.content_builder.module_openapi_security : Get the CURRENT WORKING DIR] *************************************************************************
ok: [localhost]
TASK [ansible.content_builder.module_openapi_security : Create temporary build directory] ********************************************************************
changed: [localhost]
TASK [ansible.content_builder.module_openapi_security : EXECUTE the python script] ***************************************************************************
fatal: [localhost -> 127.0.0.1]: FAILED! => {"changed": false, "cmd": ["python3", "/Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/module_openapi_security/templates/doc_generator.py", "/Users/pradeep.bhati/Downloads/openapi3_0.json", "/networking/v4.0.b1/config/subnets", "subnets", "1.0.0", "subnets", "nutanix", "ncp", "", "[email protected]", "/var/folders/4w/z2gbpknj63zd_mx6003hhpjh0000gp/T/ansible.qjnr_fm0build"], "delta": "0:00:00.167435", "end": "2023-11-10 12:09:39.275832", "msg": "non-zero return code", "rc": 1, "start": "2023-11-10 12:09:39.108397", "stderr": "Traceback (most recent call last):\n File \"/Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/module_openapi_security/templates/doc_generator.py\", line 914, in <module>\n main()\n File \"/Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/module_openapi_security/templates/doc_generator.py\", line 904, in main\n post_properties,\nUnboundLocalError: local variable 'post_properties' referenced before assignment", "stderr_lines": ["Traceback (most recent call last):", " File \"/Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/module_openapi_security/templates/doc_generator.py\", line 914, in <module>", " main()", " File \"/Users/pradeep.bhati/.ansible/collections/ansible_collections/ansible/content_builder/roles/module_openapi_security/templates/doc_generator.py\", line 904, in main", " post_properties,", "UnboundLocalError: local variable 'post_properties' referenced before assignment"], "stdout": "", "stdout_lines": []}
NO MORE HOSTS LEFT *******************************************************************************************************************************************
PLAY RECAP ***************************************************************************************************************************************************
localhost : ok=15 changed=1 unreachable=0 failed=1 skipped=7 rescued=0 ignored=0
EXPECTED RESULTS
Code generation should go fine.
ACTUAL RESULTS
Failing with error as above.
I was able to overcome this issue by moving line https://github.com/ansible-community/ansible.content_builder/blob/15a074270083fe091fb79a9f14f2d7b0272fdcd1/roles/module_openapi_security/templates/doc_generator.py#L875
Above one line, so it looks like this
post_properties = OrderedDict()
if request_fields:
post_properties.update(
I'm having the same issue as OP.
@kksat fix let me continue but I then ran into an issue with module_openapi_security__' is undefined. Not sure if related or not.