0

I have a JSON file which I want to take and put into python objects. It has two parts, staff and assets and I want to load them into two separate ones. Here is a sample of the JSON file:

{
"staff": [
    {
        "id": "DA7153",
        "name": [
            "Fran\u00c3\u00a7ois",
            "Ullman"
        ],
        "department": {
            "name": "Admin"
        },
        "server_admin": "true"
    },
    {
        "id": "DA7356",
        "name": [
            "Bob",
            "Johnson"
        ],
        "department": {
            "name": "Admin"
        },
        "server_admin": "false"
    },
],
"assets": [
    {
        "asset_name": "ENGAGED SLOTH",
        "asset_type": "File",
        "owner": "DA8333",
        "details": {
            "security": {
                "cia": [
                    "HIGH",
                    "INTERMEDIATE",
                    "LOW"
                ],
                "data_categories": {
                    "Personal": "true",
                    "Personal Sensitive": "true",
                    "Customer Sensitive": "true"
                }
            },
            "retention": 2
        },
        "file_type": "Document",
        "server": {
            "server_name": "ISOLATED UGUISU",
            "ip": [
                10,
                234,
                148,
                52
            ]
        }
    },
    {
        "asset_name": "ISOLATED VIPER",
        "asset_type": "File",
        "owner": "DA8262",
        "details": {
            "security": {
                "cia": [
                    "LOW",
                    "HIGH",
                    "LOW"
                ],
                "data_categories": {
                    "Personal": "false",
                    "Personal Sensitive": "false",
                    "Customer Sensitive": "true"
                }
            },
            "retention": 2
        },
    },
]

I have tried to create a class for staff but whenever I do I get the error "TypeError: dict expected at most 1 argument, got 3"

The code I am using looks like this:

import json

with open('Admin_sample.json') as f:
    admin_json = json.load(f)

class staffmem(admin_json):
    def __init__(self, id, name, department, server_admin):
        self.id = id
        self.name = name
        self.deparment = department[name]
        self.server_admin = server_admin

    def staffid(self):
        return self.id

print(staffmem.staffid)

I just can't work it out. Any help would be appreciated.

Thanks.

bi1806398
  • 13
  • 2
  • What will you do with internal objects like Departments? – urban Jun 16 '20 at 14:23
  • [How to convert JSON data into a Python object](https://stackoverflow.com/questions/6578986/how-to-convert-json-data-into-a-python-object) – Sercan Jun 16 '20 at 14:23
  • Are you trying to inherit your class from the dict value??? Looks liek an error. Then you use a class in place of its instance to take an instance attribute... which is a function. ut you don't call it. – LiMar Jun 16 '20 at 14:24

1 Answers1

0

The following should be a good starting point but you have to fix few things. Note that I am using get() everywhere to provide a "safe" default if the keys do not exist:

import json

class StaffMember:
    def __init__(self, json_entry):
        self.name = ",".join(json_entry.get("name"))
        self.id = json_entry.get("id")
        self.dept = json_entry.get("department", {}).get("name")
        self.server_admin = (
            True
            if json_entry.get("server_admin", "false").lower() == "true"
            else False
        )

# Get the data
with open("/tmp/test.data") as f:
    data = json.load(f)

# For every entry in the data["staff"] create object and index them by ID
all_staff = {}
for json_entry in data.get("staff", []):
    tmp = StaffMember(json_entry)
    all_staff[tmp.id] = tmp


print(all_staff)
print(all_staff['DA7153'].name)

Output:

$ python3 /tmp/test.py
{'DA7153': <__main__.StaffMember object at 0x1097b2d50>, 'DA7356': <__main__.StaffMember object at 0x1097b2d90>}
François,Ullman

Potential Improvements:

  • Unicode handling
  • Add getters/setters
  • Instead of passing json dict in ctor, consider adding a from_json() static method to create your object
  • Error handling on missing values
  • Consider using a dataclass in py3 if this object is used to only/mainly store data
  • Consider the namedtuple approach from the comments if you do not intend to modify the object (read-only)

Notes:

  • The json you provided is not correct - you will need to fix it
  • Your syntax is wrong in your example and the naming convention is not much pythonic (read more here
urban
  • 5,392
  • 3
  • 19
  • 45
  • 1
    Good start, but I would separate object initialization from navigating the JSON object. `StaffMember.__init__` should be "dumb": give it a name, id, dept, and admin status, and simply save those values. A separate `classmethod` can be responsible for extracting values from an object before creating a new object. – chepner Jun 16 '20 at 14:43
  • @chepner I would go with a staticmethod there. I added some ideas on how to improve – urban Jun 16 '20 at 14:45
  • This is the use case class methods were created for. (Well, almost. But it's the use case it turned out they were useful for.) – chepner Jun 16 '20 at 14:46