AndroidDrew 7 years ago
commit 37355d14cb

1
.gitignore vendored

@ -16,6 +16,7 @@ __pycache__/
# Distribution / packaging # Distribution / packaging
.Python .Python
env/ env/
pypyenv/
build/ build/
develop-eggs/ develop-eggs/
dist/ dist/

@ -1,4 +0,0 @@
# config.ini
[user]
BCRYPT_LOG_ROUNDS : 13

@ -5,14 +5,17 @@ from apistar.frameworks.wsgi import WSGIApp as App
from apistar.handlers import docs_urls, static_urls from apistar.handlers import docs_urls, static_urls
from apistar.interfaces import Router, Injector, Auth from apistar.interfaces import Router, Injector, Auth
from apistar_jwt.authentication import JWTAuthentication from apistar_jwt.authentication import JWTAuthentication
import logbook
from cookie_api.auth import auth_routes, auth_components from cookie_api.auth import auth_routes, auth_components
from cookie_api.commands import commands from cookie_api.commands import commands
from cookie_api.models import Cookie from cookie_api.models import Cookie
from cookie_api.schema import CookieSchema from cookie_api.schema import CookieSchema
from cookie_api import logging
cookie_schema = CookieSchema() cookie_schema = CookieSchema()
logger = logbook.Logger('Cookies')
@annotate(authentication=[JWTAuthentication()]) @annotate(authentication=[JWTAuthentication()])
def get_state(injector: Injector, auth: Auth): def get_state(injector: Injector, auth: Auth):
@ -24,73 +27,57 @@ def get_state(injector: Injector, auth: Auth):
def get_cookies(session: Session): def get_cookies(session: Session):
"""Retrieves all Cookies""" logger.info("Accessing the Cookies resource")
cookies = session.query(Cookie).all() cookies = session.query(Cookie).all()
return cookie_schema.dump(cookies, many=True).data return cookie_schema.dump(cookies, many=True).data
def create_cookie(session: Session, json_data: http.RequestData, route: Router):
"""Create a Cookie"""
cookie_data, errors = cookie_schema.load(json_data)
if errors:
msg = {"message": "400 Bad Request", "error": errors}
return http.Response(msg, status=400)
cookie = Cookie(**cookie_data)
session.add(cookie)
session.flush()
headers = {'Location': route.reverse_url('get_cookie', dict(id=cookie.id))}
return http.Response(cookie_schema.dump(cookie).data, status=201, headers=headers)
def get_cookie(session: Session, id): def get_cookie(session: Session, id):
"""Retrieve Cookie by id"""
cookie = session.query(Cookie).filter_by(id=id).one_or_none() cookie = session.query(Cookie).filter_by(id=id).one_or_none()
if cookie is None: if cookie is None:
msg = {"message": "404 Not Found"} logger.warn("Someone keeps requesting bad cookie locations")
msg = {"error": "404 Not Found"}
return http.Response(msg, status=404) return http.Response(msg, status=404)
return cookie_schema.dump(cookie).data return cookie_schema.dump(cookie).data
def patch_cookie(session: Session, json_data: http.RequestData, id: int): def create_cookie(session: Session, json_data: http.RequestData, route: Router):
"""Update Cookie through partial update""" cookie_data = cookie_schema.load(json_data)
cookie = session.query(Cookie).filter_by(id=id).one_or_none()
if cookie is None: #cookie = Cookie(name=json_data['name'],
msg = {"message": "404 Not Found"} # recipe_url=json_data['recipe_url'],
return http.Response(msg, status=404) # sku=json_data['sku'],
# run schema validation of fields # qoh=json_data['qoh'],
cookie_data, errors = cookie_schema.load(json_data, partial=True) # unit_cost=json_data['unit_cost'])
if errors: cookie = Cookie(**cookie_data)
msg = {"message": "400 Bad Request", "error": errors} session.add(cookie)
return http.Response(msg, status=400) session.commit()
headers = {'Location': route.reverse_url('get_cookie', dict(id=cookie.id))}
for k, v in cookie_data.items(): return http.Response(cookie_schema.dump(cookie), status=201, headers=headers)
setattr(cookie, k, v)
session.flush()
return cookie_schema.dump(cookie).data
def delete_cookie(session: Session, id: int): def delete_cookie(session: Session, id: int):
"""Delete a Cookie"""
cookie = session.query(Cookie).filter_by(id=id).one_or_none() cookie = session.query(Cookie).filter_by(id=id).one_or_none()
if cookie is None: if cookie is None:
msg = {"message": "404 Not Found"} msg = {"error": "404 Not Found"}
return http.Response(msg, status=404) return http.Response(msg, status=404)
session.delete(cookie) session.delete(cookie)
return {"message": "200 OK"} return {"message": "200 OK"}
routes = [ routes = [
Route('/state', 'GET', get_state), Route('/state', 'GET', get_state),
Route('/cookies', 'GET', get_cookies), Route('/cookies', 'GET', get_cookies),
Route('/cookies', 'POST', create_cookie), Route('/cookies', 'POST', create_cookie),
Route('/cookies/{id}', 'GET', get_cookie), Route('/cookies/{id}', 'GET', get_cookie),
Route('/cookies/{id}', 'PATCH', patch_cookie),
Route('/cookies/{id}', 'DELETE', delete_cookie),
Include('/docs', docs_urls), Include('/docs', docs_urls),
Include('/static', static_urls) Include('/static', static_urls)
] ]
app_settings = {} app_settings = {
"LOGGING": {
"LEVEL": "DEBUG"
}
}
routes = routes + auth_routes routes = routes + auth_routes
@ -101,7 +88,11 @@ components = sqlalchemy_backend.components + auth_components
def application_factory(settings={}): def application_factory(settings={}):
"""Returns an instance of Cookie API""" """Returns an instance of Cookie API"""
return App(settings={**app_settings, **settings}, _settings = {**app_settings, **settings}
logging.global_init(_settings)
return App(settings=_settings,
commands=commands, commands=commands,
components=components, components=components,
routes=routes) routes=routes)

@ -15,7 +15,7 @@ from cookie_api.models import User
auth_components = [ auth_components = [
Component(JWT, init=get_jwt) Component(JWT, init=get_jwt)
] ]
[]
# /auth/login # /auth/login
def login(settings: Settings, json_data: http.RequestData, session: Session): def login(settings: Settings, json_data: http.RequestData, session: Session):

@ -0,0 +1,16 @@
import sys
import logbook
def global_init(settings={}):
_logging_setting = settings.get("LOGGING", {"LEVEL": logbook.TRACE})
_log_file = _logging_setting.get("LOG_FILE")
_level = _logging_setting.get("LEVEL")
if _log_file is not None:
logbook.TimedRotatingFileHandler(_log_file, level=_level).push_application()
else:
logbook.StreamHandler(sys.stdout, level=_level).push_application()

@ -1,5 +1,3 @@
from configparser import ConfigParser
import bcrypt import bcrypt
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Numeric from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Numeric
@ -8,11 +6,7 @@ from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime as DateTimeType from sqlalchemy.types import DateTime as DateTimeType
cfg = ConfigParser() BCRYPT_LOG_ROUNDS = 13
cfg.read('config.ini')
BCRYPT_LOG_ROUNDS = int(cfg.get('user', 'BCRYPT_LOG_ROUNDS'))
# can be moved to models util? # can be moved to models util?
class utcnow(expression.FunctionElement): class utcnow(expression.FunctionElement):

@ -1,25 +1,12 @@
from marshmallow import Schema, fields, ValidationError from marshmallow import Schema, fields
def non_neg(value):
if not value >= 0:
raise ValidationError('Value cannot be negative')
def non_neg_non_zero(value):
if not value > 0:
raise ValidationError('Value cannot be negative or zero')
class CookieSchema(Schema): class CookieSchema(Schema):
id = fields.Int(dump_only=True) id = fields.Int()
created_date = fields.DateTime(dump_only=True) created_date = fields.DateTime()
modified_date = fields.DateTime() modified_date = fields.DateTime()
name = fields.Str(required=True, error_messages={'required': "Cookie name is required"}) name = fields.Str(required=True)
recipe_url = fields.Str() recipe_url = fields.Str()
sku = fields.Str(required=True, error_messages={'required': "Cookie sku is required"}) sku = fields.Str(required=True)
qoh = fields.Int(validate=non_neg, required=True, error_messages={'required': "Cookie qoh is required"}) qoh = fields.Int(required=True)
unit_cost = fields.Decimal(validate=non_neg_non_zero, required=True, error_messages={'required': "Cookie unit_cost is required"}) unit_cost = fields.Decimal(required=True)
class Meta:
ordered = True

@ -10,7 +10,9 @@ coreschema==0.0.4
idna==2.6 idna==2.6
itypes==1.1.0 itypes==1.1.0
Jinja2==2.9.6 Jinja2==2.9.6
Logbook==1.1.0
MarkupSafe==1.0 MarkupSafe==1.0
marshmallow==2.15.0
psycopg2==2.7.3.1 psycopg2==2.7.3.1
py==1.4.34 py==1.4.34
pycparser==2.18 pycparser==2.18

@ -1,3 +1,10 @@
try:
import psycopg2
except ImportError:
# Fall back to psycopg2cffi
from psycopg2cffi import compat
compat.register()
import os import os
import sys import sys
from cookie_api import JSONRenderer, Base, application_factory from cookie_api import JSONRenderer, Base, application_factory
@ -10,6 +17,10 @@ settings = {
'RENDERERS': [JSONRenderer()], 'RENDERERS': [JSONRenderer()],
'JWT': { 'JWT': {
'SECRET': 'thisisasecret' 'SECRET': 'thisisasecret'
},
'LOGGING': {
"LOG_FILE": 'mylogfile.log',
"LEVEL": "DEBUG"
} }
} }

Loading…
Cancel
Save