Skip to content

Commit db0d295

Browse files
committed
Updated files to follow PEP-8 style guide
1 parent 69d1f1c commit db0d295

File tree

3 files changed

+88
-84
lines changed

3 files changed

+88
-84
lines changed

apod/service.py

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,144 +11,148 @@
1111
from datetime import datetime
1212
from flask import request, jsonify, render_template, Flask
1313
from flask_cors import CORS, cross_origin
14-
from apod.utility import parse_apod, get_concepts
14+
from apod.utility import parse_apod, get_concepts
1515
import logging
1616

1717
app = Flask(__name__)
1818
CORS(app)
1919

2020
LOG = logging.getLogger(__name__)
2121
logging.basicConfig(level=logging.DEBUG)
22-
#LOG.setLevel(logging.DEBUG)
22+
# LOG.setLevel(logging.DEBUG)
2323

2424
# this should reflect both this service and the backing
2525
# assorted libraries
26-
SERVICE_VERSION='v1'
27-
APOD_METHOD_NAME='apod'
26+
SERVICE_VERSION = 'v1'
27+
APOD_METHOD_NAME = 'apod'
2828
ALLOWED_APOD_FIELDS = ['concept_tags', 'date', 'hd']
2929
ALCHEMY_API_KEY = None
3030

31-
3231
try:
3332
with open('alchemy_api.key', 'r') as f:
3433
ALCHEMY_API_KEY = f.read()
3534
except:
36-
LOG.info ("WARNING: NO alchemy_api.key found, concept_tagging is NOT supported")
35+
LOG.info("WARNING: NO alchemy_api.key found, concept_tagging is NOT supported")
3736

38-
def _abort(code, msg, usage=True):
3937

38+
def _abort(code, msg, usage=True):
4039
if (usage):
41-
msg += " "+_usage()+"'"
40+
msg += " " + _usage() + "'"
4241

4342
response = jsonify(service_version=SERVICE_VERSION, msg=msg, code=code)
4443
response.status_code = code
4544
LOG.debug(str(response))
46-
45+
4746
return response
4847

48+
4949
def _usage(joinstr="', '", prestr="'"):
50-
return "Allowed request fields for "+APOD_METHOD_NAME+" method are "+prestr+joinstr.join(ALLOWED_APOD_FIELDS)
50+
return "Allowed request fields for " + APOD_METHOD_NAME + " method are " + prestr + joinstr.join(
51+
ALLOWED_APOD_FIELDS)
5152

52-
def _validate (data):
53+
54+
def _validate(data):
5355
LOG.debug("_validate(data) called")
5456
for key in data:
5557
if key not in ALLOWED_APOD_FIELDS:
5658
return False
5759
return True
5860

59-
def _validate_date (dt):
60-
61+
62+
def _validate_date(dt):
6163
LOG.debug("_validate_date(dt) called")
6264
today = datetime.today()
63-
begin = datetime (1995, 6, 16) # first APOD image date
64-
65+
begin = datetime(1995, 6, 16) # first APOD image date
66+
6567
# validate input
6668
if (dt > today) or (dt < begin):
67-
6869
today_str = today.strftime('%b %d, %Y')
6970
begin_str = begin.strftime('%b %d, %Y')
70-
71+
7172
raise ValueError('Date must be between %s and %s.' % (begin_str, today_str))
72-
73+
74+
7375
def _apod_handler(dt, use_concept_tags=False, use_default_today_date=False):
7476
"""Accepts a parameter dictionary. Returns the response object to be
7577
served through the API."""
7678
try:
7779
page_props = parse_apod(dt, use_default_today_date)
7880
LOG.debug("managed to get apod page characteristics")
79-
81+
8082
if use_concept_tags:
8183
if ALCHEMY_API_KEY == None:
8284
page_props['concepts'] = "concept_tags functionality turned off in current service"
8385
else:
8486
page_props['concepts'] = get_concepts(request, page_props['explanation'], ALCHEMY_API_KEY)
85-
86-
return page_props
87-
87+
88+
return page_props
89+
8890
except Exception as e:
89-
90-
LOG.error("Internal Service Error :"+str(type(e))+" msg:"+str(e))
91+
92+
LOG.error("Internal Service Error :" + str(type(e)) + " msg:" + str(e))
9193
# return code 500 here
9294
return _abort(500, "Internal Service Error", usage=False)
93-
95+
96+
9497
#
9598
# Endpoints
9699
#
97100

98101
@app.route('/')
99102
def home():
100103
return render_template('home.html', version=SERVICE_VERSION, \
101-
service_url=request.host, \
102-
methodname=APOD_METHOD_NAME, \
103-
usage=_usage(joinstr='", "', prestr='"')+'"')
104+
service_url=request.host, \
105+
methodname=APOD_METHOD_NAME, \
106+
usage=_usage(joinstr='", "', prestr='"') + '"')
104107

105-
@app.route('/'+SERVICE_VERSION+'/'+APOD_METHOD_NAME+'/', methods=['GET'])
106-
def apod():
107108

109+
@app.route('/' + SERVICE_VERSION + '/' + APOD_METHOD_NAME + '/', methods=['GET'])
110+
def apod():
108111
LOG.info("apod path called")
109112
try:
110113

111114
# application/json GET method
112115
args = request.args
113116

114117
if not _validate(args):
115-
return _abort (400, "Bad Request incorrect field passed.")
116-
118+
return _abort(400, "Bad Request incorrect field passed.")
119+
117120
# get the date param
118121
use_default_today_date = False
119122
date = args.get('date')
120123
if not date:
121124
# fall back to using today's date IF they didn't specify a date
122125
date = datetime.strftime(datetime.today(), '%Y-%m-%d')
123126
use_default_today_date = True
124-
127+
125128
# grab the concept_tags param
126129
use_concept_tags = args.get('concept_tags', False)
127-
130+
128131
# validate input date
129132
dt = datetime.strptime(date, '%Y-%m-%d')
130133
_validate_date(dt)
131-
134+
132135
# get data
133136
data = _apod_handler(dt, use_concept_tags, use_default_today_date)
134137
data['date'] = date
135138
data['service_version'] = SERVICE_VERSION
136-
139+
137140
# return info as JSON
138141
return jsonify(data)
139142

140143
except ValueError as ve:
141144
return _abort(400, str(ve), False)
142-
145+
143146
except Exception as ex:
144147

145148
etype = type(ex)
146149
if etype == ValueError or "BadRequest" in str(etype):
147-
return _abort(400, str(ex)+".")
150+
return _abort(400, str(ex) + ".")
148151
else:
149-
LOG.error("Service Exception. Msg: "+str(type(ex)))
152+
LOG.error("Service Exception. Msg: " + str(type(ex)))
150153
return _abort(500, "Internal Service Error", usage=False)
151154

155+
152156
@app.errorhandler(404)
153157
def page_not_found(e):
154158
"""Return a custom 404 error."""
@@ -163,4 +167,3 @@ def application_error(e):
163167

164168
if __name__ == '__main__':
165169
app.run()
166-

apod/utility.py

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414

1515
LOG = logging.getLogger(__name__)
1616
logging.basicConfig(level=logging.WARN)
17-
#LOG.setLevel(logging.DEBUG)
17+
# LOG.setLevel(logging.DEBUG)
1818

1919
# location of backing APOD service
2020
BASE = 'https://apod.nasa.gov/apod/'
2121

22+
2223
def _get_apod_chars(dt):
23-
2424
media_type = 'image'
2525
date_str = dt.strftime('%y%m%d')
2626
apod_url = '%sap%s.html' % (BASE, date_str)
27-
LOG.debug("OPENING URL:"+apod_url)
27+
LOG.debug("OPENING URL:" + apod_url)
2828
soup = BeautifulSoup(requests.get(apod_url).text, "html.parser")
2929
LOG.debug("getting the data url")
3030
data = None
@@ -33,7 +33,7 @@ def _get_apod_chars(dt):
3333
# it is an image, so get both the low- and high-resolution data
3434
data = BASE + soup.img['src']
3535
hd_data = data
36-
36+
3737
LOG.debug("getting the link for hd_data")
3838
for link in soup.find_all('a', href=True):
3939
if link['href'] and link['href'].startswith("image"):
@@ -43,23 +43,23 @@ def _get_apod_chars(dt):
4343
# its a video
4444
media_type = 'video'
4545
data = soup.iframe['src']
46-
47-
46+
4847
props = {}
49-
50-
props['explanation'] = _explanation(soup)
51-
props['title'] = _title(soup)
48+
49+
props['explanation'] = _explanation(soup)
50+
props['title'] = _title(soup)
5251
copyright = _copyright(soup)
5352
if copyright:
5453
props['copyright'] = copyright
5554
props['media_type'] = media_type
5655
props['url'] = data
57-
56+
5857
if hd_data:
5958
props['hdurl'] = hd_data
60-
59+
6160
return props
6261

62+
6363
def _title(soup):
6464
"""Accepts a BeautifulSoup object for the APOD HTML page and returns the
6565
APOD image title. Highly idiosyncratic with adaptations for different
@@ -77,6 +77,7 @@ def _title(soup):
7777
else:
7878
raise ValueError('Unsupported schema for given date.')
7979

80+
8081
def _copyright(soup):
8182
"""Accepts a BeautifulSoup object for the APOD HTML page and returns the
8283
APOD image copyright. Highly idiosyncratic with adaptations for different
@@ -87,28 +88,27 @@ def _copyright(soup):
8788

8889
# There's no uniform handling of copyright (sigh). Well, we just have to
8990
# try every stinking text block we find...
90-
91+
9192
copyright = None
9293
use_next = False
9394
for element in soup.findAll('a', text=True):
94-
#LOG.debug("TEXT: "+element.text)
95-
95+
# LOG.debug("TEXT: "+element.text)
96+
9697
if use_next:
9798
copyright = element.text.strip(' ')
9899
break
99-
100+
100101
if "Copyright" in element.text:
101-
LOG.debug("Found Copyright text:"+str(element.text))
102+
LOG.debug("Found Copyright text:" + str(element.text))
102103
use_next = True
103-
104-
104+
105105
if not copyright:
106-
107-
for element in soup.findAll(['b','a'], text=True):
108-
#LOG.debug("TEXT: "+element.text)
106+
107+
for element in soup.findAll(['b', 'a'], text=True):
108+
# LOG.debug("TEXT: "+element.text)
109109
# search text for explicit match
110110
if "Copyright" in element.text:
111-
LOG.debug("Found Copyright text:"+str(element.text))
111+
LOG.debug("Found Copyright text:" + str(element.text))
112112
# pull the copyright from the link text
113113
# which follows
114114
sibling = element.next_sibling
@@ -119,11 +119,10 @@ def _copyright(soup):
119119
except Exception:
120120
pass
121121
sibling = sibling.next_sibling
122-
122+
123123
if stuff:
124124
copyright = stuff.strip(' ')
125-
126-
125+
127126
return copyright
128127

129128
except Exception as ex:
@@ -133,6 +132,7 @@ def _copyright(soup):
133132
# NO stated copyright, so we return None
134133
return None
135134

135+
136136
def _explanation(soup):
137137
"""Accepts a BeautifulSoup object for the APOD HTML page and returns the
138138
APOD image explanation. Highly idiosyncratic."""
@@ -153,22 +153,22 @@ def _explanation(soup):
153153
return s
154154

155155

156-
def parse_apod (dt, use_default_today_date=False):
156+
def parse_apod(dt, use_default_today_date=False):
157157
"""Accepts a date in '%Y-%m-%d' format. Returns the URL of the APOD image
158158
of that day, noting that """
159159

160-
LOG.debug("apod chars called date:"+str(dt))
161-
160+
LOG.debug("apod chars called date:" + str(dt))
161+
162162
try:
163163
return _get_apod_chars(dt)
164-
164+
165165
except Exception as ex:
166-
166+
167167
# handle edge case where the service local time
168168
# miss-matches with 'todays date' of the underlying APOD
169169
# service (can happen because they are deployed in different
170170
# timezones). Use the fallback of prior day's date
171-
171+
172172
if use_default_today_date:
173173
# try to get the day before
174174
dt = dt - timedelta(days=1)
@@ -177,25 +177,25 @@ def parse_apod (dt, use_default_today_date=False):
177177
# pass exception up the call stack
178178
LOG.error(str(ex))
179179
raise Exception(ex)
180-
181-
180+
181+
182182
def get_concepts(request, text, apikey):
183183
"""Returns the concepts associated with the text, interleaved with integer
184184
keys indicating the index."""
185185
cbase = 'http://access.alchemyapi.com/calls/text/TextGetRankedConcepts'
186-
186+
187187
params = dict(
188188
outputMode='json',
189189
apikey=apikey,
190190
text=text
191191
)
192192

193193
try:
194-
194+
195195
LOG.debug("Getting response")
196196
response = json.loads(request.get(cbase, fields=params))
197197
clist = [concept['text'] for concept in response['concepts']]
198198
return {k: v for k, v in zip(range(len(clist)), clist)}
199-
199+
200200
except Exception as ex:
201201
raise ValueError(ex)

0 commit comments

Comments
 (0)