diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2017-10-11 19:39:04 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2017-10-11 19:39:56 -0400 |
| commit | 49fda3601248d939b0cfff1bff5a18800e498bdc (patch) | |
| tree | de97903cdb154a9ba11d8d2b603c2b90c45aa8a0 | |
The HTML is kind of jank
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | LICENSE.md | 21 | ||||
| -rw-r--r-- | Procfile | 1 | ||||
| -rw-r--r-- | app.py | 37 | ||||
| -rwxr-xr-x | bin/web | 67 | ||||
| -rw-r--r-- | requirements.txt | 18 | ||||
| -rw-r--r-- | runtime.txt | 1 | ||||
| -rw-r--r-- | templates/index.html | 37 | ||||
| -rw-r--r-- | tests.py | 10 | ||||
| -rw-r--r-- | things-to-check.yml | 35 |
10 files changed, 229 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4df23a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.venv/ +*.pyc diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..7ac9dc8 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +Copyright (c) 2017 the authors. Please see the Git history, or contact +agora-discussion@agoranomic.org for information about the authorship of this +project. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..bb58ffb --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: bin/web @@ -0,0 +1,37 @@ +from apistar import Include, Route, annotate, render_template +from apistar.frameworks.wsgi import WSGIApp as App +from apistar.handlers import docs_urls, static_urls +from apistar.renderers import HTMLRenderer +import random +import yaml + +with open('things-to-check.yml', 'r') as things_file: + things = yaml.safe_load(things_file) + +@annotate(renderers=[HTMLRenderer()]) +def random_thing(item: int = None): + if item is None: + item = random.randrange(len(things)) + return render_template('index.html', + item=item, + thing=things[item], + ) + + +routes = [ + Route('/', 'GET', random_thing), + Include('/docs', docs_urls), + Include('/static', static_urls), +] + +settings = { + 'TEMPLATES': { + 'ROOT_DIR': 'templates', # Include the 'templates/' directory. + 'PACKAGE_DIRS': ['apistar'] # Include the built-in apistar templates. + } +} + +app = App( + routes=routes, + settings=settings, +) @@ -0,0 +1,67 @@ +#!/bin/bash -e + +# See "Running in Production" in the API Star documentation at +# <https://github.com/encode/apistar#running-in-production> + +# In development, gunicorn can automatically reload code as you edit it. To +# enable this feature, export `GUNICORN_CMD_ARGS='--reload'` before running +# this script. +# +# See: +# * <http://docs.gunicorn.org/en/stable/settings.html> +# * <http://docs.gunicorn.org/en/stable/settings.html#reload> + +# If the `PORT` environment variable is set, we're probably running on a +# platform like Heroku that expects the application to bind to it. Otherwise, +# default to port 5000. gunicorn will print the value on startup either way, +# allowing administrators and developers to determine the server's base URL. +# +# See: +# * <https://devcenter.heroku.com/articles/runtime-principles#web-servers> +# * <https://devcenter.heroku.com/articles/dynos#web-dynos> + +PORT=${PORT:-5000} + +# Run the application with gunicorn. Note that the API Star documentation +# recommends setting `--workers`. We omit this option: on our target platform, +# this is controlled automatically using the `WEB_CONCURRENCY` environment +# variable, which has a computed default based on the resources available at +# runtime. Falling back to gunicorn's default configuration is safe enough, as +# an administrator who discovers this is the wrong configuration can easily set +# `WEB_CONCURRENCY` to override it. +# +# See: +# * <https://devcenter.heroku.com/articles/python-gunicorn#basic-configuration> +# * <http://docs.gunicorn.org/en/stable/settings.html#workers> +# +# The API Star documentation also recommends the Meinheld worker type. However, +# deploying Meinheld to Heroku causes the application to fail on startup: +# +# Error: class uri 'meinheld.gmeinheld.MeinheldWorker' invalid or not found: +# [Traceback (most recent call last): +# File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/util.py", line 134, in load_class +# File "/app/.heroku/python/lib/python3.6/importlib/__init__.py", line 126, in import_module +# mod = import_module('.'.join(components)) +# return _bootstrap._gcd_import(name[level:], package, level) +# File "<frozen importlib._bootstrap>", line 978, in _gcd_import +# File "<frozen importlib._bootstrap>", line 936, in _find_and_load_unlocked +# File "<frozen importlib._bootstrap>", line 961, in _find_and_load +# File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed +# File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked +# File "<frozen importlib._bootstrap>", line 655, in _load_unlocked +# File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed +# File "<frozen importlib._bootstrap_external>", line 678, in exec_module +# File "/app/.heroku/python/lib/python3.6/site-packages/meinheld/__init__.py", line 1, in <module> +# from meinheld.server import * +# File "<frozen importlib._bootstrap>", line 978, in _gcd_import +# File "<frozen importlib._bootstrap>", line 961, in _find_and_load +# ImportError: libpython3.6m.so.1.0: cannot open shared object file: No such file or directory +# ] +# +# The `libpython3.6m.so` library does not appear to be present. As we don't need +# to squeeze every ounce of performance out of this application, I've removed +# the Meinheld worker and opened a support ticket to get an explanation from +# Heroku. + +exec gunicorn app:app \ + --bind="0.0.0.0:${PORT}" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ce5bb01 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +apistar==0.3.9 +certifi==2017.7.27.1 +chardet==3.0.4 +coreapi==2.3.3 +coreschema==0.0.4 +gunicorn==19.7.1 +idna==2.6 +itypes==1.1.0 +Jinja2==2.9.6 +MarkupSafe==1.0 +py==1.4.34 +pytest==3.2.3 +PyYAML==3.12 +requests==2.18.4 +uritemplate==3.0.0 +urllib3==1.22 +Werkzeug==0.12.2 +whitenoise==3.3.1 diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000..cfa5aa5 --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.6.2 diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..a827efe --- /dev/null +++ b/templates/index.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> + <title>Have you checked {{ thing }}?</title> + <style> + body { + background: #dddde7; + font-color: #888; + font-family: Helvetica, sans-serif; + display: flex; + flex-direction: column; + justify-content: center; + height: 100%; + } + + section { + width: 600px; + margin: auto; + } + + p { + font-size: 24px; + } + + a { + text-decoration: none; + } + </style> +</head> +<body> + <section> + <p>Have you checked {{ thing }}?</p> + <p><a href="">That wasn't it, suggest something else.</a></p> + <p><a href="?item={{ item }}">Share this troubleshooting suggestion.</a></p> + </section> +</body> +</html> diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..9d52baa --- /dev/null +++ b/tests.py @@ -0,0 +1,10 @@ +from apistar.test import TestClient +from app import app, welcome + + +def test_welcome(): + """ + Testing a view directly. + """ + data = welcome() + assert data == {'message': 'Welcome to API Star!'} diff --git a/things-to-check.yml b/things-to-check.yml new file mode 100644 index 0000000..29ecb37 --- /dev/null +++ b/things-to-check.yml @@ -0,0 +1,35 @@ +--- +# Insert new items at the bottom. The index into this list is the item's +# permalink. +# +# Yes, this is HTML and no, I don't care about injection. +- permissions +- cabling +- for a full disk +- the cache +- for a version conflict +- for a duplex mismatch +- the firewall rules +- <code>resolv.conf</code> +- <code>/etc/hosts</code> +- DNS +- <code>CR/LF</code> +- setuid/setgid bits +- the default gateway +- for IP conflicts +- the logs +- the port number +- for a zonefile dot +- I/O dammit +- the mounts +- the power +- for the wrong whitespace +- if it reloaded into bad config +- IP forwarding +- the trailing slash +- the MAC address +- if the filesystem is out of inodes +- the line length +- if you're on the wrong wifi network +- if the vpn timed out +- if that's the wrong host |
