Get "Bad Request" when using json api - json

I am trying to get a json post working using grails, and keep getting "bad request". I have stripped down everything to the point that the routine doesn't make much sense, but it is simple.
The api should return an error text requesting valid parameters...
You will be able to guess that I am pretty new to this, so any hints would be greatly appreciated.
Thanks...
def testit() {
def statusLine = "200"
def http = new HTTPBuilder( 'http://api.scribblepics.com' )
def postBody = [
'apiKey': 'test',
'sender': [
'firstName': 'First',
'lastName': 'Last',
'email': 'first.last#mail.com'
]
]
http.post( path: '/postcard/create', body: postBody,
requestContentType: URLENC ) { resp ->
println "status: ${resp.statusLine}"
statusLine = resp.statusLine
assert resp.statusLine.statusCode == 200
}
}

You are missing other mandatory parameters recipient, message, imageData.
Or have you already tried with these and are still getting the same error?

def postBody = [
'apiKey': 'test',
'sender': [
'firstName': 'First',
'lastName': 'Last',
'email': 'first.last#mail.com'
],
'recipient': [
'name': 'full name',
'addressLine1': 'Main Street',
'addressLine2': 'Main Street2',
'city': 'city',
'state': 'state',
'zip': '1234',
'country': 'country'
],
'message': 'A test message...',
'imageUrl':'http://www.google.ch/imgres?sa=X&biw=1680&bih=859&tbm=isch&tbnid=Dw_q5yUyBtrHAM%3A&imgrefurl=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FFerrari_F430&docid=sKowXM25Yu8uoM&imgurl=http%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F1%2F17%2FFerrari_F430_front_20080605.jpg&w=2275&h=1160&ei=jsAJU9CHL6OK5AS7u4GQAw&zoom=1&ved=0CGUQhBwwAA&iact=rc&dur=2130&page=1&start=0&ndsp=18'
]

Related

Remove empty elements from nested JSON

I have a nested json with an arbitrary depth level :
json_list = [
{
'class': 'Year 1',
'room': 'Yellow',
'students': [
{'name': 'James', 'sex': 'M', 'grades': {}},
]
},
{
'class': 'Year 2',
'info': {
'teachers': {
'math': 'Alan Turing',
'physics': []
}
},
'students': [
{ 'name': 'Tony', 'sex': 'M', 'age': ''},
{ 'name': 'Jacqueline', 'sex': 'F' },
],
'other': []
}
]
I want to remove any element that its value meet certain criteria.
For example:
values_to_drop = ({}, (), [], '', ' ')
filtered_json = clean_json(json_list, values_to_drop)
filtered_json
Expected Output of clean_json:
[
{
'class': 'Year 1',
'room': 'Yellow',
'students': [
{'name': 'James', 'sex': 'M'},
]
},
{
'class': 'Year 2',
'info': {
'teachers': {
'math': 'Alan Turing',
}
},
'students': [
{ 'name': 'Tony', 'sex': 'M'},
{ 'name': 'Jacqueline', 'sex': 'F'},
]
}
]
I thought of something like first converting the object to string using json.dumps and then looking in the string and replacing each value that meets the criteria with some kind of flag to filter it after before reading it again with json.loads but I couldn't figure it out and I don't know if this is the way to go
I managed to get the desired output by tweaking this answer a bit:
def clean_json(json_obj, values_to_drop):
if isinstance(json_obj, dict):
json_obj = {
key: clean_json(value, values_to_drop)
for key, value in json_obj.items()
if value not in values_to_drop}
elif isinstance(json_obj, list):
json_obj = [clean_json(item, values_to_drop)
for item in json_obj
if item not in values_to_drop]
return json_obj

'Reader' object has no attribute 'tell' error with jsonlines and cloud storage

I'm writing a cloud function to extract data from an API in the following format:
[{'_id': '123qasd', 'description': 'stuff here', 'userId': 'xxxx', 'billable': False, 'taskId': 'asddf1234', 'projectId': '5e11gg55', 'timeInterval': {'start': '2020-05-16T09:00:00+02:00', 'end': '2020-05-16T13:00:00+02:00', 'duration': 14400}, 'taskName': 'Production', 'tags': [], 'isLocked': True, 'customFields': [], 'userName': 'Dupond', 'userEmail': 'stuff#mail.com', 'projectName': 'my project', 'projectColor': '#607D8B', 'clientName': 'my client', 'clientId': 'xxxxxxxx'}, {'_id': '123qasd', 'description': 'stuff here', 'userId': 'xxxx', 'billable': False, 'taskId': 'asddf1234', 'projectId': '5e11gg55', 'timeInterval': {'start': '2020-05-16T09:00:00+02:00', 'end': '2020-05-16T13:00:00+02:00', 'duration': 14400}, 'taskName': 'Production', 'tags': [], 'isLocked': True, 'customFields': [], 'userName': 'Dupond', 'userEmail': 'stuff#mail.com', 'projectName': 'my project', 'projectColor': '#607D8B', 'clientName': 'my client', 'clientId': 'xxxxxxxx'}, {'_id': '123qasd', 'description': 'stuff here', 'userId': 'xxxx', 'billable': False, 'taskId': 'asddf1234', 'projectId': '5e11gg55', 'timeInterval': {'start': '2020-05-16T09:00:00+02:00', 'end': '2020-05-16T13:00:00+02:00', 'duration': 14400}, 'taskName': 'Production', 'tags': [], 'isLocked': True, 'customFields': [], 'userName': 'Dupond', 'userEmail': 'stuff#mail.com', 'projectName': 'my project', 'projectColor': '#607D8B', 'clientName': 'my client', 'clientId': 'xxxxxxxx'}]
I want to send this data to Cloud Storage and then, read them with BigQuery. In order to do this I need to convert json to ndjson.
I'm using jsonlines to handle the conversion. Here is an extract of my function:
with jsonlines.open(f'/tmp/output.jsonl', "w") as writer:
writer.write(data)
date = datetime.today().strftime('%Y-%m-%d %H:%M:%S')
bucket = storage_client.bucket(bucket_name)
destination_blob_name = '{}'.format(date)
blob = bucket.blob(destination_blob_name)
with jsonlines.open('/tmp/output.jsonl') as reader:
blob.upload_from_file(reader)
I have the following error 'Reader' object has no attribute 'tell'
What's wrong?
I managed to get it to work! use just normal file open.
with open('output.jsonl', 'rb') as f:
blob.upload_from_file(f)

remove k,v from http response in python

I am new to python and am struggling with remove a key and value from a json return by an http request. When querying a task I get the following back.
data = requests.get(url,headers=hed).json()['data']
[{
'gid': '12011553977',
'due_on': None,
'name': 'do something',
'notes': 'blalbla,
'projects': [{
'gid': '120067502445',
'name': 'Project1'
}]
}, {
'gid': '12002408815',
'due_on': '2021-10-21',
'name': 'Proposal',
'notes': 'bla',
'projects': [{
'gid': '12314323523',
'name': 'Project1'
}, {
'gid': '12314323523',
'name': 'Project2'
}, {
'gid': '12314323523',
'name': 'Project3'
}]
I am trying to remove 'gid' from all projects so projects look like this
'projects': [{
'name': 'Company'
}]
What is the best way to do this with python3?
You can use recursion to make a simpler function to handle all elements and sub-elements. I haven't done extensive testing, or included any error checking or exception handling; but this should be close to what you want:
def rec_pop(top_level_list,key_to_pop='gid'):
for item in top_level_list:
item.pop(key_to_pop)
for v in item.values():
if isinstance(v,list):
rec_pop(v)
# call recursive fn
rec_pop(data)
Result:
In [25]: data
Out[25]:
[{'due_on': None,
'name': 'do something',
'notes': 'blalbla',
'projects': [{'name': 'Project1'}]},
{'due_on': '2021-10-21',
'name': 'Proposal',
'notes': 'bla',
'projects': [{'name': 'project2'}]}]

Getting "Method not found: 'Boolean Newtonsoft.Json.Schema.SchemaExtensions.IsValid" in VS2019

I've copied a sample from the site https://www.newtonsoft.com/jsonschema/help/html/ValidatingJson.htm:
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
...
string schemaJson = #"{
'description': 'A person',
'type': 'object',
'properties': {
'name': {'type': 'string'},
'hobbies': {
'type': 'array',
'items': {'type': 'string'}
}
}
}";
JSchema schema = JSchema.Parse(schemaJson);
JObject person = JObject.Parse(#"{
'name': 'James',
'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS']
}");
bool valid = person.IsValid(schema);
// true
When I try to debug it in VS2019 I get an exception: "Method not found: 'Boolean Newtonsoft.Json.Schema.SchemaExtensions.IsValid"
I feel so stupid for asking, but what am I doing wrong?

How to save data in json file?

I need to save JSON data into a .json file after converting an object to a string using JSON.stringify
This is my current code:
const jsonObject: object = {
'countryName': 'Switzerland',
'users': [
{
'id': 1,
'name': 'Basel',
'founded': -200,
'beautiful': true,
'data': 123,
'keywords': ['Rhine', 'River']
},
{
'id': 1,
'name': 'Zurich',
'founded': 0,
'beautiful': false,
'data': 'no',
'keywords': ['Limmat', 'Lake']
}
]
};
const myData = JSON.stringify(jsonObject);
Note: I want to save this data dynamically, and I was used to jsonConverter of jsonTypescript2.
I tried using this method:-
let a = document.createElement('a');
// JSON.stringify(jsonObject), 'ex.json' // another
a.setAttribute('href', 'data:application/json;charset=UTF-8,' + encodeURIComponent(myData));
Okay after 6 days ago I discover best solution, how to connect between Angular 6 and Node.js + json File directly and dynamically .
npm install file-saver --save
import { saveAs } from 'file-saver';
const jsonObject: object = {
'City': [
{
'id': 1,
'name': 'Basel',
'founded': -200,
'beautiful': true,
'data': 123,
'keywords': ['Rhine', 'River']
},
{
'id': 1,
'name': 'Zurich',
'founded': 0,
'beautiful': false,
'data': 'no',
'keywords': ['Limmat', 'Lake']
}
]
};
const blob = new Blob([JSON.stringify(jsonObject)], {type : 'application/json'});
saveAs(blob, 'abc.json');
You can use fs.js NPM module to write data to file
There are a lot of details in the filesystem API. The most common way (as far as I know) is:
var fs = require('fs');
fs.writeFile("/fileName.json", myData, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});