Python Boto get_report class call? - python

What I am trying to do is get a report using Boto and Get_Report(). I have a valid report id, and seem to be having problems getting the python call correct. The call requires the variable ReportId and I have been trying various methods of getting it to accept the id.
from boto.mws.connection import MWSConnection
import sys, getopt
def main(argv):
MarketPlaceID = 'a'
Merchant = 'a'
AccessKeyID = 'a'
SecretKey = 'a'
program_name = sys.argv[0]
MarketPlaceID = sys.argv[1]
Merchant = sys.argv[2]
AccessKeyID = sys.argv[3]
SecretKey = sys.argv[4]
print 'MarketplaceID is ', MarketPlaceID
print 'Merchant is ', Merchant
print 'AccessKey is ', AccessKeyID
print 'Secret key is ', SecretKey
conn = MWSConnection(AccessKeyID,SecretKey)
conn.SellerId = Merchant
conn.Merchant = Merchant
conn.MarketplaceId = MarketPlaceID
myId = '1432456045'
# sample one
conn.get_report(ReportId=myId)
# sample two
conn.get_report(myId)
# sample three
conn.get_report(myId,)
# sample four
conn.get_report(1432456045)
# sample five
conn.get_report('1432456045')
if __name__ == "__main__":
main(sys.argv1:)
With each of these five variations, I get the same key error: KeyError: 'GetReport requires R+e+p+o+r+t+I+d argument(s)'. This example will take the four arguments (MarketPlaceID, Merchant, AccessKeyID, and SecretKey) and tries to call get_report. The id number is a valid report, I have successfully used the scratchpad and downloaded the csv file.
The object is to call the get_report() call with a value of an inventory file. The call within boto takes an argument of an integer. I have tried various versions from an integer, integer encased within a string, and a list of one integer. Each of these failed with the same access key error.
I know that the five samples that I have above don't work as I have them. Has anyone successfully got the Get_report call to work? And could you point me to what I am doing incorrect?
Thank you

I ran into the same issue. The problem is actually in connection.py.
#requires('ReportId')
Should read
#requires(['ReportId'])
Hope this helps!

http://boto.readthedocs.org/en/latest/ref/mws.html#boto.mws.connection.MWSConnection.get_report
get_report() worked for me when I used something similar to this:
from boto.mws.connection import MWSConnection
MarketPlaceID = 'a'
MerchantID = 'a'
AccessKeyID = 'a'
SecretKey = 'a'
mws = MWSConnection(AccessKeyID,SecretKey)
mws.SellerId = MerchantID
mws.Merchant = MerchantID
mws.MarketplaceId = MarketPlaceID
report = mws.get_report(ReportId='1234567890')

Related

AWS KMS client not returning an alias name

I've been using the list_aliases() method of KMS client since a while now without any issues. But recently it has stopped listing one of the alias names I want to use.
import boto3
kms_client = boto3.client('kms')
# Getting all the aliases from my KMS
key_aliases = kms_client.list_aliases()
key_aliases = key_aliases['Aliases']
# DO SOMETHING...
The key_aliases list above contains all the keys except the one I want to use. However, I can see from the AWS KMS UI that the key is enabled. Not sure why the list_aliases() method is not returning it.
Has anyone faced this problem?
It looks like the response is truncated. The default number of aliases fetched by this API call is 50. You can increase the limit up to 100, which should solve your problem.
key_aliases = kms_client.list_aliases(Limit=100)
You should also check if the truncated field in the response is set to True. In that case, you can just make another API call to fetch the remaining results:
if key_aliases['Truncated'] is True:
key_aliases = kms_client.list_aliases(Marker=key_aliases['NextMarker'])
...
def get_keys_arn(kmsclient,key_name):
#Marker = 'string'
alias_list = kmsclient.list_aliases(Limit=999)
if alias_list['Truncated'] is True:
alias_list_trun = alias_list['Aliases']
for alias in alias_list_trun:
if alias["AliasName"] == "alias/" + key_name:
return alias["TargetKeyId"]
while alias_list['Truncated'] :
alias_list = kmsclient.list_aliases(Limit=999,Marker=alias_list['NextMarker'])
alias_list_trun = alias_list['Aliases']
for alias in alias_list_trun:
if alias["AliasName"] == "alias/" + key_name:
return alias["TargetKeyId"]
else:
alias_list= alias_list['Aliases']
for alias in alias_list:
if alias["AliasName"] == "alias/" + key_name:
return alias["TargetKeyId"]

class instance method takes exactly two args, one given

I am having a bit of an issue. First off, I know that this code is able to stand alone and not be in a class but I would prefer that it is in a class. Second, when I run the code, I get this error TypeError: set_options() takes exactly 2 arguments (1 given) .
Here is my code. If anyone could point me in the right direction, I would appreciate it. I'm assuming that the set_options method isn't getting my jobj instance. Am I correct in assuming that and how would one go about fixing this? ps. I do have the correct imports and here is my py command at terminal python test.py radar 127.0.0.1 hashNumber testplan:speed
class TransferStuff(object):
tool = sys.argv[1]
target = sys.argv[2]
hash = sys.argv[3]
options = sys.argv[4]
def set_options(self, test_options):
option_arr = test_options.split(',')
new_arr = [i + ':{}'.format(i) for i in option_arr if ':' not in i]
for i in option_arr:
if ':' in i:
new_arr.append(i)
d = {}
for i in new_arr:
temp = i.split(':')
d[temp[0]] = temp[1]
return d
data = {'target': target, 'test': tool, 'HASH': hash,
'options': set_options(options)}
def write_to_json(self):
"""Serialize cli args and tool options in json format.
Write stream to json file.
"""
with open('envs.json', 'w') as fi:
json.dump(TransferStuff.data, fi)
if __name__ == "__main__":
try:
jobj = TransferStuff()
jobj.write_to_json()
Your method is inside a class, you need to create a instance of the class:
transfer_stuff_instance = TransferStuff()
And call the method with this instance:
transfer_stuff_instance.ser_options(options)

Selecting values from a JSON file in Python

I am getting JIRA data using the following python code,
how do I store the response for more than one key (my example shows only one KEY but in general I get lot of data) and print only the values corresponding to total,key, customfield_12830, summary
import requests
import json
import logging
import datetime
import base64
import urllib
serverURL = 'https://jira-stability-tools.company.com/jira'
user = 'username'
password = 'password'
query = 'project = PROJECTNAME AND "Build Info" ~ BUILDNAME AND assignee=ASSIGNEENAME'
jql = '/rest/api/2/search?jql=%s' % urllib.quote(query)
response = requests.get(serverURL + jql,verify=False,auth=(user, password))
print response.json()
response.json() OUTPUT:-
http://pastebin.com/h8R4QMgB
From the the link you pasted to pastebin and from the json that I saw, its a you issues as list containing key, fields(which holds custom fields), self, id, expand.
You can simply iterate through this response and extract values for keys you want. You can go like.
data = response.json()
issues = data.get('issues', list())
x = list()
for issue in issues:
temp = {
'key': issue['key'],
'customfield': issue['fields']['customfield_12830'],
'total': issue['fields']['progress']['total']
}
x.append(temp)
print(x)
x is list of dictionaries containing the data for fields you mentioned. Let me know if I have been unclear somewhere or what I have given is not what you are looking for.
PS: It is always advisable to use dict.get('keyname', None) to get values as you can always put a default value if key is not found. For this solution I didn't do it as I just wanted to provide approach.
Update: In the comments you(OP) mentioned that it gives attributerror.Try this code
data = response.json()
issues = data.get('issues', list())
x = list()
for issue in issues:
temp = dict()
key = issue.get('key', None)
if key:
temp['key'] = key
fields = issue.get('fields', None)
if fields:
customfield = fields.get('customfield_12830', None)
temp['customfield'] = customfield
progress = fields.get('progress', None)
if progress:
total = progress.get('total', None)
temp['total'] = total
x.append(temp)
print(x)

Why can't I pickle this list?

The purpose of this form is to let users enter a lot of places (comma separated) and it'll retrieve the phone, name, website. Have it working in a python IDE, no problem, but having issues putting it into my webapp.
I'm getting the error Exception Value: Can't pickle local object 'GetNums.<locals>.get_data' at the line where a is assigned. I checked the type of inputText and verified that it is indeed a list. So, I'm not sure why it won't pickle.
def GetNums(request):
form = GetNumsForm(request.POST or None)
if form.is_valid():
inputText = form.cleaned_data.get('getnums')
# all experimental
inputText = inputText.split(',')
def get_data(i):
#DON'T FORGET TO MOVE THE PRIMARY KEY LATER TO SETTINGS
r1 = requests.get('https://maps.googleapis.com/maps/api/place/textsearch/json?query=' + i + '&key=GET_YOUR_OWN')
a = r1.json()
pid = a['results'][0]['place_id']
r2 = requests.get('https://maps.googleapis.com/maps/api/place/details/json?placeid=' + pid + '&key=GET_YOUR_OWN')
b = r2.json()
phone = b['result']['formatted_phone_number']
name = b['result']['name']
try:
website = b['result']['website']
except:
website ='No website found'
return ' '.join((phone, name, website))
v = str(type(inputText))
with Pool(5) as p:
a = (p.map(get_data, inputText))
# for line in p.map(get_data, inputText):
# print(line)
#code assist by http://stackoverflow.com/a/34512870/5037442
#end experimental
return render(request, 'about.html', {'v': a})
It's actually barfing when trying to pickle get_data, which is a nested function/closure.
Move get_data out of GetNums (and agh rename it to snake_case please) and it should work.

Reading specific test steps from Quality Center with python

I am working with Quality Center via OTA COM library. I figured out how to connect to server, but I am lost in OTA documentation on how to work with it. What I need is to create a function which takes a test name as an input and returns number of steps in this test from QC.
For now I am this far in this question.
import win32com
from win32com.client import Dispatch
# import codecs #to store info in additional codacs
import re
import json
import getpass #for password
qcServer = "***"
qcUser = "***"
qcPassword = getpass.getpass('Password: ')
qcDomain = "***"
qcProject = "***"
td = win32com.client.Dispatch("TDApiOle80.TDConnection.1")
#Starting to connect
td.InitConnectionEx(qcServer)
td.Login(qcUser,qcPassword)
td.Connect(qcDomain, qcProject)
if td.Connected == True:
print "Connected to " + qcProject
else:
print "Connection failed"
#Path = "Subject\Regression\C.001_Band_tones"
mg=td.TreeManager
npath="Subject\Regression"
tsFolder = td.TestSetTreeManager.NodeByPath(npath)
print tsFolder
td.Disconnect
td.Logout
print "Disconnected from " + qcProject
Any help on descent python examples or tutorials will be highly appreciated. For now I found this and this, but they doesn't help.
Using the OTA API to get data from Quality Center normally means to get some element by path, create a factory and then use the factory to get search the object. In your case you need the TreeManager to get a folder in the Test Plan, then you need a TestFactory to get the test and finally you need the DesignStepFactory to get the steps. I'm no Python programmer but I hope you can get something out of this:
mg=td.TreeManager
npath="Subject\Test"
tsFolder = mg.NodeByPath(npath)
testFactory = tsFolder.TestFactory
testFilter = testFactory.Filter
testFilter["TS_NAME"] = "Some Test"
testList = testFactory.NewList(testFilter.Text)
test = testList.Item(1) # There should be only 1 item
print test.Name
stepFactory = test.DesignStepFactory
stepList = stepFactory.NewList("")
for step in stepList:
print step.StepName
It takes some time to get used to the QC OTA API documentation but I find it very helpful. Nearly all of my knowledge comes from the examples in the API documentation—for your problem there are examples like "Finding a unique test" or "Get a test object with name and path". Both examples are examples to the Test object. Even if the examples are in VB it should be no big thing to adapt them to Python.
I figured out the solution, if there is a better way to do this you are welcome to post it.
import win32com
from win32com.client import Dispatch
import getpass
def number_of_steps(name):
qcServer = "***"
qcUser = "***"
qcPassword = getpass.getpass('Password: ')
qcDomain = "***"
qcProject = "***"
td = win32com.client.Dispatch("TDApiOle80.TDConnection.1")
#Starting to connect
td.InitConnectionEx(qcServer)
td.Login(qcUser, qcPassword)
td.Connect(qcDomain, qcProject)
if td.Connected is True:
print "Connected to " + qcProject
else:
print "Connection failed"
mg = td.TreeManager # Tree manager
folder = mg.NodeByPath("Subject\Regression")
testList = folder.FindTests(name) # Make a list of tests matching name (partial match is accepted)
if testList is not None:
if len(testList) > 1:
print "There are multiple tests matching this name, please check input parameter\nTests matching"
for test in testList:
print test.name
td.Disconnect
td.Logout
return False
if len(testList) == 1:
print "In test %s there is %d steps" % (testList[0].Name, testList[0].DesStepsNum)
else:
print "There are no test with this test name in Quality Center"
td.Disconnect
td.Logout
return False
td.Disconnect
td.Logout
print "Disconnected from " + qcProject
return testList[0].DesStepsNum # Return number of steps for given test

Categories