Gathering API payload (Dell DataIQ) - python

Trying to figure out how to extract the payload from a Dell DataIQ server. From the documentation the call looks like:
def updateShareReports(api):
request = claritynowapi.FastStatRequest()
request.resultType = claritynowapi.FastStatRequest.ALL_PATHS
subRequest = claritynowapi.SubRequest()
subRequest.name = 'Shares'
request.requests.append(subRequest)
results = api.report(request)
report = results.requests[0].results
print (report)
I added the print line in there hoping to see the output, but what I get is: [<claritynowapi.PathResult object at 0x00000233D1C8B700>]
Any suggestions on what I need to do to see the output in a json?
Thanks

Related

extract dicitonary values from non-subscriptable object-type in python

i'm a python novice, trying to learn and be useful at work at the same time
we use DespatchBay to send parcels. they have a SOAP API which i don't entirely understand, and am using an SDK they released.
before booking a collection and producing a label my code queries the api to get available services, and available dates, and returns what i think are custom object-types containing the info i need. i want to extract and then print information from these objects so that i can confirm the correct details have been used.
postcode = "NW1 4RY"
street_num = 1
recipient_address = client.find_address(postcode, street_num)
print (recipient_address)
yields:
(AddressType){
CompanyName = "London Zoo"
Street = "Regents Park"
Locality = None
TownCity = "London"
County = None
PostalCode = "NW1 4RY"
CountryCode = "GB"
}
i can see there's a dictionary there, and i want to drill down into it to extract details, but i don't understand the "(AddressType)" before the dictionary - how do i get past it and call values from the dictionary?
AddressType has some ref here but it doesn't shine much light for me
thanks for any help you can offer!
full code: sdk ref
import os
from despatchbay.despatchbay_sdk import DespatchBaySDK
from pprint import pprint
api_user = os.getenv('DESPATCH_API_USER')
api_key = os.getenv('DESPATCH_API_KEY')
client = DespatchBaySDK(api_user=api_user, api_key=api_key)
sender_id = '5536'
# inputs
postcode = "NW1 4RY"
street_num = 1
customer = "Testy Mctestson"
phone = "07666666666"
email = "testicles#tested.com"
num_boxes = 2
collection_date = '2022-09-11'
recipient_address = client.find_address(postcode, street_num)
recipient = client.recipient(
name=customer,
telephone=phone,
email=email,
recipient_address=recipient_address
)
print (recipient_address)
parcels = []
parcel_names = []
for x in range(num_boxes):
parcelname = "my_parcel_" + str(x + 1)
parcel_names.append(parcelname)
for my_parcel in parcel_names:
go_parcel = client.parcel(
contents="Radios",
value=500,
weight=6,
length=60,
width=40,
height=40,
)
parcels.append(go_parcel)
sender = client.sender(
address_id=sender_id
)
shipment_request = client.shipment_request(
parcels=parcels,
client_reference=customer,
collection_date=collection_date,
sender_address=sender,
recipient_address=recipient,
follow_shipment='true'
)
services = client.get_available_services(shipment_request)
shipment_request.service_id = services[0].service_id
dates = client.get_available_collection_dates(sender, services[0].courier.courier_id)
print(customer + "'s shipment of",num_boxes, "parcels will be collected from: ",recipient['RecipientAddress'], "on", dates[0])
shipment_request.collection_date = dates[0]
added_shipment = client.add_shipment(shipment_request)
client.book_shipments([added_shipment])
shipment_return = client.get_shipment(added_shipment)
label_pdf = client.get_labels(shipment_return.shipment_document_id)
label_pdf.download('./' + customer + '.pdf')
You do not know exactly how they store the data inside of their object, even if it looks like a dictionary. you could run print(dir(recipient_address)) and see what the "inside of the object looks like". once you get the output you start inspecting which attributes or methods may have the data you want. Of course, you should always follow the published contract for interacting withe these objects, as the implementation details can always change. I've examine the source code of this object published here
https://github.com/despatchbay/despatchbay-python-sdk/blob/master/despatchbay/despatchbay_entities.py#L169
It turns out that it doesn't use a dictionary. It looks like you are meant to just access the data via attributes like follows:
recipient_address.company_name
recipient_address.street
recipient_address.locality
recipient_address.town_city
recipient_address.county
recipient_address.postal_code
recipient_address.country_code
I agree, their python sdk could use improved documentation..

Using a variable from a dictionary in a loop to attach to an API call

I'm calling a LinkedIn API with the code below and it does what I want.
However when I use almost identical code inside a loop it returns a type error.
it returns a type error:
File "C:\Users\pchmurzynski\OneDrive - Centiq Ltd\Documents\Python\mergedreqs.py", line 54, in <module>
auth_headers = headers(access_token)
TypeError: 'dict' object is not callable
It has a problem with this line (which again, works fine outside of the loop):
headers = headers(access_token)
I tried changing it to
headers = headers.get(access_token)
or
headers = headers[access_token]
EDIT:
I have also tried this, with the same error:
auth_headers = headers(access_token)
But it didn't help. What am I doing wrong? Why does the dictionary work fine outside of the loop, but not inside of it and what should I do to make it work?
What I am hoping to achieve is to get a list, which I can save as json with share statistics called for each ID from the "shids" list. That can be done with individual requests - one link for one ID,
(f'https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3A77487&ugcPosts=List(urn%3Ali%3AugcPost%3A{shid})
or a a request with a list of ids.
(f'https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3A77487&ugcPosts=List(urn%3Ali%3AugcPost%3A{shid},urn%3Ali%3AugcPost%3A{shid2},...,urn%3Ali%3AugcPost%3A{shidx})
Updated Code thanks to your comments.
shlink = ("https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3A77487&shares=List(urn%3Ali%3Ashare%3A{})")
#loop through the list of share ids and make an api request for each of them
shares = []
token = auth(credentials) # Authenticate the API
headers = fheaders(token) # Make the headers to attach to the API call.
for shid in shids:
#create a request link for each sh id
r = (shlink.format(shid))
#call the api
res = requests.get(r, headers = auth_headers)
share_stats = res.json()
#append the shares list with the responce
shares.append(share_stats["elements"])
works fine outside the loop
Because in the loop, you re-define the variable. Added print statments to show it
from liapiauth import auth, headers # one type
for ...:
...
print(type(headers))
headers = headers(access_token) # now set to another type
print(type(headers))
Lesson learned - don't overrwrite your imports
Some refactors - your auth token isn't changing, so don't put it in the loop; You can use one method for all LinkedIn API queries
from liapiauth import auth, headers
import requests
API_PREFIX = 'https://api.linkedin.com/v2'
SHARES_ENDPOINT_FMT = '/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3A77487&shares=List(urn%3Ali%3Ashare%3A{}'
def get_linkedin_response(endpoint, headers):
return requests.get(API_PREFIX + endpoint, headers=headers)
def main(access_token=None):
if access_token is None:
raise ValueError('Access-Token not defined')
auth_headers = headers(access_token)
shares = []
for shid in shids:
endpoint = SHARES_ENDPOINT_FMT.format(shid)
resp = get_linkedin_response(endpoint, auth_headers)
if resp.status_code // 100 == 2:
share_stats = resp.json()
shares.append(share_stats[1])
# TODO: extract your data here
idlist = [el["id"] for el in shares_list["elements"]]
if __name__ == '__main__':
credentials = 'credentials.json'
main(auth(credentials))

KeyError for 'snippet' when using YouTube Data API RelatedToVideoID feature

This is my first ever question on Stack Overflow so please do tell me if anything remains unclear. :)
My issue is somewhat related to this thread. I am trying to use the YouTube Data API to sample videos for my thesis. I have done so successfully with the code below; however, when I change the criterion from a query (q) to relatedToVideoId, the unpacking section breaks for some reason.
It works outside of my loop, but not inside it (same story for the .get() suggestion from the other thread). Does anyone know why this might be and how I can solve it?
This is the (shortened) code I wrote which you can use to replicate the issue:
import numpy as np
import pandas as pd
# Allocate credentials:
from googleapiclient.discovery import build
api_key = "YOUR KEY SHOULD GO HERE"
# Session Build
youtube = build('youtube', 'v3', developerKey = api_key)
df_sample_v2 = pd.DataFrame(columns = ["Video.ID", "Title", "Channel Name"])
keywords = ['Global Warming',
'Coronavirus'
]
iter = list(range(1, 150))
rand_selec_ids = ['H6u0VBqNBQ8',
'LEZCxxKp0hM'
]
for i in iter:
# Search Request
request = youtube.search().list(
part = "snippet",
#q = keywords[4],
relatedToVideoId = rand_selec_ids[1],
type = "video",
maxResults = 5000,
videoCategoryId = 28,
order = "relevance",
eventType = "completed",
videoDuration = "medium"
)
# Save Response
response = request.execute()
# Unpack Response
rows = []
for i in list(range(0, response['pageInfo']['resultsPerPage'])):
rows.append([response['items'][i]['id']['videoId'],
response['items'][i]['snippet']['title'], # this is the problematic line
response['items'][i]['snippet']['channelTitle']]
)
temp = pd.DataFrame(rows, columns = ["Video.ID", "Title", "Channel Name"])
df_sample_v2 = df_sample_v2.append(temp)
print(f'{len(df_sample_v2)} videos retrieved!')
The KeyError I get is at the second line of rows.append() where I try to access the snippet.
KeyError Traceback (most recent call last)
<ipython-input-90-c6c01139e372> in <module>
45
46 rows.append([response['items'][i]['id']['videoId'],
---> 47 response['items'][i]['snippet']['title'],
48 response['items'][i]['snippet']['channelTitle']]
49 )
KeyError: 'snippet'
Your issue stems from the fact that the property resultsPerPage should not be used as an indicator for the size of the array items.
The proper way to iterate the items obtained from the API is as follows (this is also the general pythonic way of doing such kind of iterations):
for item in response['items']:
rows.append([
item['id']['videoId'],
item['snippet']['title'],
item['snippet']['channelTitle']
])
You may well add to your code the something like the debugging code below to convince yourself about the claim I made.
print(f"resultsPerPage={response['pageInfo']['resultsPerPage']}")
print(f"len(items)={len(response['items'])}")

Is there a way to combine 2 decorators in python with or condition?

I am using RTMclient to get slack message data. Here the type of message is 'message' which only gives us the data of parent thread. But I want the message data of replies.
On research I found it is 'message_replied' type. I want to include either message or message_replied in decorator.
Pfb a sample code.
#slack.RTMClient.run_on(event='message')
def respond(**payload):
data = payload['data']
web_client = payload['web_client']
rtm_client = payload['rtm_client']
user_id = data.get("user")
text = data.get("text")
Here I want to use #slack.RTMClient.run_on(event='message_replied') also but with 'or' condition
Looking at the source code for slack.RTMClient.run_on(), you should be able to "stack" the decorators like so:
#slack.RTMClient.run_on(event='message')
#slack.RTMClient.run_on(event='message_replied')
def respond(**payload):
data = payload['data']
web_client = payload['web_client']
rtm_client = payload['rtm_client']
user_id = data.get("user")
Have you tried this?

Get result from xml code with python

I have an xml code from nimbuzz chat app which searches for a chatroom in nimbuzz server using input keyword.
<iq type="set" id="Nimbuzz_SearchRooms" to="conference.nimbuzz.com"><query xmlns="jabber:iqearch"><set xmlns="http://jabber.org/protocol/rsm"><index>0</index><max>10</max></set><x type="get" xmlns="jabberata"><field var="name"><value>**INPUT KEYWORD FOR ROOM NAME**</value></field><field var="include_password_protected"><value>true</value></field></x></query></iq>
The code is working and I'm getting the following result as xml code:
See the image:
The result code image
I started with this code but I can't complete it because I can't understand how it works:
def handler_search_room(type, source, parameters):
Key_word = raw_input("Please write the Key word: ")
if parameters.split():
iq = xmpp.Iq('set')
iq.setID('Nimbuzz_SearchRooms')
iq.setTo('conference.nimbuzz.com)
I need to send the first code to the nimbuzz server and then I need to get the result with the information of each Chatroom.
The result code should get this information for each chatroom:
name
subject.
num_users
num_max_users
is_passowrd_protected
is_member_only
language
location-type
location
How can I do that with python? I will happy if someone would help me to make my code.
Download the XML code if you want:
http://qfs.mobi/f1833350
def handler_akif_room(type, source, parameters):
room = parameters
if parameters.split():
iq = xmpp.Iq('set')
iq.setID('Nimbuzz_SearchRooms')
iq.setTo('conference.nimbuzz.com')
query = xmpp.Node('query')
query.setNamespace('jabber:iq:search')
iq.addChild(node=query)
sett = xmpp.Node('set')
sett.setNamespace('http://jabber.org/protocol/rsm')
query.addChild(node=sett)
sifir = "0"
ind = xmpp.Node('index')
ind.setData(sifir)
sett.addChild(node=ind)
on = "10"
maxx = xmpp.Node('max')
maxx.setData(on)
sett.addChild(node=maxx)
qqx = xmpp.Node('x')
qqx.setNamespace('jabber:x:data" type="get')
query.addChild(node=qqx)
field = xmpp.Node('field')
field.setAttr('var','name')
field.setData(' ')
qqx.addChild(node=field)
valueone = xmpp.Node('value')
valueone.setData(room)
field.addChild(node=valueone)
fieldtwo = xmpp.Node('field')
fieldtwo.setAttr('var','include_password_protected')
fieldtwo.setData(' ')
qqx.addChild(node=fieldtwo)
valuetwo = xmpp.Node('value')
valuetwo.setData('true')
fieldtwo.addChild(node=valuetwo)
JCON.SendAndCallForResponse(iq, handler_akif_room_answ, {'type': type, 'source': source})
msg(source[1], u''+str(iq)+' .') ## <= OUT SHOW :)) GOOD WORK! CONTACT ME akif#nimbuzz.com :)

Categories

Resources