Skip to content

Commit

Permalink
add object parser example to server
Browse files Browse the repository at this point in the history
  • Loading branch information
voschezang committed Jul 5, 2023
1 parent 729786e commit 0f4b0b0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/mash/object_parser/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class BuildError(SpecError):
class BuildErrors(SpecError):
pass


def to_string(errors: BuildErrors) -> str:
return '\n'.join(error.args[0] for error in errors.args[0])


class ErrorMessages:
"""A static class with can be subclassed
"""
Expand Down
10 changes: 8 additions & 2 deletions src/mash/object_parser/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,10 @@ def build_field(self, key, data):

def build_from_dict(self, fields: dict):
if hasattr(self.cls, '__dataclass_fields__'):
return self.cls(**fields)
try:
return self.cls(**fields)
except TypeError as e:
pass

if is_Dict(self.cls):
return self.build_generic_Dict(fields)
Expand All @@ -199,7 +202,10 @@ def build_from_dict(self, fields: dict):
if issubclass(self.cls, Spec):
instance = super(Spec, self.cls).__new__(self.cls)
else:
instance = self.cls()
try:
instance = self.cls()
except TypeError:
raise BuildError('Invalid input')

if has_annotations(self.cls):
# assume instance of Spec
Expand Down
31 changes: 24 additions & 7 deletions src/mash/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http.client import BAD_REQUEST
from dataclasses import dataclass
from json import loads
from logging import debug
from flask import Flask, request
from http import HTTPStatus
from werkzeug.utils import secure_filename
Expand All @@ -8,6 +9,8 @@
import time

from mash import verify_server
from mash.object_parser.errors import BuildError, BuildErrors, to_string
from mash.object_parser.factory import JSONFactory

UPLOAD_FOLDER = 'tmp/flask-app'

Expand All @@ -16,6 +19,12 @@
db = None


@dataclass
class RawUser:
name: str
email: str


def init():
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Expand Down Expand Up @@ -125,10 +134,18 @@ def users():
if request.method == 'POST':
data = loads(request.data)

if 'name' not in data or 'email' not in data:
return 'Missing fields', HTTPStatus.BAD_REQUEST

id = create_user(data['name'], data['email'])
# WARNING: this exposes internal classes
try:
user = JSONFactory(RawUser).build(data)
except BuildError as e:
debug('POST /users\n' + e.args[0])
return f'Invalid input: {e.args[0]}', HTTPStatus.BAD_REQUEST
except BuildErrors as e:
errors = to_string(e)
debug('POST /users\n' + errors)
return f'Invalid input: {errors}', HTTPStatus.BAD_REQUEST

id = create_user(user)
return str(id)

return '', HTTPStatus.BAD_REQUEST
Expand All @@ -150,11 +167,11 @@ def generate_user(i: int) -> dict:
return {'name': f'name_{i}', 'email': f'name.{i}@company.com'}


def create_user(name, email):
def create_user(user: RawUser):
# generate user id
id = len(db['users']) + 1
# create object
user = {'name': name, 'email': email}
user = {'name': user.name, 'email': user.email}
# store object
db['users'][id] = user
return id
Expand Down
8 changes: 7 additions & 1 deletion test/object_parser/test_object_parser_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ def test_Team_with_factory():

# missing mandatory key
with pytest.raises(SpecError):
team = JSONFactory(Team).build({'manager': manager})
JSONFactory(Team).build({'manager': manager})

with pytest.raises(SpecError):
JSONFactory(Team).build({})


def test_Team_enum():
Expand Down Expand Up @@ -107,6 +110,9 @@ def test_DepartmentData():
assert d.teams[i].manager == department['teams'][i]['manager']
assert d.teams[i].members == department['teams'][i]['members']

with pytest.raises(SpecError):
JSONFactory(DepartmentData).build({})


def test_OrganizationData():
org = JSONFactory(OrganizationData).build(json)
Expand Down
7 changes: 7 additions & 0 deletions test/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ def test_users_post():
assert data['email'] == user['email']


def test_users_post_unhappy():
client = init()
user = {'name': 'test'}
response = client.post(basepath + 'users', json=user)
assert response.status_code == 400


def assert_response(response, expected_data=b'ok'):
assert response.status_code == HTTPStatus.OK
assert response.get_data() == expected_data
Expand Down

0 comments on commit 0f4b0b0

Please sign in to comment.