Importing JSON data from a file as class instances - python

class Company:
def __init__(self, company_id, name):
self.company_id = company_id
self.name = name
I have a class named Company (class shown above), and I am trying to add companies into this program using this JSON file:
[
{
"id": "companyA",
"name": "Apple Farm"
},
{
"id": "companyB",
"name": "Buzzing Bees"
},
{
"id": "companyC",
"name": "Cat Corporate"
},
{
"id": "companyD",
"name": "Dog Dentists Limited"
}
]
Right now I, know how to add each company individually like this:
c = Company(company[0]['id'], company[0]['name'])
However, I want to create all of them with a for loop which creates these companies, and so that I can access them by their company_id.
How can I do this?

I dint understand the last part of the question where you say you want to "call them by company IDs"..
If you dont want to handle each objects independently and reference it by their name then storing them in a dict is a useful way. A dictionary comprehension will be the easiest way to do it.
company_objects = {company['id']: Company(company['id'], company['name']) for company in companies}
Now you should be able to access them as company_objects['companyA']
If you change the JSON definition slightly as below:
{
"company_id": "companyA",
"name": "Apple Farm"
}
You will be able to even optimize the dictionary comprehension as below:
{company['company_id']: Company(**company) for company in companies}

You can first retrieve the JSON code with the json library:
import json
with open("path/to/file.json") as jsonFile: # Replace "path/to/file.json" with the path to your JSON file
companies = json.load(jsonFile)
Then, you can create a dictionary to store the companies:
companyDict = {}
You then iterate through all the companies in the JSON file. Then, for every dictionary inside the JSON file, create a Company:
for company in companies:
companyDict[company["id"]] = Company(company["id"], company["name"])
You can then access your company like this:
companyA = companyDict["companyA"] # You can replace the key with the company ID

From the looks of your class, it looks as though it is not meant to contain information pertaining to multiple companies. Rather, you should create a separate class instance for each company.
Using the object you provided as such:
companies = [
{
"id": "companyA",
"name": "Apple Farm"
},
{
"id": "companyB",
"name": "Buzzing Bees"
},
{
"id": "companyC",
"name": "Cat Corporate"
},
{
"id": "companyD",
"name": "Dog Dentists Limited"
}
]
you can create a class for each company as such:
company_classes = [Company(company.id, company.name) for company in companies]
this will create a list of company objects.

Related

Improperly formatted json? [duplicate]

This question already has answers here:
Python list of dictionaries search
(24 answers)
Closed last month.
First, I am new to Python and working with JSON.
I am trying to extract just one value from an API request response, and I am having a difficult time parsing out the data I need.
I have done a lot of searching on how to do this, but most all the examples use a string or file that is formatted is much more basic than what I am getting.
I understand the key - value pair concept but I am unsure how to reference the key-value I want. I think it has something to do with the response having multiple objects having the same kay names. Or maybe the first line "Bookmark" is making things goofy.
The value I want is for the model name in the response example below.
That's all I need from this. Any help would be greatly appreciated.
{
"Bookmark": "<B><P><p>SerNum</p><p>Item</p></P><D><f>false</f><f>false</f></D><F><v>1101666</v><v>ADDMASTER IJ7102-23E</v></F><L><v>123456</v><v>Model Name</v></L></B>",
"Items": [
[
{
"Name": "SerNum",
"Value": "123456"
},
{
"Name": "Item",
"Value": "Model Name"
},
{
"Name": "_ItemId",
"Value": "PBT=[unit] unt.DT=[2021-07-28 08:20:33.513] unt.ID=[eae2621d-3e9f-4515-9763-55e67f65fae6]"
}
]
],
"Message": "Success",
"MessageCode": 0
}
If you want to find value of dictionary with key 'Name' and value 'Item' you can do:
import json
with open('your_data.json', 'r') as f_in:
data = json.load(f_in)
model_name = next((i['Value'] for lst in data['Items'] for i in lst if i['Name'] == 'Item'), 'Model name not found.')
print(model_name)
Prints:
Model Name
Note: if the dictionary is not found string 'Model name not found.' is returned
First, load the JSON into a python dict:
import json
x = '''{
"Bookmark": "<B><P><p>SerNum</p><p>Item</p></P><D><f>false</f><f>false</f></D><F><v>1101666</v><v>ADDMASTER IJ7102-23E</v></F><L><v>123456</v><v>Model Name</v></L></B>",
"Items": [
[
{
"Name": "SerNum",
"Value": "123456"
},
{
"Name": "Item",
"Value": "Model Name"
},
{
"Name": "_ItemId",
"Value": "PBT=[unit] unt.DT=[2021-07-28 08:20:33.513] unt.ID=[eae2621d-3e9f-4515-9763-55e67f65fae6]"
}
]
],
"Message": "Success",
"MessageCode": 0
}'''
# parse x:
y = json.loads(x)
# The result is a Python dictionary.
Now if you want the value 'Model Name', you would do:
print(y['Items'][0][1]['Value'])

PynamoDB dynamic names for MapAttribute

I'm currently a bit stuck. I have to create a model of our dynamodb using pynamodb, and here's what I have (part of a bigger model, exported from a real user in DB)
packs = [
{
"exos": {
"4": {
"start": 1529411739,
"session": 1529411739,
"finish": 1529417144
},
"5": {
"start": 1529417192,
"session": 1529417192
}
},
"id": 10
},
{
"exos": {
"32": {
"start": 1529411706,
"session": 1529411706
}
},
"id": 17
}
]
Here's what I got so far:
class ExercisesMapAttribute(MapAttribute):
pass
class PackMapAttribute(MapAttribute):
exos = ExercisesMapAttribute()
id = NumberAttribute()
class TrainUser(Model):
class Meta:
table_name = 'TrainUser'
region = 'eu-west-1'
# [...] Other stuff removed for clarity
packs = ListAttribute(of=PackMapAttribute())
Currently I think I got correctly up until the "4":, "5": etc... As they are exercices name.
The idea is that this structure is supposed to represent a list of packs, then inside a list of exercises with their id and more info... I need a way to map that from the current db json to classes I can then use with PynamoDB. Is it even possible?
Thanks!
I've tried DynamicMapAttribute but I can't figure out if it will work with my configuration.
I also don't know how a custom attribute could be done to overcome this.

marshmallow - choose nested schema based on field value and handle fields 'starting with'

I am parsing a file and end up with a dictionary like this:
user_data = {
"title": "TestA",
"sects": [
{
"type": "cmd",
"cmd0": {
"moveX": 12,
"moveY": 34,
"action": "fire"
},
"session": 9999,
"cmd1": {
"moveX": 56,
"moveY": 78,
"action": "stop"
},
"endType": 0,
},
{
"type": "addUsers",
"user1": {
"name": "John",
"city": "London"
},
"user2": {
"name": "Mary",
"city": "New York"
},
post = "yes"
}
]
}
I am attempting to validate it using marshmallow but not sure how to handle these two things:
With sects the content of each nested dict is dependent on the type (cmd, addUser, etc). Is there a way to pick a schema based on the value of a field?
Is there such a thing as field 'startsWith' to handle the fact that I may have cmd0, cmd1...cmdN?
So, something like the following:
class CmdSchema(schema):
type = fields.Str()
cmdN = fields.Dict(...) # Allow cmd1, cmd2, etc
session = fields.Int()
endType = fields.Int()
class AddUsersSchema(schema):
type = fields.Str()
userN = fields.Dict(...) # Allow user1, user2, etc
post = fields.Str()
class ParsedFileSchema(schema):
title = fields.Str()
sects = fields.Nested(...) # Choose nested schema based on sects[i]['type']?
Note: I cannot change the format/content of the file I'm parsing and order matters (so I need to retain the order of cmd1, cmd2, etc so they can be processed in the correct order).
1/ What you want to achieve is polymorphism. You may want to check out marshmallow-oneofschema.
2/ This does not exist to my knowledge. It shouldn't be too hard to create as a custom validator, though. It might even make it to the core.

Python: String replacement with JSON dictionary

I need to create a script in Python, for replacement of strings in a json file, based on a json dictionary. The file has information about patents and it looks like this:
{
"US-8163793-B2": {
"publication_date": "20120424",
"priority_date": "20090420",
"family_id": "42261969",
"country_code": "US",
"ipc_code": "C07D417/14",
"cpc_code": "C07D471/04",
"assignee_name": "Hoffman-La Roche Inc.",
"title": "Proline derivatives",
"abstract": "The invention relates to a compound of formula (I) wherein A, R 1 -R 6 are as defined in the description and in the claims. The compound of formula (I) can be used as a medicament."
}
}
Initially I used a software that identifies, based on entities (ex. COMPANY), all the words that are written differently, but are the same. For example, the company "BMW" can be called "BMW Ag" as well as "BMW Group". And this dictionary has a structure like this (is only partially represented, otherwise it would be very long):
{
"RESP_META" : {
,"RESP_WARNINGS" : null
,"RESP_PAYLOAD":
{
"BIOCHEM": [
{
"hitID": "D011392",
"name": "L-Proline",
"frag_vector_array": [
"16#{!Proline!} derivatives"
],
...,
"sectionMeta": {
"8": "$.US-8163793-B2.title|"
}
},
{
(next hit...)
},
...
]
}
Taking into consideration that the "sectionMeta" key gives me the patent ID and, for ex., abstract, title or assignee_name, I would like to use this information to find out in which patent will the replacement take place, and then based on the "frag_vector_array" key, find the word to be replaced, which always is between {!!}, for example {! Proline!}, and that word should be replaced by "name", for ex. L-Proline.
I've tried something to replace the companies name, but I think I'm going the wrong way. Here is the code I started:
import json
patents = json.load(open("testset_patents.json"))
companies = json.load(open("termite_output.json"))
print(companies)
companies = companies['RESP_PAYLOAD']
# loop through companies data
for company in companies.values():
company_list = company["COMPANY"]
for comp in company_list:
comp_name = comp["name"]
# update patents "name" in "assignee_name"
for patent in patents.values():
patent['assignee_name'] = comp_name
print(patents)
# save output in new file
with open('company_replacement.json', 'w') as fp:
json.dump(patents, fp)
Well any and all help is welcome.

Getting json file fields issue

OK, I am new to python but what I am trying to do is to access specific fields from a json text file
my json text file is like this:
{
"paging": {
"next": "https://graph.facebook.com/search?limit=5000&offset=5000&type=page&q=%26&locale=ar_AR&access_token=CAACEdEose0cBAD7z1vK0aO2Mlb1QZBOb9OwjYZCZBZB56P0MrYnt54WJYZCZBy4ZBv4zaYG0mj9ZCZAMkZBmlP83E885ykZAafog7QbcWwEtvRXfjtVa12DBnW8omWsnC8N6lsmNK7yktI89kBDdrTH9TOIdATHdsX5OewWhzGTpXDelSjE8HAbtcn08zSWsweDc4UZD&__after_id=139433456868"
},
"data": [
{
"category": "\u0627\u0644\u062a\u0639\u0644\u064a\u0645",
"name": "The London School of Economics and Political Science - LSE",
"category_list": [
{
"id": "108051929285833",
"name": "\u0627\u0644\u0643\u0644\u064a\u0629 \u0648\u0627\u0644\u062c\u0627\u0645\u0639\u0629"
},
{
"id": "187751327923426",
"name": "\u0645\u0646\u0638\u0645\u0629 \u062a\u0639\u0644\u064a\u0645\u064a\u0629"
}
],
"id": "6127898346"
},
the filed that I want to access is the 'category_list' filed in order to get the 'id' filed
I have tried some thing like this:
import json
idvalue = []
jsonFile = open('samples0.txt', 'r')
values = json.load(jsonFile)
jsonFile.close()
idValue = values['data'][0]['category_list'][0]['id']
print idvalue
but it keeps telling me that there is a key error.
what I am missing here?
what is the wrong thing I am doing?
any help please
edit :
my code returning null I still cannot understand why?
values['data'][0]['category_list'] is a list, so something like values['data'][0]['category_list'][0]['id'] should work.
No need to declare idValue. Just use it as
idValue = values['data'][0]['category_list'][0]['id']

Categories