diff --git a/APOD Using NASA API.ipynb b/APOD Using NASA API.ipynb new file mode 100644 index 0000000..41d2ad0 --- /dev/null +++ b/APOD Using NASA API.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get the Astronomy Picture of the Day\n", + "## Using NASA's API\n", + "\n", + "https://api.nasa.gov/" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "import requests\n", + "import json\n", + "from datetime import date\n", + "from random import randrange" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def construct_url(base, params):\n", + " \"\"\"Construct an APOD API URL\"\"\"\n", + " url = base\n", + " for i, (param, val) in enumerate(params):\n", + " if i == 0:\n", + " url += \"?{0}={1}\".format(param, val)\n", + " else:\n", + " url += \"&{0}={1}\".format(param, val)\n", + " return url" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def get_random_apod():\n", + " sleep_t = 10\n", + " this_year = date.today().year\n", + " base_url = \"https://api.nasa.gov/planetary/apod\"\n", + "\n", + " while True:\n", + " url_params = [(\"api_key\", \"DEMO_KEY\"), (\"hd\", True)]\n", + " \n", + " year = randrange(1997, this_year + 1)\n", + " month = randrange(1, 13)\n", + " day = randrange(1, 31)\n", + "\n", + " date_param = (\"date\", \"{0}-{1:02d}-{2:02d}\".format(year, month, day))\n", + "\n", + " url_params.append(date_param)\n", + " apod_url = construct_url(base_url, url_params)\n", + "\n", + " try:\n", + " print(apod_url)\n", + " response = requests.get(apod_url, timeout=30)\n", + " \n", + " if response.status_code == 200:\n", + " apod = response.json\n", + " print(apod)\n", + " print(f\"\\nPausing for {sleep_t} seconds before \"\n", + " \"next image.\\n\")\n", + " time.sleep(sleep_t)\n", + " elif response.status_code == 429:\n", + " print(f\"Error retrieving image from API, got {response.status_code}\")\n", + " print(f\"Sleeping {sleep_t} seconds.\")\n", + " time.sleep(sleep_t)\n", + " except KeyError:\n", + " print(f\"No larger-format image available, sleeping {sleep_t} seconds.\")\n", + " time.sleep(sleep_t)\n", + " except (requests.exceptions.ConnectionError,\n", + " requests.exceptions.ReadTimeout):\n", + " print(f\"Connection error, sleeping {sleep_t} seconds.\")\n", + " time.sleep(sleep_t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&hd=True&date=2000-04-19\n", + ">\n", + "\n", + "Pausing for 10 seconds before next image.\n", + "\n" + ] + } + ], + "source": [ + "get_random_apod()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Remote Library Client.ipynb b/Remote Library Client.ipynb new file mode 100644 index 0000000..a18a416 --- /dev/null +++ b/Remote Library Client.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import json" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "def main():\n", + " base_library_url = \"http://127.0.0.1:5000/api/v1/resources/books/\"\n", + "\n", + " _id = 0\n", + " library_url = base_library_url + f\"?id={_id}\"\n", + " req = requests.get(library_url)\n", + "\n", + " while req.json() != []:\n", + " print(req.json())\n", + " print()\n", + " _id += 1\n", + " library_url = base_library_url + f\"?id={_id}\"\n", + " req = requests.get(library_url)\n", + " \n", + " print(req, req.text)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'author': 'Vernor Vinge', 'first_sentence': 'The coldsleep itself was dreamless.', 'id': 0, 'title': 'A Fire Upon the Deep', 'year_published': '1992'}]\n", + "\n", + "[{'author': 'Ursula K. Le Guin', 'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.', 'id': 1, 'published': '1973', 'title': 'The Ones Who Walk Away From Omelas'}]\n", + "\n", + "[{'author': 'Samuel R. Delany', 'first_sentence': 'to wound the autumnal city.', 'id': 2, 'published': '1975', 'title': 'Dhalgren'}]\n", + "\n", + " []\n", + "\n" + ] + } + ], + "source": [ + "main()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Web APIs With Python.key b/Web APIs With Python.key new file mode 100644 index 0000000..c30cf8f Binary files /dev/null and b/Web APIs With Python.key differ diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/__init__.py b/src/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/api.py b/src/api/api.py new file mode 100644 index 0000000..134f2cf --- /dev/null +++ b/src/api/api.py @@ -0,0 +1,47 @@ +import flask +import books +from flask import request, jsonify +from flask_restful import Resource, Api, reqparse + +app = flask.Flask(__name__) +api = Api(app) + +app.config["DEBUG"] = True + +@app.route('/', methods=['GET']) +def home(): + return """

Distant Reading Archive

+

This site is a prototype API for distant reading of + science fiction novels.

""" + +parser = reqparse.RequestParser() +parser.add_argument('task') + +class Library(Resource): + def get(self, _id=None): + if _id: + results = [] + for liber in books.books: + if liber['id'] == int(_id): + results.append(liber) + break + return results + else: + return books.books + + def put(self, _id=None): + _id = int(_id) + json_data = request.get_json(force=True) + if _id: + for liber in books.books: + if liber['id'] == _id: + print(json_data) + print(liber) + liber['id'] = int(json_data['new_id']) + break + +api.add_resource(Library, + '/api/v1/resources/books/', + '/api/v1/resources/books/<_id>') + +app.run() diff --git a/src/api/api2.py b/src/api/api2.py new file mode 100644 index 0000000..6ff9214 --- /dev/null +++ b/src/api/api2.py @@ -0,0 +1,14 @@ +from flask import Flask +from flask_restful import Resource, Api + +app = Flask(__name__) +api = Api(app) + +class HelloWorld(Resource): + def get(self): + return {'hello': 'world'} + +api.add_resource(HelloWorld, '/') + +if __name__ == '__main__': + app.run(debug=True) diff --git a/src/api/api_old.py b/src/api/api_old.py new file mode 100644 index 0000000..d14347e --- /dev/null +++ b/src/api/api_old.py @@ -0,0 +1,39 @@ +import flask +import books +from flask import request, jsonify + +app = flask.Flask(__name__) +app.config["DEBUG"] = True + +@app.route('/', methods=['GET']) +def home(): + return """

Distant Reading Archive

+

This site is a prototype API for distant reading of + science fiction novels.

""" + +@app.route("/api/v1/resources/books/all", methods=["GET"]) +def api_all(): + return jsonify(books.books) + + +@app.route("/api/v1/resources/books/", methods=["GET"]) +def api_id(): + # Check if an ID was provided as part of the URL + # If ID is provided, assign it to a variable. + # If no ID is provided, display an error in the browser + if 'id' in request.args: + _id = int(request.args['id']) + else: + return "Error: No id field provided. Please specify an id.", 500 + + results = [] + + for liber in books.books: + if liber['id'] == _id: + results.append(liber) + break + + return jsonify(results) + + +app.run() diff --git a/src/api/books.py b/src/api/books.py new file mode 100644 index 0000000..777241b --- /dev/null +++ b/src/api/books.py @@ -0,0 +1,17 @@ +books = [ + {'id': 0, + 'title': 'A Fire Upon the Deep', + 'author': 'Vernor Vinge', + 'first_sentence': 'The coldsleep itself was dreamless.', + 'year_published': '1992'}, + {'id': 1, + 'title': 'The Ones Who Walk Away From Omelas', + 'author': 'Ursula K. Le Guin', + 'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.', + 'published': '1973'}, + {'id': 2, + 'title': 'Dhalgren', + 'author': 'Samuel R. Delany', + 'first_sentence': 'to wound the autumnal city.', + 'published': '1975'} +]