Skip to content

Commit

Permalink
Merge branch 'master' into private/aaronrobson/404-on-favicon-excepti…
Browse files Browse the repository at this point in the history
…on-raised
  • Loading branch information
JustinGOSSES authored Nov 12, 2020
2 parents 1499f29 + 05a7d14 commit f6c56f8
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 83 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ lib/
.DS_Store
.idea/
apod/__pycache__/
venv/
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3-alpine

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["application.py"]
188 changes: 122 additions & 66 deletions README.md

Large diffs are not rendered by default.

File renamed without changes.
18 changes: 16 additions & 2 deletions utility.py → apod/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,21 @@ def _get_apod_chars(dt, thumbs):
date_str = dt.strftime('%y%m%d')
apod_url = '%sap%s.html' % (BASE, date_str)
LOG.debug('OPENING URL:' + apod_url)
soup = BeautifulSoup(requests.get(apod_url).text, 'html.parser')
res = requests.get(apod_url)

if res.status_code == 404:
return None
# LOG.error(f'No APOD entry for URL: {apod_url}')
# default_obj_path = 'static/default_apod_object.json'
# LOG.debug(f'Loading default APOD response from {default_obj_path}')
# with open(default_obj_path, 'r') as f:
# default_obj_props = json.load(f)

# default_obj_props['date'] = dt.strftime('%Y-%m-%d')

# return default_obj_props

soup = BeautifulSoup(res.text, 'html.parser')
LOG.debug('getting the data url')
hd_data = None
if soup.img:
Expand Down Expand Up @@ -88,7 +102,7 @@ def _get_apod_chars(dt, thumbs):
props['media_type'] = media_type
if data:
props['url'] = _get_last_url(data)
props['date'] = dt.isoformat()
props['date'] = dt.strftime('%Y-%m-%d')

if hd_data:
props['hdurl'] = _get_last_url(hd_data)
Expand Down
64 changes: 64 additions & 0 deletions apod_parser/apod_object_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import requests
import json
import os
from PIL import Image

def get_data(api_key):
raw_response = requests.get(f'https://api.nasa.gov/planetary/apod?api_key={api_key}').text
response = json.loads(raw_response)
return response


def get_date(response):
date = response['date']
return date


def get_explaination(response):
explaination = response['explanation']
return explaination


def get_hdurl(response):
hdurl = response['hdurl']
return hdurl


def get_media_type(response):
media_type = response['media_type']
return media_type

def get_service_version(response):
service_version = response['service_version']
return service_version


def get_title(response):
service_version = response['title']
return service_version

def get_url(response):
url = response['url']
return url

def download_image(url, date):
if os.path.isfile(f'{date}.png') == False:
raw_image = requests.get(url).content
with open(f'{date}.jpg', 'wb') as file:
file.write(raw_image)

else:
return FileExistsError


def convert_image(image_path):
path_to_image = os.path.normpath(image_path)

basename = os.path.basename(path_to_image)

filename_no_extension = basename.split(".")[0]

base_directory = os.path.dirname(path_to_image)

image = Image.open(path_to_image)
image.save(f"{base_directory}/{filename_no_extension}.png")
66 changes: 66 additions & 0 deletions apod_parser/apod_parser_readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# apod_object_parser

get a Nasa api key by clicking <a href="https://api.nasa.gov/#signUp">here</a>.

## How to use
1. import the file
```python
import apod_object_parser
```
2. Now call the `get_data` function and pass the `nasa api key` as the argument. Note api_key is a string. The response returned will be a Dictionary. Now you can parse the dictionary too

```python
response = apod_object_parser.get_data(##Pass In Your API key here)
```
### get_date

the `get_date` function takes the dictionary we got above and returns the date.

```python
date = apod_object_parser.get_date(response)
```
### get_explaination
the `get_explaination` function takes the dictionary we got above and returns the explaintion.

```python
date = apod_object_parser.get_explaination(response)
```
### get_hdurl
the `get_hdurl` function takes the dictionary we got above and returns the High Definition url of the image.

```python
date = apod_object_parser.get_hdurl(response)
```
### get_title
the `get_title` function takes the dictionary we got above and returns the title of the image.

```python
date = apod_object_parser.get_title(response)
```
### get_url
the `get_url` function takes the dictionary we got above and returns the Standard definition url of the image.

```python
date = apod_object_parser.get_hdurl(response)
```
### get_media_type
the `get_media_type` function takes the dictionary we got above and returns the media type the file (might be a video of a image).

```python
date = apod_object_parser.get_hdurl(response)
```

## Other functions
there are also other functions that might help you in situations

### download_image
the `download_image` finction takes the url (hdurl or url) and the date from the function `get_date` and downloads the image in the current directory and with the file name of the date. the image downloaded is in the .jpg format
```python
apod_object_parser.download_image(url, date)
```

### convert_image
sometimes the image we downloaded above might not be in the right format (.jpg) so you may call `convert_image` function to convert the image into .png. takes the `image_path` parameter which is the filepath.
```python
apod_object_parser.convert_image(image_path)
```
48 changes: 35 additions & 13 deletions application.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
A micro-service passing back enhanced information from Astronomy
Picture of the Day (APOD).
Adapted from code in https://github.com/nasa/planetary-api
Dec 1, 2015 (written by Dan Hammer)
Expand All @@ -18,10 +18,10 @@
sys.path.insert(1, ".")

from datetime import datetime, date
from random import sample
from flask import request, jsonify, render_template, Flask
from random import shuffle
from flask import request, jsonify, render_template, Flask, current_app
from flask_cors import CORS
from utility import parse_apod, get_concepts
from apod.utility import parse_apod, get_concepts
import logging

#### added by justin for EB
Expand All @@ -31,9 +31,10 @@
CORS(application)

LOG = logging.getLogger(__name__)
# logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.DEBUG)

# this should reflect both this service and the backing
# this should reflect both this service and the backing
# assorted libraries
SERVICE_VERSION = 'v1'
APOD_METHOD_NAME = 'apod'
Expand Down Expand Up @@ -91,7 +92,10 @@ def _apod_handler(dt, use_concept_tags=False, use_default_today_date=False, thum
served through the API.
"""
try:

page_props = parse_apod(dt, use_default_today_date, thumbs)
if not page_props:
return None
LOG.debug('managed to get apod page characteristics')

if use_concept_tags:
Expand Down Expand Up @@ -131,6 +135,11 @@ def _get_json_for_date(input_date, use_concept_tags, thumbs):

# get data
data = _apod_handler(dt, use_concept_tags, use_default_today_date, thumbs)

# Handle case where no data is available
if not data:
return _abort(code=404, msg=f"No data available for date: {input_date}", usage=False)

data['service_version'] = SERVICE_VERSION

# return info as JSON
Expand All @@ -145,22 +154,27 @@ def _get_json_for_random_dates(count, use_concept_tags, thumbs):
:param use_concept_tags:
:return:
"""

if count > 100 or count <= 0:
raise ValueError('Count must be positive and cannot exceed 100')

begin_ordinal = datetime(1995, 6, 16).toordinal()
today_ordinal = datetime.today().toordinal()

date_range = range(begin_ordinal, today_ordinal + 1)
random_date_ordinals = sample(date_range, count)
random_date_ordinals = list(range(begin_ordinal, today_ordinal + 1))
shuffle(random_date_ordinals)

all_data = []
for date_ordinal in random_date_ordinals:
dt = date.fromordinal(date_ordinal)
data = _apod_handler(dt, use_concept_tags, date_ordinal == today_ordinal, thumbs)

# Handle case where no data is available
if not data:
continue

data['service_version'] = SERVICE_VERSION
all_data.append(data)
if len(all_data) >= count:
break

return jsonify(all_data)

Expand Down Expand Up @@ -199,7 +213,14 @@ def _get_json_for_date_range(start_date, end_date, use_concept_tags, thumbs):
while start_ordinal <= end_ordinal:
# get data
dt = date.fromordinal(start_ordinal)

data = _apod_handler(dt, use_concept_tags, start_ordinal == today_ordinal, thumbs)

# Handle case where no data is available
if not data:
start_ordinal += 1
continue

data['service_version'] = SERVICE_VERSION

if data['date'] == dt.isoformat():
Expand All @@ -223,6 +244,10 @@ def home():
methodname=APOD_METHOD_NAME,
usage=_usage(joinstr='", "', prestr='"') + '"')

@application.route('/static/<asset_path>')
def serve_static(asset_path):
return current_app.send_static_file(asset_path)


@application.route('/' + SERVICE_VERSION + '/' + APOD_METHOD_NAME + '/', methods=['GET'])
def apod():
Expand Down Expand Up @@ -286,7 +311,4 @@ def application_error(e):


if __name__ == '__main__':
application.run()
# httpd = make_server('', 8000, application)
# print("Serving on port 8000...")
# httpd.serve_forever()
application.run('0.0.0.0', port=5000)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ nose==1.3.7
setupext-janitor==1.0.0
bs4==0.0.1
mock>=3.0.0
Pillow==7.1.2
2 changes: 1 addition & 1 deletion run_coverage.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Need to sort out why this is the only way nosetests seem
# to work right..
nosetests -v tests/apod/*
nosetests -v tests/*
Binary file added static/default_apod_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions static/default_apod_object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"explanation": "This is a fallback image used in the case where there is a missing/corrupted asset on apod.nasa.gov. Image source: https://en.wikipedia.org/wiki/File:Black_Hole_in_the_universe.jpg",
"hdurl": "https://api.nasa.gov/planetary/apod/static/default_apod_image.jpg",
"media_type": "image",
"title": "Default Image",
"url": "https://api.nasa.gov/planetary/apod/static/default_apod_image.jpg"
}
2 changes: 1 addition & 1 deletion tests/apod/test_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class TestApod(unittest.TestCase):
'newer page, Reprocessing & copyright' :
{
"datetime": datetime(2017, 2, 8),
"copyright": "Jesús M.Vargas & Maritxu Poyal",
"copyright": "Jes�s M.Vargas & Maritxu Poyal",
"date": "2017-02-08",
"explanation": "The bright clusters and nebulae of planet Earth's night sky are often named for flowers or insects. Though its wingspan covers over 3 light-years, NGC 6302 is no exception. With an estimated surface temperature of about 250,000 degrees C, the dying central star of this particular planetary nebula has become exceptionally hot, shining brightly in ultraviolet light but hidden from direct view by a dense torus of dust. This sharp close-up of the dying star's nebula was recorded by the Hubble Space Telescope and is presented here in reprocessed colors. Cutting across a bright cavity of ionized gas, the dust torus surrounding the central star is near the center of this view, almost edge-on to the line-of-sight. Molecular hydrogen has been detected in the hot star's dusty cosmic shroud. NGC 6302 lies about 4,000 light-years away in the arachnologically correct constellation of the Scorpion (Scorpius). Follow APOD on: Facebook, Google Plus, Instagram, or Twitter",
"hdurl": "https://apod.nasa.gov/apod/image/1702/Butterfly_HubbleVargas_5075.jpg",
Expand Down

0 comments on commit f6c56f8

Please sign in to comment.