Python YAML解析引发KeyError。

huangapple go评论47阅读模式
英文:

Python YAML parsing raising KeyError

问题

我正在尝试构建一份审计报告,其中用户将访问我们的Kafka环境中的哪些主题。我编写了一段Python代码来完成这个任务,但出于某种原因它停止工作了,我不知道为什么。

我有以下代码:

import yaml
import glob

yaml_file_names = glob.glob('/tmp/kafka-topics/topics/*.yaml')
file1 = open("Access_Audit_Report_testenv.txt", "w")
file1.close()
for each_yaml_file in yaml_file_names:
    with open(each_yaml_file) as f:
        document = yaml.safe_load(f)
        current_context = document["context"]
        for each_project in document['projects']:
            file1 = open("Access_Audit_Report_testenv.txt", "a")
            for each_topic in each_project['topics']:
                topic_name = '.'.join([current_context, each_project['name'], each_topic['name']])
                file1.write(topic_name+"\n")
                file1.write('Consumers:\n')

                for each_entry in each_topic['consumers']:
                    file1.write(str(each_entry)+"\n")

                file1.write(''+"\n")
                file1.write('Producers:\n')

                for each_entry in each_topic['producers']:
                    file1.write(str(each_entry)+"\n")

                file1.write(''+"\n")
file1.close()

上述位置中的典型yaml文件如下所示:

---
context: "building_administration"
projects:
  - name: "school"
    topics:
      - name: "publish"
        plan: "default"
        consumers:
          - principal: "User:consumer_planning_test"
        producers:
          - principal: "User:producer_maintenance_test"

  - name: "iot"
    topics:
      - name: "metrics.publish"
        plan: "default"
        consumers:
          - principal: "User:consumer_maintenance_test"
          - principal: "User:consumer_planning_test"
          
        producers:
          - principal: "User:producer_planner_test"
...

期望的输出应该类似于这样:

building_administration.school.publish
Consumers:
{'principal': 'User:consumer_planning_test'}

Producers:
{'principal': 'User:producer_maintenance_test'}

iot.metrics.publish
Consumers:
{'principal': 'User:consumer_maintenance_test'}
{'principal': 'User:consumer_planning_test'}

Producers:
{'principal': 'User:producer_planner_test'}

我收到的错误是:

Traceback (most recent call last):
  File "/tmp/kafka-audit-builder/build-audit-testenv.py", line 13, in <module>
    for each_topic in each_project['topics']:
KeyError: 'topics'

所以我理解什么是KeyError,我只是不明白为什么会出现这个错误?特别是因为这段代码以前是正常工作的。任何想法或帮助将不胜感激。

谢谢!

英文:

I am trying to build an audit report of which users will have access to which topics in our kafka environment. I wrote a piece of python code that does this, but for some reason it stopped working, and I have no idea why.

I have the following code:

import yaml
import glob

yaml_file_names = glob.glob(&#39;/tmp/kafka-topics/topics/*.yaml&#39;)
file1 = open(&quot;Access_Audit_Report_testenv.txt&quot;, &quot;w&quot;)
file1.close()
for each_yaml_file in yaml_file_names:
    with open(each_yaml_file) as f:
        document = yaml.safe_load(f)
        current_context = document[&quot;context&quot;]
        for each_project in document[&#39;projects&#39;]:
            file1 = open(&quot;Access_Audit_Report_testenv.txt&quot;, &quot;a&quot;)
            for each_topic in each_project[&#39;topics&#39;]:
                topic_name = &#39;.&#39;.join([current_context, each_project[&#39;name&#39;], each_topic[&#39;name&#39;]])
                file1.write(topic_name+&quot;\n&quot;)
                file1.write(&#39;Consumers:\n&#39;)


                for each_entry in each_topic[&#39;consumers&#39;]:
                    file1.write(str(each_entry)+&quot;\n&quot;)

                file1.write(&#39;&#39;+&quot;\n&quot;)
                file1.write(&#39;Producers:\n&#39;)

                for each_entry in each_topic[&#39;producers&#39;]:
                    file1.write(str(each_entry)+&quot;\n&quot;)

                file1.write(&#39;&#39;+&quot;\n&quot;)
file1.close()

A typical yaml file in the above-mentioned location looks like this:

---
context: &quot;building_administration&quot;
projects:
  - name: &quot;school&quot;
    topics:
      - name: &quot;publish&quot;
        plan: &quot;default&quot;
        consumers:
          - principal: &quot;User:consumer_planning_test&quot;
        producers:
          - principal: &quot;User:producer_maintenance_test&quot;

  - name: &quot;iot&quot;
    topics:
      - name: &quot;metrics.publish&quot;
        plan: &quot;default&quot;
        consumers:
          - principal: &quot;User:consumer_maintenance_test&quot;
          - principal: &quot;User:consumer_planning_test&quot;
          
        producers:
          - principal: &quot;User:producer_planner_test&quot;
...
      

The desired output should look something like this:

building_administration.school.publish
Consumers:
{&#39;principal&#39;: &#39;User:consumer_planning_test&#39;}

Producers:
{&#39;principal&#39;: &#39;User:producer_maintenance_test&#39;}

iot.metrics.publish
Consumers:
{&#39;principal&#39;: &#39;User:consumer_maintenance_test&#39;}
{&#39;principal&#39;: &#39;User:consumer_planning_test&#39;}

Producers:
{&#39;principal&#39;: &#39;User:producer_planner_test&#39;}

The error I am getting is:

Traceback (most recent call last):
  File &quot;/tmp/kafka-audit-builder/build-audit-testenv.py&quot;, line 13, in &lt;module&gt;
    for each_topic in each_project[&#39;topics&#39;]:
KeyError: &#39;topics&#39;

So I understand what a KeyError is, I just don't understand why I am seeing it? Especially since this code had been working before. Any ideas or help will really be greatly appreciated.

Thank you!

答案1

得分: 1

感谢@franklinsijo在评论中的帮助,我通过调整我的代码来解决了我的问题,如下所示:

import yaml
import glob

# yaml_file_names = glob.glob('/builds/devops1/kafka-topics/topics/*.yaml')
yaml_file_names = glob.glob('/tmp/kafka-topics/topics/*.yaml')
file1 = open("Access_Audit_Report_testenv.txt", "w")
file1.close()
for each_yaml_file in yaml_file_names:
    with open(each_yaml_file) as f:
        document = yaml.safe_load(f)
        current_context = document["context"]
        print('###################')
        print(current_context)
        for each_project in document['projects']:
            file1 = open("Access_Audit_Report_testenv.txt", "a")
            if 'topics' in each_project:
                for each_topic in each_project['topics']:
                    topic_name = '.'.join([current_context, each_project['name'], each_topic['name']])
                    print(topic_name)
                    file1.write(topic_name+"\n")
                    file1.write('Consumers:\n')

                    if 'consumers' in each_topic:
                        for each_entry in each_topic['consumers']:
                            file1.write(str(each_entry)+"\n")
                            print('Consumer:', each_entry)

                    file1.write('Producers:\n')

                    if 'producers' in each_topic:
                        for each_entry in each_topic['producers']:
                            file1.write(str(each_entry)+"\n")
                            print('Producer:', each_entry)
                    file1.write(''+"\n")
            else:
                continue
file1.close()

如果您需要进一步的帮助,请告诉我。

英文:

Thanks to @franklinsijo in the comments, I was able to solve my problem by adapting my code to the following:

import yaml
import glob

# yaml_file_names = glob.glob(&#39;/builds/devops1/kafka-topics/topics/*.yaml&#39;)
yaml_file_names = glob.glob(&#39;/tmp/kafka-topics/topics/*.yaml&#39;)
file1 = open(&quot;Access_Audit_Report_testenv.txt&quot;, &quot;w&quot;)
file1.close()
for each_yaml_file in yaml_file_names:
    with open(each_yaml_file) as f:
        document = yaml.safe_load(f)
        current_context = document[&quot;context&quot;]
        print(&#39;###################&#39;)
        print(current_context)
        for each_project in document[&#39;projects&#39;]:
            file1 = open(&quot;Access_Audit_Report_testenv.txt&quot;, &quot;a&quot;)
            if &#39;topics&#39; in each_project:
                for each_topic in each_project[&#39;topics&#39;]:
                    topic_name = &#39;.&#39;.join([current_context, each_project[&#39;name&#39;], each_topic[&#39;name&#39;]])
                    print(topic_name)
                    file1.write(topic_name+&quot;\n&quot;)
                    file1.write(&#39;Consumers:\n&#39;)

                    if &#39;consumers&#39; in each_topic:
                        for each_entry in each_topic[&#39;consumers&#39;]:
                            file1.write(str(each_entry)+&quot;\n&quot;)
                            print(&#39;Consumer:&#39;, each_entry)

                    file1.write(&#39;Producers:\n&#39;)

                    if &#39;producers&#39; in each_topic:
                        for each_entry in each_topic[&#39;producers&#39;]:
                            file1.write(str(each_entry)+&quot;\n&quot;)
                            print(&#39;Producer:&#39;, each_entry)
                    file1.write(&#39;&#39;+&quot;\n&quot;)
            else:
                continue
file1.close()

huangapple
  • 本文由 发表于 2023年6月12日 16:11:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454691.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定