Python not returning variables - python

I'm trying to return a variable (list) in python but it does not allows me to return it. Instead it goes into except block and returns somethhing else.
The code is like this: Initially I'm getting period_value(datetime), search_name(location name) and time_period(day,week,month,year) via Ajax calls. If its day, then its work fine, but in other cases(week,month,year) the result variable does gives me satisfied data but it does not returns the data and instead goes into except and returns something else. This seems to be a weird problem. Kindly check where I'm going wrong?
if request.POST.has_key('period_val') or request.POST.has_key('search_name'):
try : period_val = request.POST['period_val']
except : period_val = datetime.datetime.strftime((datetime.date.today()), '%m/%d/%Y')
try: time_period = request.POST['time_period']
except : time_period = 'day'
try : search_name = request.POST['search_name']
except : search_name = ""
return HttpResponse(json.dumps(get_widgets_data(request,period_val,time_period,search_name)), mimetype = "application/json")
get_widgets_data functions
def get_widgets_data(request,period_val,time_period,search_name):
if time_period == 'day':
file_name = datetime.datetime.strptime(period_val, '%m/%d/%Y')
current_file_name = file_name.strftime("%Y-%m-%d.json")
yester_date = file_name - timedelta(days = 1)
yester_file_name = yester_date.strftime("%Y-%m-%d.json")
elif time_period == 'week':
file_name = str(period_val).split(", ")
current_file_name = file_name[1] + "-w" + file_name[0].split(" ")[0]+".json"
if (int(file_name[0].split(" ")[0]) - 1) <= 0:
year = int(file_name[1]) - 1
week = datetime.date(year,12,31).isocalendar()[-1]
yester_file_name = file_name[1] + "-w" + file_name[0]+".json"
else :
yester_file_name = file_name[1] + "-w" + str(int(file_name[0].split(" ")[0]) - 1)+".json"
elif time_period == 'month':
file_name = datetime.datetime.strptime(period_val, '%B, %Y')
current_file_name = file_name.strftime("%Y-%m.json")
yester_month = int((current_file_name.split(".")[0]).split("-")[1]) - 1
yester_year = int((current_file_name.split(".")[0]).split("-")[0])
if yester_month == 0:
yester_year = yester_year - 1
yester_month = 12
yester_file_name = str(yester_year) + "-" + str(yester_month) + ".json"
elif time_period == 'year':
file_name = datetime.datetime.strptime(period_val, '%Y')
current_file_name = file_name.strftime("%Y.json")
yester_file_name = str(int(period_val)-1) + ".json"
with open( os.path.join(os.path.dirname(__file__),'../../../../service/report/data/processed/Akamai/energy_meter/',current_file_name)) as file_handler:
current_file_content = json.load(file_handler)
file_handler.close()
user_level_mapping = UserLevelMapping.objects.filter(user_id=request.user.id)
level = (user_level_mapping[0].level_id).split(':')[0]
l_id = (user_level_mapping[0].level_id).split(':')[1]
try : # try if this file exists or not else goes into except.
with open( os.path.join(os.path.dirname(__file__),'../../../../service/report/data/processed/Akamai/energy_meter/',yester_file_name)) as file_handler:
yester_file_content = json.load(file_handler)
file_handler.close()
device_level_mapping_values = device_level_mapping_func(level,l_id)
yester_time = list()
yester_file_datetime = yester_file_content["device"].keys()
yester_total = 0.0
for time in yester_file_datetime:
yester_time.append(time.split(" ")[1])
for date_time in current_file_content["device"].keys():
time = date_time.split(" ")[1]
if time in yester_time:
for device in device_level_mapping_values:
yester_total += float(yester_file_content["device"][date_time][str(device)])
current_total = float(current_file_content['total']['levels']['level'+str(level)][str(l_id)])
baseline_energy_yester = (yester_total) - current_total
results = (current_total,baseline_energy_yester)
print results # prints(123,345) but does not returns. instead goes into except for week,month and year and returns (123,Nan)
return results
except:
current_total = float(current_file_content['total']['levels']['level'+str(level)][str(l_id)])
baseline_energy_yester = "NaN"
results = (current_total,baseline_energy_yester)
return results

Using except without identifying the types you're catching is a dangerous antipattern. If the code in the try block encountered a KeyboardInterrupt, NameError, ImportError or IOError, is it really safe to assume that it's safe to continue and the recovery is simply to make sure that 'search_name' is empty?
try : search_name = request.POST['search_name']
except : search_name = ""
As an aside, you can ask a dict to return a default if no matching key is defined:
search_name = request.POST.get('search_name', None)
Instead it goes into except block and returns somethhing else.
In general if your code encounters an exception, something is "wrong". Wrongness can vary, so it might not be devastating, but if you're not certain which exception is occurring and why then it's best not to try to handle it at all. Let it fly all the way up the stack either to some code that has context to recover or gracefully fail, or better still in cases like this -- all the way up to the developer (you!) so you can address the failure in design/implementation.

To get value of a POST post data field try using
period_val = request.POST.get('period_val')
instead of
period_val = request.POST['period_val']

Related

Rename duplicate pdf name by increasing counter

So I've written something to pull out certain string (beneficiary) from pdf's and rename the file based on the string but the problem is if there are duplicates, is there any way to add a +1 counter behind the name?
My inefficient code as follow, appreciate any help!:
for filename in os.listdir(input_dir):
if filename.endswith('.pdf'):
input_path = os.path.join(input_dir, filename)
pdf_array = (glob.glob(input_dir + '*.pdf'))
for current_pdf in pdf_array:
with pdfplumber.open(current_pdf) as pdf:
page = pdf.pages[0]
text = page.extract_text()
keyword = text.split('\n')[2]
try:
if 'attention' in keyword:
pdf_to_att = text.split('\n')[2]
start_to_att = 'For the attention of: '
to_att = pdf_to_att.removeprefix(start_to_att)
pdf.close()
result = to_att
os.rename(current_pdf, result + '.pdf')
else:
pdf_to_ben = text.split('\n')[1]
start_to_ben = 'Beneficiary Name : '
end_to_ben = pdf_to_ben.rsplit(' ', 1)[1]
to_ben = pdf_to_ben.removeprefix(start_to_ben).removesuffix(end_to_ben).rstrip()
pdf.close()
result = to_ben
os.rename(current_pdf, result + '.pdf')
except Exception:
pass
messagebox.showinfo("A Title", "Done!")
edit: the desired output should be
AAA.pdf
AAA_2.pdf
BBB.pdf
CCC.pdf
CCC_2.pdf
I would use a dict to record the occurrence count of each filename.
dict.get() returns the value for key if key is in the dictionary, else default. If default is not given, it defaults to None
pdf_name_count = {}
for current_pdf in pdf_array:
with pdfplumber.open(current_pdf) as pdf:
page = pdf.pages[0]
text = page.extract_text()
keyword = text.split('\n')[2]
try:
if 'attention' in keyword:
...
result = to_att
else:
...
result = to_ben
filename_count = pdf_name_count.get(result, 0)
if filename_count >= 1:
filename = f'{result}_{filename_count+1}.pdf'
else:
filename = result + '.pdf'
os.rename(current_pdf, filename)
# increase the name occurrence by 1
pdf_name_count[result] = filename_count + 1
except Exception:
pass
What you want is to build a string, for the filename, that includes a counter,
let's call it cnt. Python has the f-string syntax for this exact purpose, it
lets you interpolate a variable into a string.
Initialize your counter before the for loop:
cnt = 0
Replace
os.rename(current_pdf, result + '.pdf')
with
os.rename(current_pdf, f'{result}_{cnt}.pdf')
cnt += 1
The f before the opening quote introduces the f-string, and the curly braces
{} let you include any python expression, in your case we just substitute the
values of the two variables result and cnt. Then we increment the counter,
of course.
os.path.isfile can be your mate meet your needs.
import os
def get_new_name(result):
file_name = result + '{}.pdf'
file_number = 0
if os.path.isfile(file_name.format('')): # AAA.pdf
file_number = 2
while os.path.isfile(file_name.format('_{}'.format(file_number))):
file_number += 1
if file_number:
pdf_name = file_name.format('_{}'.format(file_number))
else:
pdf_name = file_name.format('')
return pdf_name
my screenshot
I update code for your output format, it can be work.

Add more then one Python Selenium WebDriverWait exception to download an element

So I have this in my script:
today = datetime.now()
today = today.strftime("%Y%m%d")
yesterday = datetime.now() - timedelta(days=1)
yesterday = yesterday.strftime("%Y%m%d")
y_yesterday = datetime.now() - timedelta(days=2)
y_yesterday = y_yesterday.strftime("%Y%m%d")
y2_yesterday = datetime.now() - timedelta(days=3)
y2_yesterday = y2_yesterday.strftime("%Y%m%d")
y3_yesterday = datetime.now() - timedelta(days=4)
y3_yesterday = y3_yesterday.strftime("%Y%m%d")
exp = "//*[#title='Some_excel_to_download_"+today+".xls']"
exp_y = "//*[#title='Some_excel_to_download_"+yesterday+".xls']"
exp_y2 = "//*[#title='Some_excel_to_download_"+y_yesterday+".xls']"
exp_y3 = "//*[#title='Some_excel_to_download_"+y2_yesterday+".xls']"
Basicaly, I want to download an xls file from the web site. I want to automate this process using crontab scheduler.
Problem is, that the file I want to download is uploaded at random dates and not event at random hour, but sometimes they forget to upload it for even 2 or 3 days (automation vs. manual job :) )
For now I am using this:
try:
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH,("%s" % exp)))).click()
nazwa = 'Some_excel_to_download_'+today+'.xls'
print(nazwa)
except TimeoutException:
print("Today's file not found. Trying: " + exp_y)
exp = "//*[#title='Some_excel_to_download_"+yesterday+".xls']"
driver.find_element_by_xpath(exp_y).click()
nazwa = 'Some_excel_to_download_'+yesterday+'.xls'
print(nazwa)
and this works fine, as long as a xls file is one day old...I want to know, how to add more "except" statements or (I guess it's better option) something like "if, elif, else" statement, but I am not sure how to do it... Maybe you could help me there, please ?
You use the if condition to check the length of the elements if the elements length count more than 0 then click on the element else go the next statement and check the same.
if len(driver.find_elements_by_xpath(exp))>0:
driver.find_element_by_xpath(exp).click()
elif len(driver.find_elements_by_xpath(exp_y))>0:
driver.find_element_by_xpath(exp_y).click()
elif len(driver.find_elements_by_xpath(exp_y2))>0:
driver.find_element_by_xpath(exp_y2).click()
elif len(driver.find_elements_by_xpath(exp_y3))>0:
driver.find_element_by_xpath(exp_y3).click()
else:
print("No such elements")
Or you can use nested try..except block removed the TimeoutException exception .
try:
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH,("%s" % exp)))).click()
nazwa = 'Some_excel_to_download_'+today+'.xls'
print(nazwa)
except:
try:
print("Today's file not found. Trying: " + exp_y)
exp = "//*[#title='Some_excel_to_download_"+yesterday+".xls']"
driver.find_element_by_xpath(exp_y).click()
nazwa = 'Some_excel_to_download_'+yesterday+'.xls'
print(nazwa)
except:
try:
print("Today's file not found. Trying: " + exp_y2)
exp = "//*[#title='Some_excel_to_download_" + y_yesterday + ".xls']"
driver.find_element_by_xpath(exp_y2).click()
nazwa = 'Some_excel_to_download_' + y_yesterday + '.xls'
print(nazwa)
except:
print("Today's file not found. Trying: " + exp_y3)
exp = "//*[#title='Some_excel_to_download_" + y2_yesterday + ".xls']"
driver.find_element_by_xpath(exp_y3).click()
nazwa = 'Some_excel_to_download_' + y2_yesterday + '.xls'
print(nazwa)

Try block gives output even when exception is raised by the last command (but not the first)

I use try/except to catch problems when reading a file line-by-line. The try block contains a series of manipulations, the last of which is usually the cause of the exception. Surprisingly, I noticed that all previous manipulations are executed within the try block even when an exception is raised. This is a problem when trying to turn the dictionary I created to a data frame, because the length of the lists is unequal.
This code creates the problem:
d = {'dates':[],'states':[], 'longitude':[], 'latitude':[], 'tweet_ids':[], 'user_ids':[], 'source':[]}
for file in f:
print("Processing file "+file)
t1 = file.split('/')[-1].split("_")
date = t1[0]
state_code = t1[1]
state = list(states_ref.loc[states_ref.code==state_code]['abbr'])[0]
collection = JsonCollection(file)
counter = 0
for tweet in collection.get_iterator():
counter += 1
try:
d['dates'].append(date)
d['states'].append(state)
t2 = tweet_parser.get_entity_field('geo', tweet)
if t2 == None:
d['longitude'].append(t2)
d['latitude'].append(t2)
else:
d['longitude'].append(t2['coordinates'][1])
d['latitude'].append(t2['coordinates'][0])
#note: the 3 lines bellow are the ones that can raise an exception
temp = tweet_parser.get_entity_field('source', tweet)
t5 = re.findall(r'>(.*?)<', temp)[0]
d['source'].append(t5)
except:
c += 1
print("Tweet {} in file {} had a problem and got skipped".format(counter, file))
print("This is a total of {} tweets I am missing from the {} archive I process.".format(c, sys.argv[1]))
next
tab = pd.DataFrame.from_dict(d)
I have fixed the problem by moving the manipulation that is prone to giving the error at the top, but I would like to better understand why try/except is behaving like this. Any ideas?
This code works:
d = {'dates':[],'states':[], 'longitude':[], 'latitude':[], 'tweet_ids':[], 'user_ids':[], 'source':[]}
for file in f:
print("Processing file "+file)
t1 = file.split('/')[-1].split("_")
date = t1[0]
state_code = t1[1]
state = list(states_ref.loc[states_ref.code==state_code]['abbr'])[0]
collection = JsonCollection(file)
counter = 0
for tweet in collection.get_iterator():
counter += 1
try:
#note: the 3 lines bellow are the ones that can raise an exception
temp = tweet_parser.get_entity_field('source', tweet)
t5 = re.findall(r'>(.*?)<', temp)[0]
d['source'].append(t5)
d['dates'].append(date)
d['states'].append(state)
t2 = tweet_parser.get_entity_field('geo', tweet)
if t2 == None:
d['longitude'].append(t2)
d['latitude'].append(t2)
else:
d['longitude'].append(t2['coordinates'][1])
d['latitude'].append(t2['coordinates'][0])
except:
c += 1
print("Tweet {} in file {} had a problem and got skipped".format(counter, file))
print("This is a total of {} tweets I am missing from the {} archive I process.".format(c, sys.argv[1]))
next
tab = pd.DataFrame.from_dict(d)
You could always use a temporal object to hold the output of your functions before appending to the target object. That way if something fails, it will raise an exception before putting data into the target object.
try:
#Put all data into a temporal Dictionary
#Can raise an exception here
temp = tweet_parser.get_entity_field('source', tweet)
t2 = tweet_parser.get_entity_field('geo', tweet)
tempDictionary = {
"source" : re.findall(r'>(.*?)<', temp)[0],
"latitude" : None if (t2 is None) else t2['coordinates'][1],
"longitude" : None if (t2 is None) else t2['coordinates'][0]
}
#Append data from temporal Dictionary
d['source'].append(tempDictionary['source'])
d['latitude'].append(tempDictionary['latitude'])
d['longitude'].append(tempDictionary['longitude'])
d['dates'].append(date)
d['states'].append(state)
except:
c += 1
print("Tweet {} in file {} had a problem and got skipped".format(counter, file))
print("This is a total of {} tweets I am missing from the {} archive I process.".format(c, sys.argv[1]))

What can I do for my program not to throw a KeyError for a Header not existing in a .fits file?

I am making a program that searches the computer for .fts and .fits files in which it opens the file and retrieves info that corresponds to a specific keyword in the header and renames the file to that keyword.
I am having a problem where i keep receiving a KeyError becasue a header keyword I am searching for is not found in the file. Is there a way around this? I want to be able to search various keywords and do something even if that key word does not exist in the file.
Here is code:
from astropy.io import fits
import os
for i in os.listdir(os.getcwd()):
if i.endswith(".fits") or i.endswith(".fts"):
hdulist = fits.open(i)
DATEOBS_header = hdulist[0].header['DATE-OBS']
EXPTIME_header = int(round(hdulist[0].header['EXPTIME']))
CCDTEMP_header = int(round(hdulist[0].header['CCD-TEMP']))
XBINNING_header = hdulist[0].header['XBINNING']
FILTER_header = hdulist[0].header['FILTER']
IMAGETYP_header = hdulist[0].header['IMAGETYP']
OBJECT_header = hdulist[0].header['OBJECT']
DATEandTIME = DATEOBS_header[0:]
YEAR = DATEandTIME[0:4]
MONTH = DATEandTIME[5:7]
DAY = DATEandTIME[8:10]
#TIME = DATEOBS_header[11:]
HOUR = DATEandTIME[11:13]
MINUTE = DATEandTIME[14:16]
SECONDS = DATEandTIME[17:]
DATE = str(YEAR) + str(MONTH) + str(DAY) + 'at' + str(HOUR) + str(MINUTE) + str(SECONDS)
if IMAGETYP_header == 'Light Frame':
newname = str(OBJECT_header) + '_' + str(DATE) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
if IMAGETYP_header == 'Dark Frame':
newname = 'Dark_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime' + '.fits'
if IMAGETYP_header == 'Flat Field':
newname = 'Flat_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
prevname = i
os.rename(prevname, newname)
hdulist.close()
continue
else:
continue
This is the Error I get:
Traceback (most recent call last):
File "glo1.py", line 9, in <module>
DATEOBS_header = hdulist[0].header['DATE-OBS']
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 151, in __getitem__
card = self._cards[self._cardindex(key)]
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 1723, in _cardindex
raise KeyError("Keyword %r not found." % keyword)
KeyError: "Keyword 'DATE-OBS' not found."
To prevent these kinds of exceptions from stopping your program, you can either catch them, like this:
try:
DATEOBS_header = hdulist[0].header['DATE-OBS']
except KeyError:
DATEOBS_header = None
Or, use the .get() method of dictionaries, which checks if a key exists and if it doesn't returns a default value, instead of raising an exception. The default value returned is None.
If you do this, you will also need to set some sensible defaults, or catch those cases where you are casting the values (since you cannot cast None).
Finally, whenever you are reading from files - you should always assume the data is malformed/junk and do a bit of defensive programming. In your code, you are assuming that the values returned for CCDTEMP is a number, but what if the file is corrupted or has a blank? Your application doesn't handle this case.
Here is some code that attempts to catch as many errors as possible:
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
XBINNING_header = hdulist[0].header.get('XBINNING')
FILTER_header = hdulist[0].header.get('FILTER')
IMAGETYP_header = hdulist[0].header.get('IMAGETYP')
OBJECT_header = hdulist[0].header.get('OBJECT')
# For these two, you need to either set a default
# Here I am setting the default to 0, ------------v
EXPTIME_header = int(round(hdulist[0].header.get('EXPTIME', 0)))
# Or you need to check for a value :
ccdtemp_value = hdulist[0].header.get('CCD-TEMP')
try:
ccdtemp_value = int(round(ccdtemp_value))
except ValueError:
# This means, the value was either None (header does not exist)
# or it was something that can't be converted to a number
# since it cannot be converted to a number, we do not know
# if the value is None or something like an empty string,
# so we explicitly set the value to None
ccdtemp_value = None
CCDTEMP_header = ccdtemp_value
Assuming hdulist[0].header gives you a dict instance, you can do something like
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
Which would return a None if the key 'DATE-OBS' does not exist.
See https://docs.python.org/2/library/stdtypes.html#dict.get for more details.

Skyscanner API CSV file

I am new to python and I am trying to run this code,which I found on github ,but it does not work, is something wrong with the code?Or is it my fault? I am always getting the
"no data found"
message.
skyscanner.py :
#!/usr/bin/python
"""The script obtains prices and flight information for a given
input (departure, arrival airports and date), outputs this
data to the console and writes it to a csv file."""
__author__ = "Ingvaras Merkys"
import json
import urllib2
import re
import sys
import time
# Global vars:
AUTOSUGGEST_URL = "http://www.skyscanner.net/dataservices/geo/v1.0/autosuggest/uk/en/"
# e. g. http://www.skyscanner.net/dataservices/geo/v1.0/autosuggest/uk/en/edinb
SKYSCANNER_URL = "http://www.skyscanner.net/flights/"
# e. g. http://www.skyscanner.net/flights/vno/edi/130419
ROUTEDATA_URL = "http://www.skyscanner.net/dataservices/routedate/v2.0/"
# e. g. http://www.skyscanner.net/dataservices/routedate/v2.0/a00765d2-7a39-404b-86c0-e8d79cc5f7e3
SUGGESTIONS_URL = "http://www.skyscanner.net/db.ashx?ucy=UK&lid=en&ccy=GBP"
# e. g. http://www.skyscanner.net/db.ashx?ucy=UK&lid=en&ccy=GBP&fp=KAUN&tp=EDIN&dd=20130410
def main(argv):
input_from = argv[0].replace(" ", "%20").replace("\"", "")
input_to = argv[1].replace(" ", "%20").replace("\"", "")
date = argv[2].replace("/", "")
place_id_from, place_id_to, name_from, name_to = get_codes(input_from, input_to)
# testjuly = map (lambda x: len(x) == 1 and '13070'+x or '1307'+x, [ str(i+1) for i in range(31) ])
# for date in testjuly:
session_key = get_session_key(place_id_from, place_id_to, date)
for attempt in range(3):
# if script is run repeatedly sometimes an empty html is returned
try:
response = urllib2.urlopen(ROUTEDATA_URL + session_key)
html = response.read()
data = json.loads(html)
except ValueError:
f = open("error.log", "a")
f.write(ROUTEDATA_URL + session_key + "\n")
f.write("Returned:\n" + html + "\n")
time.sleep(1)
else:
break
else:
sys.exit(1)
query = data['Query']
if data['Stats']['OutboundLegStats']['TotalCount'] == 0:
print "No flights found from", name_from, "to", name_to
return 0
#show_suggestions(query['OriginPlace'], query['DestinationPlace'], date)
#sys.exit(2)
stations = data['Stations']
quotes = data['Quotes']
carriers = data['Carriers']
cheapest_price = data['Stats']['ItineraryStats']['Total']['CheapestPrice']
print "Results for flight from", name_from, "to", name_to
print "Outbound date:", re.split('T', query['OutboundDate'])[0]
print "Cheapest Journey:", cheapest_price, "RMB"
return cheapest_price
# f = open(place_id_from + '-' + place_id_to + '-' + date + '.csv','w')
# for leg in data['OutboundItineraryLegs']:
# leg_price = get_leg_price(leg['PricingOptions'], quotes)
# depart_time = leg['DepartureDateTime'].replace("T", " ")
# arrive_time = leg['ArrivalDateTime'].replace("T", " ")
# duration = leg['Duration']
# carrier_names = get_carrier_names(leg['MarketingCarrierIds'], carriers)[1]
# print "\n\tPrice:", leg_price, "GBP"
# print "\tDeparting:", depart_time
# print "\tArriving:", arrive_time
# print "\tDuration:", duration/60, "h", duration%60, "min"
# print "\tCarriers:", carrier_names
# print "\t# of stops: ", leg['StopsCount']
# stop_ids = leg.get('StopIds', [])
# stop_ids_string = ", ".join([ get_station_name(stop_id, stations) for stop_id in stop_ids ])
# print "\t\t", stop_ids_string
# row = str(leg_price) + "\t" + depart_time + "\t" + arrive_time + "\t" + str(duration) + "\t" + carrier_names + "\t" + stop_ids_string
# f.write(row + "\n")
# Functions
def get_codes(input_from, input_to):
"""Returns place id codes and names, e. g. ("EDI", "KUN", "Edinburgh", "Kaunas")"""
try:
i = 0
autosuggest_json_from = json.load(urllib2.urlopen(AUTOSUGGEST_URL + input_from))
if len(autosuggest_json_from[0]['PlaceId']) == 4:
# for cases where the first result is abstract (e. g. Glasgow (Any))
i = 1
place_id_from = autosuggest_json_from[i]['PlaceId']
name_from = autosuggest_json_from[i]['PlaceName']
j = 0
autosuggest_json_to = json.load(urllib2.urlopen(AUTOSUGGEST_URL + input_to))
if len(autosuggest_json_to[0]['PlaceId']) == 4:
j = 1
place_id_to = autosuggest_json_to[j]['PlaceId']
name_to = autosuggest_json_to[j]['PlaceName']
except IndexError:
print "No code found for:"
print input_from, "AND/OR", input_to
sys.exit(3)
return (place_id_from, place_id_to, name_from, name_to)
def get_session_key(place_id_from, place_id_to, date):
"""Returns a session key for a given query, on failure exits
NB. distant or past dates cause failures"""
response = urllib2.urlopen(SKYSCANNER_URL + place_id_from + "/" + place_id_to + "/" + date)
html = response.read()
regex = ur'"SessionKey":"(.+?)"'
# e. g. "SessionKey":"a00765d2-7a39-404b-86c0-e8d79cc5f7e3"
try:
session_key = re.findall(regex, html)[0]
except IndexError:
print "No data found for this date"
sys.exit(4)
return session_key
def show_suggestions(from_id, to_id, date):
"""Prints alternative departure airports"""
suggest_places_string = ""
suggestions_json = json.load(urllib2.urlopen(SUGGESTIONS_URL + "&fp=" + from_id + "&tp=" + to_id + "&dd=20" + date))
try:
suggest_places = suggestions_json['rs']
for place in suggest_places:
if place['fpid'] != from_id:
suggest_places_string += place['fan'] + ", "
if suggest_places_string[:-2] != "":
print "Try airports: ", suggest_places_string[:-2]
except (KeyError, IndexError):
print "Suggestions unavailable"
def get_station_name(station_id, stations):
"""Returns the name of the (intermediate) station,
e. g. "London Heathrow" """
for station in stations:
if station['Id'] == station_id:
return station['Name']
return ""
def get_leg_price(pricing, quotes):
"""Returns lowest leg price"""
prices = []
for price in pricing:
prices.append(get_quote_price(price['QuoteIds'], quotes))
return min(prices)
def get_quote_price(quote_ids, quotes):
"""Finds quotes by quote id and returns their price sum"""
price = 0;
for quote_id in quote_ids:
for quote in quotes:
if quote['Id'] == quote_id:
price += quote['Price']
return price
def get_carrier_names(carrier_ids, carriers):
"""Returns a tuple (list, string) with carrier names
e.g. (["airBaltic", "KLM"], "airBaltic, KLM")"""
carrier_names = []
carrier_names_string = ""
for carrier_id in carrier_ids:
carrierName = get_carrier_name(carrier_id, carriers)
carrier_names.append(carrierName)
carrier_names_string += carrierName + ", "
return (carrier_names, carrier_names_string[:-2])
def get_carrier_name(carrier_id, carriers):
"""Returns carrier name by id"""
for carrier in carriers:
if carrier['Id'] == carrier_id:
return carrier['Name']
return ""
if __name__ == "__main__":
if len(sys.argv) == 4:
main(sys.argv[1:])
else:
print "Enter arguments in this way:\n"
print "python skyscanner.py {departure airport} {arrival airport} {departure date (yy/mm/dd)}\n\n"
print "e. g. python skyscanner.py \"glasgow prestwick\" kaunas 13/07/21\n"
sys.exit()
These endpoints are not supported as external APIs, they are used by the site itself. They can/do change without notice and some require a level of "state" to operate.
However, we do have an API that would allow you access to the same auto-suggest / flight data that the site is driven from. More details can be found at http://business.skyscanner.net

Categories