title: How to get all keys from deeply nested json using python?
body: <p>Problem Statement : Remove/Rename Special characters (#,$, Back slash, &amp; etc.) from json keys and replace in the main json file.</p>
  <p>Approach :</p>
  <ol>
  <li>I am trying to get all the keys of deeply nested json first.</li>
  <li>Check for special characters in each key then rename/replace and write back to the json file.</li>
  </ol>
  <p>Issue :</p>
  <ol>
  <li>Json I have is very deep nested so the logic i have written works for simple json but not deep nested json.</li>
  </ol>
  <p>Code :</p>
  <pre><code>import json
  import base64
  
  def getKeys(object, prev_key = None, keys = []):
      if type(object) != type({}):
          keys.append(prev_key)
          return keys
      new_keys = []
      for k, v in object.items():
          if prev_key != None:
              new_key = &quot;{}.{}&quot;.format(prev_key, k)
          else:
              new_key = k
          new_keys.extend(getKeys(v, new_key, []))
      return new_keys
  </code></pre>
  <p>Above code works for below json : It print all the json keys</p>
  <pre><code>json_string= '{&quot;Relate:0/name&quot;: &quot;securityhub-ec2-instance-managed-by-ssm-dc0c9f18&quot;,&quot;RelatedAWSResources:0/type&quot;: &quot;AWS::Config::ConfigRule&quot;,&quot;aws/securityhub/ProductName&quot;: &quot;Security Hub&quot;,&quot;aws/securityhub/CompanyName&quot;: &quot;AWS&quot;}'
  </code></pre>
  <p>Output :</p>
  <pre><code>['Relate:0/name', 'RelatedAWSResources:0/type', 'aws/securityhub/ProductName', 'aws/securityhub/CompanyName']
  </code></pre>
  <p>But it does not work for below json :</p>
  <pre><code>{
    &quot;version&quot;: &quot;0&quot;,
    &quot;id&quot;: &quot;ffd8a756-9fe6-fa54-af4e-cf85fa3d2896&quot;,
    &quot;detail-type&quot;: &quot;Security Hub Findings - Imported&quot;,
    &quot;source&quot;: &quot;aws.securityhub&quot;,
    &quot;account&quot;: &quot;220307202362&quot;,
    &quot;time&quot;: &quot;2021-10-17T14:26:25Z&quot;,
    &quot;region&quot;: &quot;us-west-2&quot;,
    &quot;resources&quot;: [
      &quot;arn:aws:securityhub:us-west-2::product/aws/securityhub/arn:aws:securityhub:us-west-2:220307202362:subscription/pci-dss/v/3.2.1/PCI.CW.1/finding/b5a325b7-eab1-439f-b14d-1dc52c3a423f&quot;
    ],
    &quot;detail&quot;: {
      &quot;findings&quot;: [
        {
          &quot;ProductArn&quot;: &quot;arn:aws:securityhub:us-west-2::product/aws/securityhub&quot;,
          &quot;Types&quot;: [
            &quot;Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS&quot;
          ],
          &quot;Description&quot;: &quot;This control checks for the CloudWatch metric filters using the following pattern { $.userIdentity.type = \&quot;Root\&quot; &amp;&amp; $.userIdentity.invokedBy NOT EXISTS &amp;&amp; $.eventType != \&quot;AwsServiceEvent\&quot; } It checks that the log group name is configured for use with active multi-region CloudTrail, that there is at least one Event Selector for a Trail with IncludeManagementEvents set to true and ReadWriteType set to All, and that there is at least one active subscriber to an SNS topic associated with the alarm.&quot;,
          &quot;Compliance&quot;: {
            &quot;Status&quot;: &quot;FAILED&quot;,
            &quot;StatusReasons&quot;: [
              {
                &quot;Description&quot;: &quot;Multi region CloudTrail with the required configuration does not exist in the account&quot;,
                &quot;ReasonCode&quot;: &quot;CLOUDTRAIL_MULTI_REGION_NOT_PRESENT&quot;
              }
            ],
            &quot;RelatedRequirements&quot;: [
              &quot;PCI DSS 7.2.1&quot;
            ]
          },
          &quot;ProductName&quot;: &quot;Security Hub&quot;,
          &quot;FirstObservedAt&quot;: &quot;2021-10-17T14:26:18.383Z&quot;,
          &quot;CreatedAt&quot;: &quot;2021-10-17T14:26:18.383Z&quot;,
          &quot;LastObservedAt&quot;: &quot;2021-10-17T14:26:21.346Z&quot;,
          &quot;CompanyName&quot;: &quot;AWS&quot;,
          &quot;FindingProviderFields&quot;: {
            &quot;Types&quot;: [
              &quot;Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS&quot;
            ],
            &quot;Severity&quot;: {
              &quot;Normalized&quot;: 40,
              &quot;Label&quot;: &quot;MEDIUM&quot;,
              &quot;Product&quot;: 40,
              &quot;Original&quot;: &quot;MEDIUM&quot;
            }
          },
          &quot;ProductFields&quot;: {
            &quot;StandardsArn&quot;: &quot;arn:aws:securityhub:::standards/pci-dss/v/3.2.1&quot;,
            &quot;StandardsSubscriptionArn&quot;: &quot;arn:aws:securityhub:us-west-2:220307202362:subscription/pci-dss/v/3.2.1&quot;,
            &quot;ControlId&quot;: &quot;PCI.CW.1&quot;,
            &quot;RecommendationUrl&quot;: &quot;https://docs.aws.amazon.com/console/securityhub/PCI.CW.1/remediation&quot;,
            &quot;StandardsControlArn&quot;: &quot;arn:aws:securityhub:us-west-2:220307202362:control/pci-dss/v/3.2.1/PCI.CW.1&quot;,
            &quot;aws/securityhub/ProductName&quot;: &quot;Security Hub&quot;,
            &quot;aws/securityhub/CompanyName&quot;: &quot;AWS&quot;,
            &quot;aws/securityhub/annotation&quot;: &quot;Multi region CloudTrail with the required configuration does not exist in the account&quot;,
            &quot;Resources:0/Id&quot;: &quot;arn:aws:iam::220307202362:root&quot;,
            &quot;aws/securityhub/FindingId&quot;: &quot;arn:aws:securityhub:us-west-2::product/aws/securityhub/arn:aws:securityhub:us-west-2:220307202362:subscription/pci-dss/v/3.2.1/PCI.CW.1/finding/b5a325b7-eab1-439f-b14d-1dc52c3a423f&quot;
          },
          &quot;Remediation&quot;: {
            &quot;Recommendation&quot;: {
              &quot;Text&quot;: &quot;For directions on how to fix this issue, consult the AWS Security Hub PCI DSS documentation.&quot;,
              &quot;Url&quot;: &quot;https://docs.aws.amazon.com/console/securityhub/PCI.CW.1/remediation&quot;
            }
          },
          &quot;SchemaVersion&quot;: &quot;2018-10-08&quot;,
          &quot;GeneratorId&quot;: &quot;pci-dss/v/3.2.1/PCI.CW.1&quot;,
          &quot;RecordState&quot;: &quot;ACTIVE&quot;,
          &quot;Title&quot;: &quot;PCI.CW.1 A log metric filter and alarm should exist for usage of the \&quot;root\&quot; user&quot;,
          &quot;Workflow&quot;: {
            &quot;Status&quot;: &quot;NEW&quot;
          },
          &quot;Severity&quot;: {
            &quot;Normalized&quot;: 40,
            &quot;Label&quot;: &quot;MEDIUM&quot;,
            &quot;Product&quot;: 40,
            &quot;Original&quot;: &quot;MEDIUM&quot;
          },
          &quot;UpdatedAt&quot;: &quot;2021-10-17T14:26:18.383Z&quot;,
          &quot;WorkflowState&quot;: &quot;NEW&quot;,
          &quot;AwsAccountId&quot;: &quot;220307202362&quot;,
          &quot;Region&quot;: &quot;us-west-2&quot;,
          &quot;Id&quot;: &quot;arn:aws:securityhub:us-west-2:220307202362:subscription/pci-dss/v/3.2.1/PCI.CW.1/finding/b5a325b7-eab1-439f-b14d-1dc52c3a423f&quot;,
          &quot;Resources&quot;: [
            {
              &quot;Partition&quot;: &quot;aws&quot;,
              &quot;Type&quot;: &quot;AwsAccount&quot;,
              &quot;Region&quot;: &quot;us-west-2&quot;,
              &quot;Id&quot;: &quot;AWS::::Account:220307202362&quot;
            }
          ]
        }
      ]
    }
  } 
  </code></pre>
  <p>Strip punctuation function :</p>
  <pre><code>import string
  from typing import Optional, Iterable, Union
  
  
  delete_dict = {sp_character: '' for sp_character in string.punctuation}
  
  PUNCT_TABLE = str.maketrans(delete_dict)
  
  
  def strip_punctuation(s: str,
                        exclude_chars: Optional[Union[str, Iterable]] = None) -&gt; str:
      &quot;&quot;&quot;
      Remove punctuation and spaces from a string.
  
      If `exclude_chars` is passed, certain characters will not be removed
      from the string.
  
      &quot;&quot;&quot;
      punct_table = PUNCT_TABLE.copy()
      if exclude_chars:
          for char in exclude_chars:
              punct_table.pop(ord(char), None)
  
      # Next, remove the desired punctuation from the string
      return s.translate(punct_table) 
  </code></pre>
  <p>Usage:</p>
  <pre><code>cleaned_keys = {json data}
  for key, expected_key in cleaned_keys.items():
      actual_key = strip_punctuation(key)
  </code></pre>