1

I am deliberating about how to transfer the complex information from a JSON API response to (several) Python objects. I have included the (lengthy) model response below. Note that some values are not always included in the response, and some values are a list of dictionaries.

Is there an "easy" way to map the JSON response to Python objects? How would I ideally lay out the classes?

Model JSON response:

{
   "accounts" : {
      "accounting_reference_date" : {
         "day" : "integer",
         "month" : "integer"
      },
      "last_accounts" : {
         "made_up_to" : "date",
         "period_end_on" : "date",
         "period_start_on" : "date",
         "type" : "string"
      },
      "next_accounts" : {
         "due_on" : "date",
         "overdue" : "boolean",
         "period_end_on" : "date",
         "period_start_on" : "date"
      },
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "annual_return" : {
      "last_made_up_to" : "date",
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "branch_company_details" : {
      "business_activity" : "string",
      "parent_company_name" : "string",
      "parent_company_number" : "string"
   },
   "can_file" : "boolean",
   "company_name" : "string",
   "company_number" : "string",
   "company_status" : "string",
   "company_status_detail" : "string",
   "confirmation_statement" : {
      "last_made_up_to" : "date",
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "date_of_cessation" : "date",
   "date_of_creation" : "date",
   "etag" : "string",
   "external_registration_number" : "string",
   "foreign_company_details" : {
      "accounting_requirement" : {
         "foreign_account_type" : "string",
         "terms_of_account_publication" : "string"
      },
      "accounts" : {
         "account_period_from" : {
            "day" : "integer",
            "month" : "integer"
         },
         "account_period_to" : {
            "day" : "integer",
            "month" : "integer"
         },
         "must_file_within" : {
            "months" : "integer"
         }
      },
      "business_activity" : "string",
      "company_type" : "string",
      "governed_by" : "string",
      "is_a_credit_finance_institution" : "boolean",
      "originating_registry" : {
         "country" : "string",
         "name" : "string"
      },
      "registration_number" : "string"
   },
   "has_been_liquidated" : "boolean",
   "has_charges" : "boolean",
   "has_insolvency_history" : "boolean",
   "is_community_interest_company" : "boolean",
   "jurisdiction" : "string",
   "last_full_members_list_date" : "date",
   "links" : {
      "charges" : "string",
      "filing_history" : "string",
      "insolvency" : "string",
      "officers" : "string",
      "persons_with_significant_control" : "string",
      "persons_with_significant_control_statements" : "string",
      "registers" : "string",
      "self" : "string"
   },
   "partial_data_available" : "string",
   "previous_company_names" : [
      {
         "ceased_on" : "date",
         "effective_from" : "date",
         "name" : "string"
      }
   ],
   "registered_office_address" : {
      "address_line_1" : "string",
      "address_line_2" : "string",
      "care_of" : "string",
      "country" : "string",
      "locality" : "string",
      "po_box" : "string",
      "postal_code" : "string",
      "premises" : "string",
      "region" : "string"
   },
   "registered_office_is_in_dispute" : "boolean",
   "sic_codes" : [
      "string"
   ],
   "subtype" : "string",
   "type" : "string",
   "undeliverable_registered_office_address" : "boolean"
}

2 Answers 2

3

Python provides a json module, from which you can "load" the data from JSON to Python. In this example, if response is a variable representing your big blob of JSON, you can do:

import json
py_object_collection = json.loads(response)

If this does not work for you, it will require that you specify the expected output result in your question.

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

Comments

0

If I understand properly, and you want to take a json object and abstract it to a class, you can do this with a class and setattr().

This goes through each key in the json, if the value of the key is not a dict, it sets the attribute (with the name of the key) to the value.

If the value of the key is a dict it creates a new instance of JsonToObject, and repeats the above process with the new object, and sets the attribute (with the name of the original key) to the new instance of JsonToObject.

import json

class JsonToObject:

    def __init__(self, json_object):
        self.json_object = json_object
        self.keys = json_object.keys()
        self.setup(json_object)

    def setup(self, d):
        for key, item in d.items():
            if isinstance(item, dict):
                new_object = JsonToObject(item)
                setattr(self, key, new_object)
            else:
                setattr(self, key, item)

# I am reading from a file with the contents you specified.
# If you are reading the json from a variable instead of a file,
# take away the `with open...` line and use 
# `d = json.loads(json_content)` instead of `d = json.load(f)`
with open("test.json", "rb") as f:
    d = json.load(f)

json_obj = JsonToObject(d)

print(json_obj.accounts.accounting_reference_date.day)
print(json_obj.annual_return.next_due)

Otherwise, if you only want to load json into memory and access it like a python dictionary:

import json

with open("test.json", "rb") as f:
    d = json.load(f)

print(d["accounts"]["accounting_reference_date"]["day"])
print(d["annual_return"]["next_due"])

Both examples give the same output:

integer
date

Comments

Your Answer

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