-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
5,736 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.egg-info | ||
.tox | ||
Pipfile | ||
.env | ||
.nenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
FROM python:3-alpine | ||
|
||
RUN addgroup -S user && adduser user -S -G user | ||
|
||
WORKDIR /home/user/ | ||
|
||
COPY requirements.txt . | ||
COPY gunicorn_config.py . | ||
COPY setup.py . | ||
COPY setup.cfg . | ||
COPY init_entrypoint.sh / | ||
|
||
RUN pip install hypercorn | ||
RUN pip install -r requirements.txt | ||
|
||
USER user | ||
|
||
EXPOSE 5000 | ||
|
||
ENTRYPOINT [] | ||
|
||
CMD hypercorn --config python:./gunicorn_config.py magnumopus.index:app | ||
|
||
COPY magnumopus magnumopus |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Magnum Opus | ||
=========== | ||
|
||
Recipe maker for the philosopher's stone. | ||
|
||
|
||
python3 -m pytest --cov magnumopus >> README.md | ||
|
||
============================= test session starts ============================== | ||
platform linux -- Python 3.8.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 | ||
rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus | ||
plugins: pep8-1.0.6, cov-2.10.0 | ||
collected 15 items | ||
|
||
tests/domain/test_alembic.py ....... [ 46%] | ||
tests/domain/test_pantry.py .. [ 60%] | ||
tests/domain/test_substance.py ...... [100%] | ||
|
||
----------- coverage: platform linux, python 3.8.2-final-0 ----------- | ||
Name Stmts Miss Cover | ||
------------------------------------------------------------------------ | ||
magnumopus/__init__.py 10 8 20% | ||
magnumopus/config.py 4 4 0% | ||
magnumopus/index.py 2 2 0% | ||
magnumopus/initialize.py 6 6 0% | ||
magnumopus/logger.py 4 4 0% | ||
magnumopus/models/__init__.py 3 1 67% | ||
magnumopus/models/base.py 2 0 100% | ||
magnumopus/models/substance.py 24 0 100% | ||
magnumopus/repositories/__init__.py 0 0 100% | ||
magnumopus/repositories/pantry.py 12 1 92% | ||
magnumopus/repositories/sqlalchemy_pantry.py 15 15 0% | ||
magnumopus/resources/__init__.py 7 7 0% | ||
magnumopus/resources/alembic_instruction.py 26 26 0% | ||
magnumopus/resources/substance.py 28 28 0% | ||
magnumopus/schemas/__init__.py 4 4 0% | ||
magnumopus/schemas/substance_schema.py 11 11 0% | ||
magnumopus/services/__init__.py 0 0 100% | ||
magnumopus/services/alembic.py 32 2 94% | ||
magnumopus/services/alembic_instruction_handler.py 20 20 0% | ||
magnumopus/services/assessor.py 2 2 0% | ||
------------------------------------------------------------------------ | ||
TOTAL 212 141 33% | ||
|
||
|
||
============================== 15 passed in 0.38s ============================== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop | ||
* Any attempt to mix anything other than those three substances, gives Sludge, another substance | ||
* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented | ||
* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) | ||
[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] | ||
|
||
Final rule: | ||
GROUP 1: When I process a substance, using any process, it becomes a different substance | ||
GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
version: "3" | ||
services: | ||
web_async_gql: | ||
build: . | ||
environment: | ||
DATABASE_URI: 'sqlite:////docker/storage/storage.db' | ||
volumes: | ||
- ./docker:/docker | ||
- ./magnumopus:/home/user/magnumopus | ||
ports: | ||
- 5000:5000 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
port = '5000' | ||
bind = "0.0.0.0:%s" % port | ||
workers = 1 | ||
timeout = 600 | ||
reload = False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/sh | ||
|
||
mkdir -p docker/storage | ||
|
||
docker-compose run --user root web /init_entrypoint.sh | ||
docker-compose run web python3 -m magnumopus.initialize |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/sh | ||
|
||
chown -R user:user /docker/storage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from quart_openapi import Pint | ||
|
||
def create_app(): | ||
from . import models, resources, schemas, logger, repositories, injection, graph | ||
|
||
app = Pint(__name__, title='Magnum Opus') | ||
|
||
# This could be used to separate by environment | ||
app.config.from_object('magnumopus.config.Config') | ||
|
||
# This helps avoid cyclic dependencies | ||
modules = [] | ||
|
||
modules += logger.init_app(app) | ||
modules += models.init_app(app) | ||
modules += resources.init_app(app) | ||
modules += repositories.init_app(app) | ||
modules += schemas.init_app(app) | ||
modules += graph.init_app(app) | ||
|
||
injection.init_app(app, modules) | ||
|
||
return app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import os | ||
|
||
class Config: | ||
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI', 'sqlite:///:memory:') | ||
SQLALCHEMY_TRACK_MODIFICATIONS = False | ||
|
||
PANTRY_STORE = os.environ.get('MAGNUMOPUS_PANTRY_STORE', 'list') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from quart import request, jsonify | ||
from ariadne import ObjectType, make_executable_schema, graphql | ||
from ariadne.constants import PLAYGROUND_HTML | ||
|
||
from .repositories import PANTRY_STORES | ||
|
||
PANTRY = PANTRY_STORES['list'] | ||
|
||
type_defs = """ | ||
type Query { | ||
substances(nature: String!): [Substance] | ||
} | ||
type Substance { | ||
nature: String!, | ||
state: [String]! | ||
} | ||
""" | ||
|
||
query = ObjectType('Query') | ||
substance = ObjectType('Substance') | ||
|
||
@query.field('substances') | ||
def resolve_substances(obj, *_, nature='Unknown'): | ||
return PANTRY.find_substances_by_nature(nature) | ||
|
||
|
||
@substance.field('nature') | ||
def resolve_nature(obj, *_): | ||
return obj.nature | ||
|
||
@substance.field('state') | ||
def resolve_state(obj, *_): | ||
return obj.state | ||
|
||
schema = make_executable_schema(type_defs, query, substance) | ||
|
||
async def graphql_server(): | ||
data = await request.get_json() | ||
success, result = await graphql( | ||
schema, | ||
data, | ||
context_value=request | ||
) | ||
|
||
return jsonify(result), (200 if success else 400) | ||
|
||
def init_app(app): | ||
app.route('/graphql', methods=['GET'], endpoint='graphql_playground')( | ||
lambda: (PLAYGROUND_HTML, 200) | ||
) | ||
|
||
app.route('/graphql', methods=['POST'], endpoint='graphql_server')( | ||
graphql_server | ||
) | ||
|
||
return [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from . import create_app | ||
|
||
app = create_app() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from . import create_app | ||
from .models import db | ||
|
||
if __name__ == "__main__": | ||
# There are nicer ways around this, but this keeps it clear for an example | ||
app = create_app() | ||
|
||
with app.app_context(): | ||
db.create_all() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from injector import Injector | ||
from quart.views import MethodViewType | ||
|
||
class ViewInjectorMeta(MethodViewType): | ||
def get_injector(self): | ||
return self.get_app().extensions['injector'] | ||
|
||
def __call__(cls, *args, **kwargs): | ||
return cls.get_injector().create_object( | ||
cls.__bases__[0], | ||
additional_kwargs=kwargs | ||
) | ||
|
||
def init_app(app, modules): | ||
modules.append(configure_injector) | ||
|
||
injctr = Injector() | ||
for module in modules: | ||
injctr.binder.install(module) | ||
app.extensions['injector'] = injctr | ||
|
||
def configure_injector(binder): | ||
""" | ||
Add any general purpose injectables, not included in a submodule | ||
""" | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import logging | ||
|
||
def init_app(app): | ||
app.logger.addHandler(logging.StreamHandler()) | ||
app.logger.setLevel(logging.INFO) | ||
return [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from .base import db | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
def init_app(app): | ||
# db.init_app(app) | ||
return [configure_injector] | ||
|
||
def configure_injector(binding): | ||
binding.bind( | ||
SQLAlchemy, to=db | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
db = SQLAlchemy() |
40 changes: 40 additions & 0 deletions
40
022-burette/magnum_opus_iii/magnumopus/models/substance.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from . import db | ||
from sqlalchemy_utils import ScalarListType | ||
|
||
class SubstanceMustBeFreshToProcessException(Exception): | ||
pass | ||
|
||
class Substance(db.Model): | ||
__tablename__ = 'substances' | ||
|
||
id = db.Column(db.Integer, primary_key=True) | ||
nature = db.Column(db.String(32), default='Unknown') | ||
state = db.Column(ScalarListType()) | ||
|
||
def __init__(self, nature='Unknown'): | ||
self.state = [] | ||
self.nature = nature | ||
|
||
super(Substance, self).__init__() | ||
|
||
def _process(self, process_name): | ||
# Example of leakage of persistence behaviour into | ||
# domain, due to db.Model -- we must copy the state list to | ||
# ensure it is seen to change... | ||
state = self.state[:] | ||
state.append(process_name) | ||
self.state = state | ||
|
||
return self | ||
|
||
def cook(self): | ||
return self._process('cooked') | ||
|
||
def pickle(self): | ||
return self._process('pickled') | ||
|
||
def ferment(self): | ||
return self._process('fermented') | ||
|
||
def wash(self): | ||
return self._process('washed') |
18 changes: 18 additions & 0 deletions
18
022-burette/magnum_opus_iii/magnumopus/repositories/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from .pantry import Pantry | ||
from .list_pantry import ListPantry | ||
from .sqlalchemy_pantry import SQLAlchemyPantry | ||
|
||
PANTRY_STORES = { | ||
'sqlalchemy': SQLAlchemyPantry, | ||
'list': ListPantry() # we instantiate this, as we want a singleton cupboard | ||
} | ||
|
||
def init_app(app): | ||
return [lambda binder: configure_injector(binder, app)] | ||
|
||
def configure_injector(binder, app): | ||
pantry_cls = PANTRY_STORES[app.config['PANTRY_STORE']] | ||
|
||
binder.bind( | ||
Pantry, to=pantry_cls | ||
) |
26 changes: 26 additions & 0 deletions
26
022-burette/magnum_opus_iii/magnumopus/repositories/list_pantry.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
class ListPantry: | ||
def __init__(self): | ||
self._cupboard = [] | ||
|
||
def empty_pantry(self): | ||
self._cupboard = [] | ||
|
||
def add_substance(self, substance): | ||
self._cupboard.append(substance) | ||
|
||
def find_substances_by_nature(self, nature): | ||
return [substance for substance in self._cupboard if substance.nature == nature] | ||
|
||
def count_all_substances(self): | ||
return len(self._cupboard) | ||
|
||
def commit(self): | ||
# Give each substance an ID, if it does not have one | ||
free_ids = iter( | ||
set(range(1, len(self._cupboard) + 1)) - | ||
set([substance.id for substance in self._cupboard if substance]) | ||
) | ||
|
||
for substance in self._cupboard: | ||
if not substance.id: | ||
substance.id = next(free_ids) |
25 changes: 25 additions & 0 deletions
25
022-burette/magnum_opus_iii/magnumopus/repositories/pantry.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from abc import ABC, abstractmethod | ||
|
||
class Pantry(ABC): | ||
def __init__(self): | ||
pass | ||
|
||
@abstractmethod | ||
def do_empty(self): | ||
pass | ||
|
||
@abstractmethod | ||
def add_substance(self, substance): | ||
pass | ||
|
||
@abstractmethod | ||
def find_substances_by_nature(self, nature): | ||
pass | ||
|
||
@abstractmethod | ||
def count_all_substances(self): | ||
pass | ||
|
||
@abstractmethod | ||
def commit(self): | ||
pass |
Oops, something went wrong.