Related
In TestRail, I have created several testruns. When I execute:
test_runs = client.send_get('get_runs/1')
pprint(test_runs)
The following results are returned:
{'_links': {'next': None, 'prev': None},
'limit': 250,
'offset': 0,
'runs': [{'assignedto_id': None,
'blocked_count': 0,
'completed_on': None,
'config': None,
'config_ids': [],
'created_by': 1,
'created_on': 1651790693,
'custom_status1_count': 0,
'custom_status2_count': 0,
'custom_status3_count': 0,
'custom_status4_count': 0,
'custom_status5_count': 0,
'custom_status6_count': 0,
'custom_status7_count': 0,
'description': None,
'failed_count': 1,
'id': 13,
'include_all': False,
'is_completed': False,
'milestone_id': None,
'name': '2022-05-05-testrun',
'passed_count': 2,
'plan_id': None,
'project_id': 1,
'refs': None,
'retest_count': 0,
'suite_id': 1,
'untested_count': 0,
'updated_on': 1651790693,
'url': 'https://xxxxxxxxxx.testrail.io/index.php?/runs/view/13'},
{'assignedto_id': None,
'blocked_count': 0,
'completed_on': 1650989972,
'config': None,
'config_ids': [],
'created_by': 5,
'created_on': 1650966329,
'custom_status1_count': 0,
'custom_status2_count': 0,
'custom_status3_count': 0,
'custom_status4_count': 0,
'custom_status5_count': 0,
'custom_status6_count': 0,
'custom_status7_count': 0,
'description': None,
'failed_count': 0,
'id': 9,
'include_all': False,
'is_completed': True,
'milestone_id': None,
'name': 'This is a new test run',
'passed_count': 0,
'plan_id': None,
'project_id': 1,
'refs': None,
'retest_count': 0,
'suite_id': 1,
'untested_count': 3,
'updated_on': 1650966329,
'url': 'https://xxxxxxxxxx.testrail.io/index.php?/runs/view/9'}],
'size': 2}
In my code, I am trying to scan through all of the resulting testruns, locate the testrun I'm interested in by matching the testrun name, and then have the ID for the testrun returned.
from pprint import pprint
from testrail import *
class connecting():
def connectPostRun(self):
client = APIClient('https://xxxxxxxxxx.testrail.io')
client.user = 'abc#abc.com'
client.password = 'abc123'
test_run_name = '2022-05-05-testrun'
test_runs = client.send_get('get_runs/1')
pprint(test_runs)
for test_run in test_runs:
if test_run['name'] == test_run_name:
run_id = test_run['id']
break
return run_id
pprint(run_id)
c=connecting()
c.connectPostRun()
Executing the code as is now results in the following error:
if test_run['name'] == test_run_name:
TypeError: string indices must be integers
You're looping over the wrong part of the datastructure that the function returned. The loop for test_run in test_runs: only iterates over the keys of the top-level dictionary ("_links", "limit", etc.).
You want to be looping over test_runs['runs'], which will give you dictionaries with the "name" keys you're matching against. Try making your loop look like this:
for test_run in test_runs['runs']:
if test_run['name'] == test_run_name:
run_id = test_run['id']
break
I'd note that there's a potential problem in this code, that if you never find a matching run, the run_id variable will never be assigned to, so the return statement at the end of the function will raise an exception. If you think that could ever happen, you should probably either set a default value, or perhaps raise your own exception (with a more clear message) if you get into that situation.
I am pulling data from an API and looks like this.
{'results': {'payroll_report': {'1437252': {'user_id': 1437252,
'client_id': '606152',
'start_date': '2021-07-13',
'end_date': '2021-07-13',
'total_re_seconds': 14340,
'total_pto_seconds': 0,
'total_work_seconds': 14340,
'total_paid_break_seconds': 0,
'total_unpaid_break_seconds': 0,
'pto_seconds': {},
'overtime_seconds': {'1.5': 0, '2': 0},
'timesheet_count': 2},
'1413446': {'user_id': 1413446,
'client_id': '606152',
'start_date': '2021-07-13',
'end_date': '2021-07-13',
'total_re_seconds': 14160,
'total_pto_seconds': 0,
'total_work_seconds': 14160,
'total_paid_break_seconds': 0,
'total_unpaid_break_seconds': 0,
'pto_seconds': {},
'overtime_seconds': {'1.5': 0, '2': 0},
I want to convert it from this format to a CSV.
response = requests.request("POST", url, data=payload, headers=headers)
df = json.loads(response.text)
is my current code, I cannot get this to work!
user_id,'client_id','start_date','end_date',
'total_re_seconds',
'total_pto_seconds',
'total_work_seconds',
'total_paid_break_seconds',
'total_unpaid_break_seconds',
'pto_seconds',
'overtime_seconds',
'timesheet_count'
To be my column headers! Any help would be awesome tia!
The values you want is a nested dictionary so you have to specify the on you want from the parent dictionary to be converted to a pandas df
mydict = {'results': {'payroll_report': {'1437252': {'user_id': 1437252, 'client_id': '606152', 'start_date': '2021-07-13', 'end_date': '2021-07-13', 'total_re_seconds': 14340, 'total_pto_seconds': 0, 'total_work_seconds': 14340, 'total_paid_break_seconds': 0, 'total_unpaid_break_seconds': 0, 'pto_seconds': {}, 'overtime_seconds': {'1.5': 0, '2': 0}, 'timesheet_count': 2}, '1413446': {'user_id': 1413446, 'client_id': '606152', 'start_date': '2021-07-13', 'end_date': '2021-07-13', 'total_re_seconds': 14160, 'total_pto_seconds': 0, 'total_work_seconds': 14160, 'total_paid_break_seconds': 0, 'total_unpaid_break_seconds': 0, 'pto_seconds': {}, 'overtime_seconds': {'1.5': 0, '2': 0}}}}}
df = pd.DataFrame(mydict['results']['payroll_report']['1437252'])
print(df)
df.to_csv(r'Path where you want to store the exported CSV file\File Name.csv', index = False)
I am trying to indent and assort the format of balance so that it is easier to read. I want to print the RequestResponse like the Expected output. The balance variable is of type tuple. How could I do such a thing?
import bybit
import json
balance = client.Wallet.Wallet_getBalance(coin="BTC").result()
print(balance)
Output:
({'ret_code': 0, 'ret_msg': 'OK', 'ext_code': '', 'ext_info': '', 'result': {'BTC': {'equity': 0.00208347, 'available_balance': 0.00208347, 'used_margin': 0, 'order_margin': 0, 'position_margin': 0, 'occ_closing_fee': 0, 'occ_funding_fee': 0, 'wallet_balance': 0.00208347, 'realised_pnl': 0, 'unrealised_pnl': 0, 'cum_realised_pnl': 8.347e-05, 'given_cash': 0, 'service_cash': 0}}, 'time_now': '1616685310.655072', 'rate_limit_status': 118, 'rate_limit_reset_ms': 1616685310652, 'rate_limit': 120}, <bravado.requests_client.RequestsResponseAdapter object at 0x000001F5E92EB048>)
Expected Output:
{
"cross_seq": 11518,
"data": [
{
"price": "2999.00",
"side": "Buy",
"size": 9,
"symbol": "BTCUSD"
},
{
"price": "3001.00",
"side": "Sell",
"size": 10,
"symbol": "BTCUSD"
}
],
"timestamp_e6": 1555647164875373,
"topic": "orderBookL2_25.BTCUSD",
"type": "snapshot"
}
I think you provided the wrong expected output since the fields between your output and expected output don't match but in general if you want a better display of a dictionary you can use the json package:
response = {'ret_code': 0, 'ret_msg': 'OK', 'ext_code': '', 'ext_info': '', 'result': {'BTC': {'equity': 0.00208347, 'available_balance': 0.00208347, 'used_margin': 0, 'order_margin': 0, 'position_margin': 0, 'occ_closing_fee': 0, 'occ_funding_fee': 0, 'wallet_balance': 0.00208347, 'realised_pnl': 0, 'unrealised_pnl': 0, 'cum_realised_pnl': 8.347e-05, 'given_cash': 0, 'service_cash': 0}}, 'time_now': '1616685310.655072', 'rate_limit_status': 118, 'rate_limit_reset_ms': 1616685310652, 'rate_limit': 120}
import json
json.loads(json.dumps(response, indent=4, sort_keys=True))
This will give you the following output:
{'ext_code': '',
'ext_info': '',
'rate_limit': 120,
'rate_limit_reset_ms': 1616685310652,
'rate_limit_status': 118,
'result': {'BTC': {'available_balance': 0.00208347,
'cum_realised_pnl': 8.347e-05,
'equity': 0.00208347,
'given_cash': 0,
'occ_closing_fee': 0,
'occ_funding_fee': 0,
'order_margin': 0,
'position_margin': 0,
'realised_pnl': 0,
'service_cash': 0,
'unrealised_pnl': 0,
'used_margin': 0,
'wallet_balance': 0.00208347}},
'ret_code': 0,
'ret_msg': 'OK',
'time_now': '1616685310.655072'}
Another solution is to use pprint
import pprint
pprint.pprint(response)
This will give you the following output:
{'ext_code': '',
'ext_info': '',
'rate_limit': 120,
'rate_limit_reset_ms': 1616685310652,
'rate_limit_status': 118,
'result': {'BTC': {'available_balance': 0.00208347,
'cum_realised_pnl': 8.347e-05,
'equity': 0.00208347,
'given_cash': 0,
'occ_closing_fee': 0,
'occ_funding_fee': 0,
'order_margin': 0,
'position_margin': 0,
'realised_pnl': 0,
'service_cash': 0,
'unrealised_pnl': 0,
'used_margin': 0,
'wallet_balance': 0.00208347}},
'ret_code': 0,
'ret_msg': 'OK',
'time_now': '1616685310.655072'}
Import JSON, then using json.dumps(balance, indent=4) would get you that format.
You could add keyword argument of sort_keys=True if you want them sorted.
Currently I'm trying to get 'stringency' data from a json file which contains dates and countries. Here's an excerpt of what the json output looks like:
import pandas as pd
import json
from bs4 import BeautifulSoup
# load file
with open("Stringency April 8.txt") as file:
stringency_data = json.load(file)
stringency_data["data"]
#this gives the output:
{'2020-01-02': {'ABW': {'confirmed': None,`
'country_code': 'ABW',
'date_value': '2020-01-02',
'deaths': None,
'stringency': 0,
'stringency_actual': 0},
'AFG': {'confirmed': 0,
'country_code': 'AFG',
'date_value': '2020-01-02',
'deaths': 0,
'stringency': 0,
'stringency_actual': 0},
'AGO': {'confirmed': None,
'country_code': 'AGO',
'date_value': '2020-01-02',
'deaths': None,
'stringency': 0,
'stringency_actual': 0},
'AUS': {'confirmed': 0,
'country_code': 'AUS',
'date_value': '2020-01-02',
'deaths': 0,
'stringency': 7.14,
'stringency_actual': 7.14},
'AUT': {'confirmed': 0,
'country_code': 'AUT',
'date_value': '2020-01-02',
'deaths': 0,
'stringency': 0,
'stringency_actual': 0},.........
Here's my code so far (I've shortened it a bit for the sake of this post):
# create empty list for dates
date_index = []
[date_index.append(date) for date in stringency_data["data"]]
#creates empty lists for countries
Australia = []
Austria = []
...
US = []
# put these lists into a list
countries_lists = [Australia, Austria,...US]
# put country codes into a list
country_codes = ["AUS", "AUT",..."USA"]
# loop through countries
i = 0
for country, code in zip(countries_lists, country_codes):
while i<=len(date_index):
country.append(stringency_data["data"][date_index[i]][code]["stringency_actual"])
i+=1
When I print the list "Australia" I get all the values I want. But ever country from Austria onwards is still an empty list.
I get the output - KeyError: "AUS". This indicates that the code retrieved the whole time series, but only for the first country (Australia). How can I loop this for each country code?
Here's what I see about the data you've described/shown:
file data is a dictionary; single known/desired key is "data", value is a dictionary.
--> keys are all date_strings. Each value is a dictionary.
-----> keys are all country_codes. Each value is a dictionary.
--------> a key "stringency_actual" is present, and its value is desired.
So a straightforward plan for getting this data out could look like this:
1. grab file['data']
2. iterate all keys and values in this dictionary. (Actually, you may only care about the values.)
3. iterate all keys and values in this dictionary. Keys are country_codes, which tell you to which list you want to append the stringency_actual value you're about to get.
4. grab this dictionary['stringency_actual'] and append it to the list corresponding to the correct country.
4b. translate the country_code to the country_name, since that's apparently how you would like to store this data for now.
I changed the data retrieval because the data is all dictionaries so it's self-describing by its keys. Doing it this way can help prevent the KeyError I see mentioned in the original question and a comment. (Without the complete input file or the line number of the KeyError, I think none of us is 100% certain which value in the input is causing that KeyError.)
Potential answer:
import json
# Input sample data; would actually be retrieved from file.
stringency_data = json.loads("""
{"data": {"2020-01-02": {"ABW": {"confirmed": null,
"country_code": "ABW",
"date_value": "2020-01-02",
"deaths": null,
"stringency": 0,
"stringency_actual": 0},
"AFG": {"confirmed": 0,
"country_code": "AFG",
"date_value": "2020-01-02",
"deaths": 0,
"stringency": 0,
"stringency_actual": 0},
"AGO": {"confirmed": null,
"country_code": "AGO",
"date_value": "2020-01-02",
"deaths": null,
"stringency": 0,
"stringency_actual": 0},
"AUS": {"confirmed": 0,
"country_code": "AUS",
"date_value": "2020-01-02",
"deaths": 0,
"stringency": 7.14,
"stringency_actual": 7.14},
"AUT": {"confirmed": 0,
"country_code": "AUT",
"date_value": "2020-01-02",
"deaths": 0,
"stringency": 0,
"stringency_actual": 0}}}
}""")
country_name_by_code = {
'ABW': 'Aruba',
'AFG': 'Afghanistan',
'AUS': 'Australia',
'AUT': 'Austria',
# ...
'USA': 'United States'
}
# Output data we want to create
actual_stringencies_by_country_name = {}
# Helper method to store data we're interested in
def append_country_stringency(country_code, actual_stringency_value):
if country_code not in country_name_by_code:
print(f'Unknown country_code value "{country_code}"; ignoring.')
return
country_name = country_name_by_code[country_code]
if country_name not in actual_stringencies_by_country_name:
actual_stringencies_by_country_name[country_name] = []
actual_stringencies_by_country_name[country_name].append(actual_stringency_value)
# Walk our input data and store the parts we're looking for
for date_string, data_this_date in stringency_data['data'].items():
for country_code, country_data in data_this_date.items():
append_country_stringency(country_code, country_data['stringency_actual'])
print(actual_stringencies_by_country_name)
My output:
C:\some_dir>python test.py
Unknown country_code value "AGO"; ignoring.
{'Aruba': [0], 'Afghanistan': [0], 'Australia': [7.14], 'Austria': [0]}
I want to convert one json file format to another format.
input json file looks like,
json1 = {"Roll Number":{"0":"12345675890"},"Exam Code":{"0":"125"},"q1":{"0":"A"},"q2":{"0":"B"},"q3":{"0":"B"},"q4":{"0":"C"},"q5":{"0":"C"}
Here you can consider 0 as the 0th student (answersheet of first student)
I want this output format,
json2 = {
"id": 1,
"Roll Number": 12345675890,
"Exam Code": 125,
"qtn_ans_id": 1, #this is question number
"field1": 0,
"field2": 0,
"field3": 1, #if ans is C then field3=1 and else is 0
"field4": 0,
}
in json1 it contains 5 question answers and details and i want to convert it into json2, and my code is
import json
Stored json file into data
with open('json1.json') as data_file:
data = json.load(data_file)
write default format
format = {"table": "omr",
"rows":
[
{
"id": 1,
"regist_no": 1215152,
"exam_id": 125,
"qtn_ans_id": 1,
"field1": 0,
"field2": 0,
"field3": 0,
"field4": 0,
}
]
}
My dummy Code
json2 = {}
for (k, v) in data.items():
if(k=='Roll Number'):
format['rows'][0]['regist_no']=v['0']
if(k=='Exam Code'):
format['rows'][0]['exam_id'] = v['0']
if(v['0']=='A'):
format['rows'][0]['field1'] = 1
elif(v['0']=='B'):
format['rows'][0]['field2'] = 1
elif(v['0']=='C'):
format['rows'][0]['field3'] = 1
elif(v['0']=='D'):
format['rows'][0]['field4'] = 1
json2.append(format['rows'])
wrong output i get is,
[{
'field1': 1,
'field2': 1,
'field3': 1,
'field4': 1
}]
All the field values are 1.
For answer A Right output can be,
[{
'field1': 1,
'field2': 0,
'field3': 0,
'field4': 0
}]
or is there any other way like using pandas data frame.
I know this is long and dummy question but i will be glade if anyone can help. Thank you!
How about something like this?
# assuming your json data looks like this:
json1 = [
{
"Roll Number" : {"0":"12345675890"},
"Exam Code" : {"0":"125"},
"q1" : {"0":"A"},
"q2" : {"0":"B"},
"q3" : {"0":"B"},
"q4" : {"0":"C"},
"q5" : {"0":"C"},
},
{
"Roll Number" : {"0":"12345675891"},
"Exam Code" : {"0":"125"},
"q1" : {"0":"C"},
"q2" : {"0":"B"},
"q3" : {"0":"A"},
"q4" : {"0":"C"},
"q5" : {"0":"D"},
},
]
Then:
# converts old question field to new question field:
def ConvertAnswer(question):
# get letter answer from question:
for key, value in question.items():
letter = value
# pack fields object:
fields = {
'field1' : 1 if letter == 'A' else 0,
'field2' : 1 if letter == 'B' else 0,
'field3' : 1 if letter == 'C' else 0,
'field4' : 1 if letter == 'D' else 0,
}
return fields
# iterate over each student:
for student in json1:
# iterate over each field in student:
for key, value in student.items():
# check for questions (check if key starts with 'q'):
if key[0] == 'q':
# replace question field in student object:
student[key] = ConvertAnswer(value)
Will result in:
# output of json1:
[{'Roll Number': {'0': '12345675890'},
'Exam Code': {'0': '125'},
'q1': {'field1': 1, 'field2': 0, 'field3': 0, 'field4': 0},
'q2': {'field1': 0, 'field2': 1, 'field3': 0, 'field4': 0},
'q3': {'field1': 0, 'field2': 1, 'field3': 0, 'field4': 0},
'q4': {'field1': 0, 'field2': 0, 'field3': 1, 'field4': 0},
'q5': {'field1': 0, 'field2': 0, 'field3': 1, 'field4': 0}},
{'Roll Number': {'0': '12345675891'},
'Exam Code': {'0': '125'},
'q1': {'field1': 0, 'field2': 0, 'field3': 1, 'field4': 0},
'q2': {'field1': 0, 'field2': 1, 'field3': 0, 'field4': 0},
'q3': {'field1': 1, 'field2': 0, 'field3': 0, 'field4': 0},
'q4': {'field1': 0, 'field2': 0, 'field3': 1, 'field4': 0},
'q5': {'field1': 0, 'field2': 0, 'field3': 0, 'field4': 1}}]
My solution in more "pandasonic" than the other answer.
Start from defining a function, which will be used to change
the answer code to 4 answer columns:
def ans(code):
return pd.Series([ int(code == x) for x in 'ABCD' ],
index=[ 'field' + str(i) for i in range(1, 5)])
Read your input file into a DataFrame as follows:
with open('input.json') as data_file:
df = pd.read_json(data_file, orient='columns')
Then reformat it, saving in another DataFrame:
df2 = pd.wide_to_long(df.rename_axis(index='id').reset_index(),
stubnames='q', i='Roll Number', j='qtn_ans_id').reset_index()\
.reindex(columns=['id', 'Roll Number', 'Exam Code', 'qtn_ans_id', 'q'])
For now it contains one column q with answer codes.
So to change it into 4 columns for each field, run:
df2 = df2.join(df2.q.apply(ans)).drop(columns=['q'])
And the last step is to create the output JSON string:
df2.to_json(orient='records')
which you can e.g. save in an output file.
Note: If your input contained e.g. data for 2 students,
the JSON file should have the following form:
{
"Roll Number":{"0":12345675890,"1":23456758901},
"Exam Code":{"0":125,"1":125},
"q1":{"0":"A","1":"A"},
"q2":{"0":"B","1":"B"},
"q3":{"0":"B","1":"C"},
"q4":{"0":"C","1":"D"},
"q5":{"0":"C","1":"C"}
}
(different than the input format proposed in the other answer).