Parsing JSON from POST request using Python and FastAPI - python-3.x

I'm trying to parse a JSON that came from a POST request from user to my API made with FastAPI. I have a nested JSON that can receive multiple values and my problem is: How can I parse it and get the values from this nested JSON?
The JSON is like this:
{
"recipe": [
{
"ingredient": "rice",
"quantity": 1.5
},
{
"ingredient": "carrot",
"quantity": 1.8
},
{
"ingredient": "beans",
"quantity": 1.8
}
]
}
I must grab the all values from the list recipe separated, as I have a database with this ingredient and will query all of this and do some calculates with the quantity given from user. But I don't even know how I can parse this JSON from the POST request.
I already have a 2 classes with Pydantic validating this values like:
class Ingredientes(BaseModel):
ingredient: str
quantity: float
class Receita(BaseModel):
receita: List[Ingredientes] = []
Edit 1: I tried to include it in my function that recieve this POST request and didn't work like:
#app.post('/calcul', status_code=200)
def calculate_table(receita: Receita):
receipe = receita["receita"]
for ingredient in receipe:
return f'{ingredient["ingredient"]}: {ingredient["quantity"]}'
Edit 2: Fixed the issue with the code bellow(Thanks MatsLindh):
#app.post('/calcul', status_code=200)
def calculate_table(receita: Receita):
receipe = receita.receita
for ingredient in receipe:
return f'{ingredient.ingrediente}: {ingredient.quantidade}'

To parse a JSON-formatted string (from the POST request, for example) into a dictionary, use the loads function from the json module, like this:
import json
s = """{
"recipe": [
{
"ingredient": "rice",
"quantity": 1.5
},
{
"ingredient": "carrot",
"quantity": 1.8
},
{
"ingredient": "beans",
"quantity": 1.8
}
]
}
"""
recipe = json.loads(s)["recipe"]
for ingredient in recipe:
print(f"{ingredient['ingredient']}: {ingredient['quantity']}")

Related

How to extract two value from json under one condition and randomize it in jmeter?

Below is the server response in a JSON format which I need to work on, In this JSON some of the objects I need to pass in the next request, which I am successfully able to do for the first occurrence, but the problem is coming on randomization in the below JSON
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "test_title",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Sword of Honour",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "India",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
if I apply $..book[0][?(#.title == 'Sword of Honour')] condition I am seeing successful output
test_1={"category":"reference","title":"Sword of Honour","author":"Nigel Rees","price":8.95}
test_2={"category":"fiction","title":"Sword of Honour","author":"Herman Melville","price":8.99,"isbn":"0-553-21311-3"}
if I apply $..book[0][?(#.title == 'Sword of Honour')].author condition I am seeing successful output
test_1=Nigel Rees
test_2=Herman Melville
But I want to extract both author's name and price for the book that has the title == 'Sword of Honour'
Actual output = able to retrieve one value with the condition $..book[0][?(#.title == 'Sword of Honour')].author
Expected output = I want to receive two values from the same list randomly. and it should look like this
Iteration 1-
test_1={"author":"Nigel Rees","price":8.95}
Iteration 2-
test_2={"author":"Herman Melville","price":8.99,}
Iteration 3-
test_2={"author":"Herman Melville","price":8.99,}
I had tried with the V function as well but got only one value. (book{__V([?(#.title == 'Sword of Honour')]_${__Random(1,${title_matchNr},)},)})
Add JSR223 PostProcessor as a child of the request which returns the above JSON
Put the following code into "Script" area:
def swords = new groovy.json.JsonSlurper().parse(prev.getResponseData()).store.book.findAll { book -> book.title == 'Sword of Honour' }
swords.eachWithIndex { def sword, int index ->
def payload = [:]
payload.put('author', sword.author)
payload.put('price', sword.price)
vars.put('test_' + (index + 1), new groovy.json.JsonBuilder(payload).toPrettyString())
}
vars.put('test_matchNr', swords.size() as String)
Now you should be able to refer random author/price pair using __V() and __Random() functions combination like: ${__V(test_${__Random(1,${test_matchNr},)},)}
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy: What Is Groovy Used For?

How to insert another item programmatically into body?

I am trying to build a free/busy body request to Google Calendar API via Python 3.8 . However, when I try to insert a new item into the body request, I am getting a bad request and can't use it.
This code is working:
SUBJECTA = '3131313636#resource.calendar.google.com'
SUBJECTB = '34343334#resource.calendar.google.com'
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": [{'id': SUBJECTA},{"id": SUBJECTB} ]
}
Good Body result:
{'timeMin': '2019-11-05T11:42:21.354803Z',
'timeMax': '2019-11-05T12:42:21.354823Z',
'timeZone': 'America/New_York',
'items': [{'id': '131313636#resource.calendar.google.com'},
{'id': '343334#resource.calendar.google.com'}]}
However,
While using this code:
items = "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}"
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": items
}
The Body results contain additional quotes at the start and end position, failing the request:
{'timeMin': '2019-11-05T12:04:41.189784Z',
'timeMax': '2019-11-05T13:04:41.189804Z',
'timeZone': 'America/New_York',
'items': ["{'ID': 13131313636#resource.calendar.google.com},{'ID':
53333383137#resource.calendar.google.com},{'ID':
831383733#resource.calendar.google.com},{'ID':
33339373237#resource.calendar.google.com},{'ID':
393935323035#resource.calendar.google.com}"]}
What is the proper way to handle it and send the item list in an accurate way?
In your situation, the value of items is given by the string of "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}".
You want to use as the object by parsing the string value with python.
The result value you expect is [{'ID': '1313636#resource.calendar.google.com'}, {'ID': '3383137#resource.calendar.google.com'}, {'ID': '383733#resource.calendar.google.com'}].
You have already been able to use Calender API.
If my understanding is correct, how about this answer? Please think of this as just one of several answers.
Sample script:
import json # Added
items = "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}"
items = json.loads(("[" + items + "]").replace("\'", "\"")) # Added
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": items
}
print(body)
Result:
If now and nownext are the values of "now" and "nownext", respectively, the result is as follows.
{
"timeMin": "now",
"timeMax": "nownext",
"timeZone": "America/New_York",
"items": [
{
"ID": "1313636#resource.calendar.google.com"
},
{
"ID": "3383137#resource.calendar.google.com"
},
{
"ID": "383733#resource.calendar.google.com"
}
]
}
Note:
If you can retrieve the IDs as the string value, I recommend the following method as a sample script.
ids = ['1313636#resource.calendar.google.com', '3383137#resource.calendar.google.com', '383733#resource.calendar.google.com']
items = [{'ID': id} for id in ids]
If I misunderstood your question and this was not the result you want, I apologize.

How to iterate through each property element in API response in Katalon studio?

I'm writing test script in katalon studio to verify response body of the API.My response body is of format:
{
"status": "Success",
"correlationCode": "1234-5678",
"type": {
"id": 51247,
"name": "Student",
},
"data": {
"name": "Sara Nieves",
"gender": "Female",
"dob": "1995-08-06",
"libraryCard": {
"id": "11178",
"type": "Seniors"
},
"qualifications": [
{
"id": "45650986546",
"name": "Graduate Certificate in Environmental Engineering Management"
}
]
}
}
I want to verify that none of the elements return 'null' value. Since, the elements returned for the API response are not static(meaning name, gender etc might not get returned every time) therefore, i can't use something like "data.name" to verify if it has null value. So, i want a generic way to loop through each and every attribute returned and check if its value is returned as null or not.
Any help will be much appreciated. Thanks!
You have the error message:
groovy.lang.MissingMethodException: No signature of method: WSVerification1569811424284$_run_closure1.doCall() is applicable for argument types: (com.kms.katalon.core.testobject.ResponseObject) values: [200 1 KB] 22572.groovy:21)
I assume your response object type: com.kms.katalon.core.testobject.ResponseObject
The code to parse response as json and validate it:
import groovy.json.JsonSlurper
/**
* the recursive method to validate that json object does not have null values
* #param obj - the parsed json object (sequence of maps and lists)
* #param path - a variable to know where the error occurred in json data.
*/
void assertNoNullValue(Object obj, String path='ROOT'){
//the main assertion
assert obj!=null : "value in json could not be null: $path"
if(obj instanceof Map){
//iterate each key-value in map and validate the value recursively
obj.each{k,v-> assertNoNullValue(v,path+".$k") }
} else if(obj instanceof List){
//iterate each value in list and validate the value recursively
obj.eachWithIndex{v,i-> assertNoNullValue(v,path+"[$i]") }
}
}
def response = ...
assert response.isJsonContentType()
def responseText = response.getResponseText()
//parse body
def data = new JsonSlurper().parseText(responseText)
assertNoNullValue(data)
This solution is not as precise as the one suggested by #dagget, but it is a quick check:
def response = '''
{
"status": "Success",
"correlationCode": "1234-5678",
"type": {
"id": 51247,
"name": "Student",
},
"data": {
"name": "Sara Nieves",
"gender": "femmina",
"dob": "1995-08-06",
"libraryCard": {
"id": "11178",
"type": "Seniors"
},
"qualifications": [
{
"id": "45650986546",
"name": "Graduate Certificate in Environmental Engineering Management"
}
]
}
}
'''
assert !response.contains("null")

How to include fields in api server and remove it before returning to results to client in Graphql

I have a Node.js GraphQL server. From the client, I am trying get all the user entries using a query like this:
{
user {
name
entries {
title
body
}
}
}
In the Node.js GraphQL server, however I want to return user entries that are currently valid based on publishDate and expiryDate in the entries object.
For example:
{
"user": "john",
"entries": [
{
"title": "entry1",
"body": "body1",
"publishDate": "2019-02-12",
"expiryDate": "2019-02-13"
},
{
"title": "entry2",
"body": "body2",
"publishDate": "2019-02-13",
"expiryDate": "2019-03-01"
},
{
"title": "entry3",
"body": "body3",
"publishDate": "2020-01-01",
"expiryDate": "2020-01-31"
}
]
}
should return this
{
"user": "john",
"entries": [
{
"title": "entry2",
"body": "body2",
"publishDate": "2019-02-13",
"expiryDate": "2019-03-01"
}
]
}
The entries is fetched via a delegateToSchema call (https://www.apollographql.com/docs/graphql-tools/schema-delegation.html#delegateToSchema) and I don't have an option to pass publishDate and expiryDate as query parameters. Essentially, I need to get the results and then filter them in memory.
The issue I face is that the original query doesn't have publishDate and expiryDate in it to support this. Is there a way to add these fields to delegateToSchema call and then remove them while sending them back to the client?
You are looking for transformResult
Implementation details are:
At delegateToSchema you need to define transforms array.
At Transform you need to define transformResult function for filtering results.
If you have ability to send arguments to remote GraphQL server, then you should use
transformRequest

How to reference parent names in JSON response (with Groovy)

I have the following JSON response in SoapUI
{
"formatted": {
"line1": "14/8 QUAY STREET",
"line2": "14/8 QUAY STREET"
},
"structure": {
"level": null
},
"location": {
"nzX": 1758749.75300025
},
"references": {
"aid": "A1003467096"
}
}
I want the following as the output
formatted, structure, location and references.
I am using Json slurper but i am not able to get all the parent element names.
How do i do it using JSON slurper in groovy.
Assuming the JSON is in a string s, consider the following which illustrates getting the top level keys:
import groovy.json.*
def json = new JsonSlurper().parseText(s)
def parentNames = json.keySet()
parentNames.each { println it }

Resources