Skip to content

Commit 8112804

Browse files
WHWH
WH
authored and
WH
committed
Bootstrap aiohttp project
1 parent 2548580 commit 8112804

12 files changed

+167
-1
lines changed

Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.PHONY: test
2+
test:
3+
pytest --cov=app
4+
5+
.PHONY: testcov
6+
testcov:
7+
pytest --cov=app && (echo "building coverage html, view at './htmlcov/index.html'"; coverage html)

README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
# aidbox-python-sdk
1+
aidbox-python-sdk
2+
=================
3+
4+
5+
1. Activate a python 3.6 environment `python3.6 -m venv env`
6+
2. Set env variables and activate virtual environment `source activate_settings.sh`
7+
2. Install the required packages with `pip install -r requirements/base.txt -r requirements/dev.txt`
8+
3. Make sure the app's settings are configured correctly (see `activate_settings.sh` and `aidbox_python_sdk/settings.py`). You can also
9+
use environment variables to define sensitive settings, eg. DB connection variables
10+
4. You can then run your app during development with `adev runserver`.

activate_settings.sh

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
# App settings go here, they're validated in app.settings
3+
4+
# the AIO_ env variables are used by `adev runserver` when serving your app for development
5+
export AIO_APP_PATH="aidbox_python_sdk/"
6+
7+
8+
# also activate the python virtualenv for convenience, you can remove this if you're python another way
9+
. env/bin/activate

aidbox_python_sdk/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
aidbox-python-sdk
3+
"""

aidbox_python_sdk/gunicorn.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
This file allows your to serve your application using gunicorn. gunicorn is not installed by default
3+
by the requirements file adev creates, you'll need to install it yourself and add it to requirements.txt.
4+
5+
To run the aidbox_python_sdk using gunicorn, in the terminal run
6+
7+
pip install gunicorn
8+
gunicorn aidbox_python_sdk.gunicorn:aidbox_python_sdk --worker-class aiohttp.worker.GunicornWebWorker
9+
10+
You could use a variant of the above with heroku (in the `Procfile`) or with Docker in the ENTRYPOINT statement.
11+
"""
12+
import asyncio
13+
import uvloop
14+
15+
from .main import create_app
16+
17+
uvloop.install()
18+
loop = asyncio.get_event_loop()
19+
20+
app = loop.run_until_complete(create_app())

aidbox_python_sdk/main.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from pathlib import Path
2+
3+
from aiohttp import web
4+
5+
from .settings import Settings
6+
from .views import index
7+
8+
9+
THIS_DIR = Path(__file__).parent
10+
BASE_DIR = THIS_DIR.parent
11+
12+
13+
def setup_routes(app):
14+
app.router.add_get('/', index, name='index')
15+
16+
17+
async def create_app():
18+
app = web.Application()
19+
settings = Settings()
20+
app.update(
21+
name='aidbox-python-sdk',
22+
settings=settings
23+
)
24+
25+
setup_routes(app)
26+
return app

aidbox_python_sdk/settings.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import os
2+
from pathlib import Path
3+
4+
5+
class Required:
6+
def __init__(self, v_type=None):
7+
self.v_type = v_type
8+
9+
10+
class Settings:
11+
"""
12+
Any setting defined here can be overridden by:
13+
14+
Settings the appropriate environment variable, eg. to override FOOBAR, `export APP_FOOBAR="whatever"`.
15+
This is useful in production for secrets you do not wish to save in code and
16+
also plays nicely with docker(-compose). Settings will attempt to convert environment variables to match the
17+
type of the value here. See also activate.settings.sh.
18+
19+
Or, passing the custom setting as a keyword argument when initialising settings (useful when testing)
20+
"""
21+
_ENV_PREFIX = 'APP_'
22+
23+
def __init__(self, **custom_settings):
24+
"""
25+
:param custom_settings: Custom settings to override defaults, only attributes already defined can be set.
26+
"""
27+
self._custom_settings = custom_settings
28+
self.substitute_environ()
29+
for name, value in custom_settings.items():
30+
if not hasattr(self, name):
31+
raise TypeError('{} is not a valid setting name'.format(name))
32+
setattr(self, name, value)
33+
setattr(self, 'static_path', None)
34+
35+
def substitute_environ(self):
36+
"""
37+
Substitute environment variables into settings.
38+
"""
39+
for attr_name in dir(self):
40+
if attr_name.startswith('_') or attr_name.upper() != attr_name:
41+
continue
42+
43+
orig_value = getattr(self, attr_name)
44+
is_required = isinstance(orig_value, Required)
45+
orig_type = orig_value.v_type if is_required else type(orig_value)
46+
env_var_name = self._ENV_PREFIX + attr_name
47+
env_var = os.getenv(env_var_name, None)
48+
if env_var is not None:
49+
if issubclass(orig_type, bool):
50+
env_var = env_var.upper() in ('1', 'TRUE')
51+
elif issubclass(orig_type, int):
52+
env_var = int(env_var)
53+
elif issubclass(orig_type, Path):
54+
env_var = Path(env_var)
55+
elif issubclass(orig_type, bytes):
56+
env_var = env_var.encode()
57+
# could do floats here and lists etc via json
58+
setattr(self, attr_name, env_var)
59+
elif is_required and attr_name not in self._custom_settings:
60+
raise RuntimeError('The required environment variable "{0}" is currently not set, '
61+
'you\'ll need to run `source activate.settings.sh` '
62+
'or you can set that single environment variable with '
63+
'`export {0}="<value>"`'.format(env_var_name))

aidbox_python_sdk/views.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from aiohttp import web
2+
3+
4+
async def index(request):
5+
"""
6+
This is the view handler for the "/" url.
7+
8+
:param request: the request object see http://aiohttp.readthedocs.io/en/stable/web_reference.html#request
9+
:return: aiohttp.web.Response object
10+
"""
11+
12+
return web.json_response({'hello': 'world'})

requirements/base.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# you will need to install these requirements with `pip install -r requirements.txt`
2+
aiohttp==3.4.4
3+
pytest-aiohttp==0.3.0
4+
pytest-cov==2.6.0
5+
pytest==4.0.1

requirements/dev.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# you will need to install these requirements with `pip install -r requirements.txt`
2+
aiohttp-devtools==0.11
3+
uvloop==0.12.0

setup.cfg

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[tool:pytest]
2+
testpaths = tests
3+
4+
[flake8]
5+
max-line-length = 120
6+
max-complexity = 12

tests/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
aidbox-python-sdk tests
3+
"""

0 commit comments

Comments
 (0)