printing in python a twitter response - python-3.x

I am making a request to a twitter URL
response = requests.get(url, auth=auth_obj)
If I do this:
for data in response:
print(data)
I get a response from it that contains all the data, username, location etc.
{"users":[{"id":2190618097,"id_str":"2190618097","name":"huramachi","screen_name":"huramachi73","location":"entre Vincennes et R
\u00e9publique ","description":"Nuclear winter is coming!!!","
So, that is json.
And if I do this:
json.dumps(parsed, indent= 4, sort_keys=True)
it looks like this:
{
"next_cursor": 1591504703761404265,
"next_cursor_str": "1591504703761404265",
"previous_cursor": 0,
"previous_cursor_str": "0",
"users": [
{
"blocked_by": false,
"blocking": false,
"contributors_enabled": false,
"created_at": "Tue Nov 12 16:07:59 +0000 2013",
"default_profile": true,
"default_profile_image": false,
"description": "Nuclear winter is coming!!!",
"entities": {
"description": {
"urls": []
}
},
"favourites_count": 781,
"follow_request_sent": false,
"followers_count": 188,
"following": false,
"friends_count": 2054,
If I do this, I get the info that parsed is a dictionary.
parsed = json.loads(response.text)
print (type(parsed))
but how do I print this dictionary, or organize it so that I can save entities in lists?

first of all, thanks to all those who tried to help.
Here is what worked for me and why.
Why:
Twitter returns a json response but this object has parents and childrens, so the printing can only be complete if you nest your loops and you know who the parent and the children are according to twitter dev docs:
Tweets are the basic atomic building block of all things Twitter. Tweets are also known as “status updates.” The Tweet object has a long list of ‘root-level’ attributes, including fundamental attributes such as id, created_at, and text. Tweet objects are also the ‘parent’ object to several child objects. Tweet child objects include user, entities, and extended_entities. Tweets that are geo-tagged will have a place child object.
You can see in there several print outs of how their json looks like and also in mine own print out above.
So, if I want to print out one of the children, for example, location, this is what worked for me:
objeto = json.loads(response.text)
for element in objeto['users']:
print (element['location'])

Related

How to return an entire array (NO FILTER!!!!!), from mongodb using node.js

heres my mongodb group document. As you can see i have an _id, which i use to find the group itself, an owner, an array of admins and an array of members.
{
"_id": {
"$oid": "60c7246f61a6cc7527f815d2"
},
"groupName": "soogroo1",
"creationDate": "11/06/2020",
"premiumStatus": true,
"phone": "08741536329995757575757575757575577575757575",
"profilePic": "post-5f2a01e2-efe3-4fa0-8302-76bfd2d70b4b-1622806860268",
"owner": ["9b8bcd57-06eb-471c-8910-c5b944d02431"],
"admin": ["f2171431-627e-47a3-a65f-4abf48d361b6", "5e3df015-a1ed-4a63-a16e-83458d0e7da3", "f85baa4a-1015-4a5e-b1ed-b79001a9f277"],
"member": ["6b1233b2-098e-480b-9462-c010c8b8de06", "0bcbb92d-6276-4118-8576-9d5f5c4ed43b"]
}
essentially i have searched the entirety of the world wide web looking for one of possibly the simplest most fundamental thing i can think of, how on gods green earth do you query an array of strings, and return the entire array. All i want to do is pass in a group id, specify that i want the entire member field returned, and then ill be able to map the members to a list on the front-end like you would with following/followers on instagram for example.
Everywhere i look all i can find is people who use arrays of objects and people who filter arrays and all that bs, i just want the entire array string for string returned. Please help i'm pulling my hair out lol.
BTW im using nodeJS with express and reactJS on the front-end (not that that's relevant)
vvvvv RELEVANT CODE vvvvv
folder name : routes
file name : groups.js
app.get("/groups/:groupId/members", (req, res)=>{
groups.getGroupsMembers(req.params.groupId).then(data=>{
res.send(data)
})
})
folder name : main
file name : groups.js
exports.getGroupsMembers = (groupId) => {
return myMongo.getGroupsMemberList("groups", groupId);
};
folder name : main
file name : mongo.js
vvvvvv (the part that is broken) vvvvvv
exports.getGroupsMemberList = (collection, groupId) => {
return db.collection(collection).findOne(
{ _id: ObjectID(groupId)},
).members
}
I currently have no way to test your code, but I guess your problem is because you are extending query with .members, not actually getting members attribute from the return value of query.
exports.getGroupsMemberList = async (collection, groupId) => {
return await (db.collection(collection).findOne(
{ _id: ObjectID(groupId)},
)).members
}
I am not sure if mongo driver accepts async/await, so you might need to do this through callbacks..?

Acumatica Inventory Summary Inquiry all items via REST APi

I need to retrieve the inventory summary for all Stock Items so that I can update an external site's inventory according to the "Available For Shipment" field on the inventory summary. I have attempted running the inventory summary via the rest API using the following method after logging in:
URL: https://mycompany.acumatica.com/entity/Default/6.00.001/InventorySummaryInquiry
Method: PUT
Request Body:
{
"InventoryID": "CW-500-MC-30"
}
However I receive this response:
{
"message": "The request is invalid.",
"modelState": {
"": [
"Error reading JObject from JsonReader. Current JsonReader item is not an object: String. Path 'InventoryID', line 2, position 30."
]
}
}
If there is a way to run the inquiry and have it return ALL stock items in an array, that would be ideal.
If that's not possible, what do I need to change to get the individual stock item inventory summary to work?
UPDATE:
After modifying my request body as #samol518 suggested, the request worked, but returned a very limited set of data (below). I'm looking to get to the "quantity available for shipment". Do I need to provide additional parameters to get more data returned?
{
"id": "bf8e0bbc-63dc-4491-802d-090367af203a",
"rowNumber": 1,
"note": null,
"ExpandByLotSerialNumber": {},
"InventoryID": {
"value": "CW-500-MC-30"
},
"LocationID": {},
"WarehouseID": {},
"custom": {},
"files": []
}
If I am not mistaken the correct structure for the Request Body should resemble the following :
Request Body :
{
"InventoryID": {"value": "CW-500-MC-30"}
}
Though if you want to retrieve all Stock Item, you could try and customize the inquiry in order to do so.
Update:
in order to retrieve all record, you might notice that the result fields are in a sub entity in the endpoint definition on the Web Service Endpoint screen (SM207060).
in order to return the data for these detail type sub entities, you must add the expand key word to your URL in the following format.
$expand=results
So your final URL should look like :
https://mycompany.acumatica.com/entity/Default/6.00.001/InventorySummaryInquiry?$expand=Results

How telegram bot can get file_id of uploaded file?

In telegram API documentation I see: "You can either pass a file_id as String to resend a photo that is already on the Telegram servers", but I can't find ways to get file_id of uploaded file. How can I get it?
Its depended to your content_types ,for example:
Video:
message.video.file_id
Audio:
message.audio.file_id
Photo:
message.photo[2].file_id
For more see this link.
This is the easiest way I've found to do it.
Upload your file to any chat and forward the message to #RawDataBot. It will return something like this:
{
"update_id": 754677603,
"message": {
"message_id": 403656,
"from": {
"id": xxx,
"is_bot": false,
"first_name": "xxx",
"username": "xxx",
"language_code": "en"
},
"chat": {
"id": xxx,
"first_name": "xxx",
"username": "xxx",
"type": "private"
},
"date": 1589342513,
"forward_from": {
"id": xxx,
"is_bot": false,
"first_name": "xxx",
"username": "xxx",
"language_code": "en"
},
"forward_date": 1589342184,
"document": {
"file_name": "filename.pdf",
"mime_type": "application/pdf",
"file_id": "This_Is_The_Thing_You_Need",
"file_unique_id": "notthis",
"file_size": 123605
}
}
}
What you need is the string under file_id. Once you have copied that, you can simply the following code to send the message.
context.bot.sendDocument(chat_id=update.effective_chat.id,
document = "Your_FILE_ID_HERE")
Depending on the method (File type) which you chose to send a file, after sending a file to Telegram a response is returned. For example if you send a MP3 file to Telegram using sendAudio method, Telegram returns an Audio object which contains the file ID.
Source: https://core.telegram.org/bots/api#audio
In addition to the answers above, you can log Updates that comes to your bot, Either from https://api.telegram.org/bot'.BOT_TOKEN.'/getUpdates or throw updates that come in your application. there you will find a Json property like below:
{
"update_id" = 1111111,
"message" =
{
"message_id" = 1111111,
"from" =
{
"id" = 111111,
...
}
"chat" =
{
"id" = 111111,
...
}
"date" = 111111,
"photo" =
{
{
"file_id" = HERE IS YOU FILE ID 1,
"file_size" => XXXX,
"width" => XX,
"height" => XX,
}
}
}
}
Say you receive a Message with an array of PhotoSize
https://core.telegram.org/bots/api#photosize
As you can see, there's a file_id, you can use this to send a photo through sendPhoto.
If we assume Update is an object, with in it a Message object, which in turn provides a Chat object with in it a id of the chat where the initial message came from and an array of PhotoSize (excuse me for using PHP here, but that's my main language...)
$update->message->photo is how you can access the array.
Use some kind of For loop to iterate over the items, or just access the first one if the array isn't bigger than 1.
After that, you can use the result(s) to extract the file_id and send it as a string via sendPhoto's photo parameter and the Chat ID via the chat_id parameter.
I hope this helped!
P.S. Here is a diagram of my current implementation of the API, i hope it brings some clarity to you!
if you use PHP:
you can write this line for full size:
$file_id = $updates['message']['photo'][1]['file_id'];
and this line for thumb:
$file_id = $updates['message']['photo'][0]['file_id'];
According to the latest docs (v20.0a6) plenty of classes have been changed. I have found that the easiest way to get started with files is using the effective_attachment property.
async def handle_file(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
media_item = await context.bot.get_file(update.message.effective_attachment[0].file_id)
media_url = media_item.file_path
For declaring the handler there have also been changes to filters, here is a simple way to declare it:
application.add_handler(MessageHandler(filters.ATTACHMENT, handle_file))

Bunyan logger.info error in Restful API

I'm working on a Restful API and I'm logging all the important steps with bunyan, including the requests. I'm having two problems with logging:
My first problem is that when I log them, all my objects, instead of appearing like independent objects, appear in the msg field, like strings.
Here is my code to log the requests:
var logger = bunyan.createLogger({
name: 'main',
streams: [{
level: 'info',
path: './logs/requests.log'
}]
});
logRequest = function(request){
logger.info("Request started.", {id: request.id}, {method: request.method});
};
and when I see the request.log file it appears like this (I've just added some tabs to make it more comfortable to see) :
{
"name": "logger",
"hostname": "LLAS",
"pid": 7700,
"level": 30,
"msg":"Request started. { id: '1428527975041:LLAS:7700:i898o4l5:10000'{ method:'post' } ",
"time":"2015-04-08T21:19:35.055Z",
"v":0
}
So my problem is that "msg" field, I want to see the "id" and "method" like other fields instead of a string. I.E. :
{
"name": "logger",
"hostname": "LLAS",
"pid": 7700,
"level": 30,
"msg":"Request started.",
"id": '1428527975041:LLAS:7700:i898o4l5:10000',
"method": 'post',
"time":"2015-04-08T21:19:35.055Z",
"v":0
}
How can I solve my problem?
And my second problem is: When I do more than one log in the same file,it writes the JSON in the same line, instead of a new line, like this:
{"name":"logger",...,"v":0}{"name":"logger",...,"v":0}
Instead of this:
{"name":"logger",...,"v":0}
{"name":"logger",...,"v":0}
And I can't work later with those objects in the same line, also it is hard to read and mantain in that way.
Anyone know why is this happening?
My first problem is that when I log them, all my objects, instead of
appearing like independent objects, appear in the "msg" field, like
strings.
That's because you are passing more than one object. You can only pass one object as the first parameter for logging, all other parameters will be considered as msg. From the bunyan source code:
/**
* The functions below log a record at a specific level.
*
* Usages:
* log.<level>() -> boolean is-trace-enabled
* log.<level>(<Error> err, [<string> msg, ...])
* log.<level>(<string> msg, ...)
* log.<level>(<object> fields, <string> msg, ...)
*
* where <level> is the lowercase version of the log level. E.g.:
*
* log.info()
* ....
*/
So if you pass all your parameters in one object, it will work properly:
var request = { id: "abc", method: "GET" }; // dummy request object
logger.info({id: request.id, method: request.method}, "Request started.");
The result is (pretty printed):
{
"name": "main",
"hostname": "Victors-MacBook-Pro.local",
"pid": 2848,
"level": 30,
"id": "abc",
"method": "GET",
"msg": "Request started.",
"time": "2015-04-08T23:25:37.967Z",
"v": 0
}
And my second problem is: When I do more than one log in the same
file,it writes the JSON in the same line, instead of a new line.
Are you on Windows? If you are, maybe the problem is that bunyan may be using the UNIX style carriage return (\n) and not the Windows style (\r\n). Try using a text editor that supports UNIX style carriage returns (like notepad++ or sublime text, for example).

nodejs async: multiple dependant HTTP API calls

I'm working on a project that involves making multiple HTTP GET requests to different APIs, each requiring information from the last. I'm trying to avoid nested-callaback-and-counter-hell, and have been trying to get it working with the async module.
This is what I need to do: I have an array of 1..n course identifiers (['2014/summer/iat/100/d100', '2014/spring/bisc/372/d100']). For each course in the array, I need to fetch its course outline via a HTTP GET.
The resulting outline looks something like this:
{
"info": {
"nodePath": "2014/spring/bisc/372/d100",
"number": "372",
"section": "D100",
"title": "Special Topics in Biology",
"term": "Spring 2014",
"description": "Selected topics in areas not currently offered...",
"name": "BISC 372 D100",
"dept": "BISC",
},
"instructor": [
{
"lastName": "Smith",
"commonName": "Frank",
"phone": "1 555 555-1234",
"email": "franksmith#school.edu",
"name": "Frank Smith",
"roleCode": "PI"
},
{
"lastName": "Doe",
"commonName": "John",
"phone": "1 555 555-9876",
"email": "johndoe#school.edu",
"name": "John Doe",
"roleCode": "PI"
}
]
}
(a bunch of non-relevant fields omitted)
Each outline object may contain an instructor property which is an array of 0..n instructor objects for the course. For each member of the instructor array, I need to then call another API to get additional data. When that call returns, I need to insert it into the right instructor object.
Finally, when everything is done, the data gets passed to a template for express to render and return to the client.
I've tried getting this working using async and had some success with async.waterfall when doing a proof-of-concept with only getting one of the instructor profiles (e.g. not looping over the array, just getting instructor[0]). The async module's docs are comprehensive, but pretty dense and I'm having a hard time determining what I actually need to do. I had a Frankenstein combination of various nested async calls which still didn't work.
I don't really care how I accomplish the task - flow-control, promises, magic pixie dust, whatever. Any hints greatly appreciated.
Using Q for promises, you can probably do something like this:
return Q
.all(course_ids.map(function(course) {
return HTTP.GET(course); // Assuming this returns a promise
}))
.then(function(course_data) {
var instructors = [];
course_data.forEach(function(course) {
var p = Q
.all(course.instructor.map(function(instructor) {
return HTTP.GET(instructor.id);
}))
.then(function(instructors) {
course.instructors_data = instructors;
return course;
});
promises.push(p);
});
return Q.all(promises);
});
Will resolve with an array containing the courses, each of which contains
an array of instructor data in its instructors_data value.
You could use async.each(), which would do the API requests in parallel (assuming there is no concurrent API request limits on the server side, if that is the case, use async.eachLimit() instead):
async.each(instructors, function(instructor, callback) {
// call API here, store result on `instructor`,
// and call `callback` when done
}, function(err){
if (err)
console.log('An error occurred while processing instructors');
else
console.log('All instructors have been processed successfully');
});

Resources