Skip to content

Commit

Permalink
Merge pull request #13 from devinaconley/0.1.1
Browse files Browse the repository at this point in the history
v0.1.1
  • Loading branch information
devinaconley authored Aug 17, 2023
2 parents 6c97821 + 6667d69 commit 35a7bc0
Show file tree
Hide file tree
Showing 24 changed files with 547 additions and 498 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018-2021 Devin A. Conley
Copyright (c) 2018-2023 Devin A. Conley

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ Simple **shapes** example:
import objectfactory

@objectfactory.register
class Square( objectfactory.Serializable ):
class Square(objectfactory.Serializable):
side = objectfactory.Field()

def get_area( self ):
def get_area(self):
return self.side * self.side

@objectfactory.register
class Triangle( objectfactory.Serializable ):
class Triangle(objectfactory.Serializable):
base = objectfactory.Field()
height = objectfactory.Field()

def get_area( self ):
def get_area(self):
return 0.5 * self.base * self.height

serialized_data = [
Expand All @@ -40,8 +40,8 @@ serialized_data = [
]

for data in serialized_data:
shape = objectfactory.create( data )
print( 'class type: {}, shape area: {}'.format( type( shape ), shape.get_area() ) )
shape = objectfactory.create(data)
print('class type: {}, shape area: {}'.format(type(shape), shape.get_area()))
```

Output:
Expand All @@ -52,7 +52,7 @@ class type: <class '__main__.Square'>, shape area: 2.25
```

### More examples
See more advanced examples [here](examples)
See more advanced examples [here](https://github.com/devinaconley/py-object-factory/tree/develop/examples)

## Install
Use [pip](https://pip.pypa.io/en/stable/installing/) for installation
Expand Down
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

# project info
project = 'objectfactory'
copyright = '2018-2021, Devin A. Conley'
copyright = '2018-2023, Devin A. Conley'
author = 'Devin A. Conley'
release = '0.1.0'
release = '0.1.1'

# config
extensions = [
Expand Down
1 change: 0 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ objectfactory

.. toctree::
:maxdepth: 2
:caption: Contents:

quickstart
objectfactory
Expand Down
30 changes: 15 additions & 15 deletions examples/custom_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def main():
# load and validate each contact
for c in contacts:
try:
contact = objectfactory.create( c, object_type=Contact )
contact = objectfactory.create(c, object_type=Contact)
print(
'Loaded contact for: {} {}, number: {}, email: {}'.format(
contact.first_name,
Expand All @@ -46,29 +46,29 @@ def main():
)
)
except marshmallow.ValidationError as e:
print( 'Validation error: {}'.format( e ) )
print('Validation error: {}'.format(e))


class PhoneNumber( marshmallow.fields.Field ):
class PhoneNumber(marshmallow.fields.Field):
"""Custom marshmallow field to validate phone number"""

def _deserialize( self, value, *args, **kwargs ):
def _deserialize(self, value, *args, **kwargs):
try:
x = value.split( '-' )
assert len( x ) == 3
assert len( x[0] ) == 3
assert len( x[1] ) == 3
assert len( x[2] ) == 4
return str( value )
x = value.split('-')
assert len(x) == 3
assert len(x[0]) == 3
assert len(x[1]) == 3
assert len(x[2]) == 4
return str(value)

except AssertionError as e:
raise marshmallow.ValidationError( 'Invalid phone number' )
raise marshmallow.ValidationError('Invalid phone number')

def _serialize( self, value, *args, **kwargs ):
return str( value )
def _serialize(self, value, *args, **kwargs):
return str(value)


class ContactSchema( marshmallow.Schema ):
class ContactSchema(marshmallow.Schema):
"""Custom marshmallow schema for contact info"""

first_name = marshmallow.fields.Str()
Expand All @@ -78,7 +78,7 @@ class ContactSchema( marshmallow.Schema ):


@objectfactory.register
class Contact( objectfactory.Serializable, schema=ContactSchema ):
class Contact(objectfactory.Serializable, schema=ContactSchema):
"""
product order from a dollar store vendor
"""
Expand Down
50 changes: 25 additions & 25 deletions examples/product_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,76 +26,76 @@ def main():
]

# deserialize raw product order
products = [objectfactory.create( order, object_type=Product ) for order in raw_orders]
products = [objectfactory.create(order, object_type=Product) for order in raw_orders]

# calculate overall price
price = sum( [prod.get_price() * prod.quantity for prod in products] )
print( 'Overall order price: ${}'.format( price ) )
price = sum([prod.get_price() * prod.quantity for prod in products])
print('Overall order price: ${}'.format(price))

# estimate delivery
days = max( [prod.get_delivery_time() for prod in products] )
print( 'Estimated delivery time is: {} days'.format( days ) )
days = max([prod.get_delivery_time() for prod in products])
print('Estimated delivery time is: {} days'.format(days))

# validate stocking
in_stock = all( [prod.quantity < prod.get_quantity_in_stock() for prod in products] )
print( 'Products are {}stocked'.format( '' if in_stock else 'not ' ) )
in_stock = all([prod.quantity < prod.get_quantity_in_stock() for prod in products])
print('Products are {}stocked'.format('' if in_stock else 'not '))


class Product( objectfactory.Serializable ):
class Product(objectfactory.Serializable):
"""
base abstract class for our products
"""
product_id = objectfactory.String() # all products will have an id
quantity = objectfactory.Integer( default=1 ) # all products will have a quantity
quantity = objectfactory.Integer(default=1) # all products will have a quantity

def get_price( self ) -> float:
def get_price(self) -> float:
"""
abstract method to calculate price and return
:return: float
"""
raise NotImplementedError( 'get_price method is required' )
raise NotImplementedError('get_price method is required')

def get_delivery_time( self ) -> int:
def get_delivery_time(self) -> int:
"""
abstract method to get required delivery time
:return:
"""
raise NotImplementedError( 'get_delivery_time method is required' )
raise NotImplementedError('get_delivery_time method is required')

def get_quantity_in_stock( self ) -> int:
def get_quantity_in_stock(self) -> int:
"""
abstract method to get quantity in stock
:return:
"""
raise NotImplementedError( 'get_quantity_in_stock method is required' )
raise NotImplementedError('get_quantity_in_stock method is required')


@objectfactory.register
class DollarStoreProduct( Product ):
class DollarStoreProduct(Product):
"""
product order from a dollar store vendor
"""

def get_price( self ) -> float:
def get_price(self) -> float:
"""
everything is a dollar!!!!
:return:
"""
return 1.00

def get_delivery_time( self ) -> int:
def get_delivery_time(self) -> int:
"""
everything takes about a week to ship
:return:
"""
return 7

def get_quantity_in_stock( self ) -> int:
def get_quantity_in_stock(self) -> int:
"""
mock connection to this vendor's supply data
Expand All @@ -105,16 +105,16 @@ def get_quantity_in_stock( self ) -> int:
'greeting_card': 300,
'candle': 15,
'glass_vase': 10
}.get( self.product_id, 0 )
}.get(self.product_id, 0)


@objectfactory.register
class EcommerceGiantProduct( Product ):
class EcommerceGiantProduct(Product):
"""
product order from an e-commerce giant
"""

def get_price( self ) -> float:
def get_price(self) -> float:
"""
mock connection to this vendor's # data
Expand All @@ -125,17 +125,17 @@ def get_price( self ) -> float:
'tv': 450,
'digital_clock': 10,
'virtual_assistant': 50
}.get( self.product_id, None )
}.get(self.product_id, None)

def get_delivery_time( self ) -> int:
def get_delivery_time(self) -> int:
"""
guaranteed 2-day delivery
:return:
"""
return 2

def get_quantity_in_stock( self ) -> int:
def get_quantity_in_stock(self) -> int:
"""
infinite supplies
Expand Down
12 changes: 6 additions & 6 deletions examples/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ def main():

# load each shape, printing object type and area
for data in serialized_data:
shape = objectfactory.create( data )
print( 'class type: {}, shape area: {}'.format( type( shape ), shape.get_area() ) )
shape = objectfactory.create(data)
print('class type: {}, shape area: {}'.format(type(shape), shape.get_area()))


@objectfactory.register
class Square( objectfactory.Serializable ):
class Square(objectfactory.Serializable):
"""
serializable square class
"""
side = objectfactory.Float()

def get_area( self ) -> float:
def get_area(self) -> float:
"""
calculate area of square
Expand All @@ -37,14 +37,14 @@ def get_area( self ) -> float:


@objectfactory.register
class Triangle( objectfactory.Serializable ):
class Triangle(objectfactory.Serializable):
"""
serializable triangle class
"""
base = objectfactory.Float()
height = objectfactory.Float()

def get_area( self ) -> float:
def get_area(self) -> float:
"""
calculate area of triangle
Expand Down
16 changes: 8 additions & 8 deletions objectfactory/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from abc import ABC, abstractmethod


class FieldABC( ABC ):
class FieldABC(ABC):
"""
abstract base class for serializable field
"""

def __init__( self, default=None, key=None, required=False, allow_none=True ):
def __init__(self, default=None, key=None, required=False, allow_none=True):
"""
:param default: default value for field if unset
:param key: dictionary key to use for field serialization
Expand All @@ -26,15 +26,15 @@ def __init__( self, default=None, key=None, required=False, allow_none=True ):
self._allow_none = allow_none

@abstractmethod
def __get__( self, instance, owner ):
def __get__(self, instance, owner):
pass

@abstractmethod
def __set__( self, instance, value ):
def __set__(self, instance, value):
pass

@abstractmethod
def marshmallow( self ):
def marshmallow(self):
"""
create generic marshmallow field to do actual serialization
Expand All @@ -43,13 +43,13 @@ def marshmallow( self ):
pass


class SerializableABC( ABC ):
class SerializableABC(ABC):
"""
abstract base class for serializable object
"""

@abstractmethod
def serialize( self, include_type: bool = True, use_full_type: bool = True ) -> dict:
def serialize(self, include_type: bool = True, use_full_type: bool = True) -> dict:
"""
serialize model to dictionary
Expand All @@ -60,7 +60,7 @@ def serialize( self, include_type: bool = True, use_full_type: bool = True ) ->
pass

@abstractmethod
def deserialize( self, body: dict ):
def deserialize(self, body: dict):
"""
deserialize model from dictionary
Expand Down
Loading

0 comments on commit 35a7bc0

Please # to comment.