Package: middle
Flexible, extensible Python data structures for general usage. Get data in and out, reliably, without boilerplate and with speed!middlestands on the shoulders ofattrsand aims to be as simple as possible to get data from complex objects to Python primitives and vice-versa, with validators, converters, a lot of sugar and other utilities!middlecan be used with your preferred web framework, background job application, configuration parser and more!Sneak peekThe most simple example ofmiddleand some of its features (using Python 3.6+ syntax):>>>importtyping>>>importmiddle>>>classAddress(middle.Model):...street_name:str...number:typing.Optional[int]...city:str>>>classPerson(middle.Model):...name:str...age:int...address:typing.Dict[str,Address]>>>data={..."name":"John Doe",..."age":42,..."address":{..."home":{..."street_name":"Foo St",..."number":None,..."city":"Python Park"...},..."work":{..."street_name":"Bar Blvd",..."number":"1337",..."city":"Park City"...}...}...}>>>person=Person(data)>>>personPerson(name='John Doe', age=42, address={'home': Address(street_name='Foo St', number=None, city='Python Park'), 'work': Address(street_name='Bar Blvd', number=1337, city='Park City')})>>>middle.asdict(person){'name': 'John Doe', 'age': 42, 'address': {'home': {'street_name': 'Foo St', 'number': None, 'city': 'Python Park'}, 'work': {'street_name': 'Bar Blvd', 'number': 1337, 'city': 'Park City'}}}Wanted a more complex example, with Python 3.5 compatible syntax? For sure!>>>fromtypingimportDict,List>>>importmiddle>>>classGame(middle.Model):...name:str=middle.field()...score:float=middle.field(minimum=0,maximum=10)...resolution_tested:str=middle.field(pattern="^\d+x\d+$")...genre:List[str]=middle.field(unique_items=True)...rating:Dict[str,float]=middle.field(max_properties=5)>>>data={..."name":"Cities: Skylines",..."score":9.0,..."resolution_tested":"1920x1200",..."genre":["Simulators","City Building"],..."rating":{..."IGN":8.5,..."Gamespot":8.0,..."Steam":4.5...}...}>>>game=Game(**data)>>>gameGame(name='Cities: Skylines', score=9.0, resolution_tested='1920x1200', genre=['Simulators', 'City Building'], rating={'IGN': 8.5, 'Gamespot': 8.0, 'Steam': 4.5})>>>middle.asdict(game){'name': 'Cities: Skylines', 'score': 9.0, 'resolution_tested': '1920x1200', 'genre': ['Simulators', 'City Building'], 'rating': {'IGN': 8.5, 'Gamespot': 8.0, 'Steam': 4.5}}middleis flexible enough to understandEnum, nested models and a large variety of types declared on thetypingmodule out of the box. Also, you canextend itto your own classes!WarningIMPORTANT:middleis invery early stagesof development. There are some requirements (likepython-dateutil) that would not be required in future releases; as there’s a lot of functionalities that needs to be implemented and some known misbehaviors to be addressed, not to mention it needs a lot of testing before moving to any other status rather thanalpha.TODOAlias options (keys) to populate classes;Read-only and write-only fields;Better error handling (almost everywhere);Create a benchmark suite against other solutions;Formatters are still missing;Possibility to “cast” an instance to another instance where the original object is a subclass of it;DoneIf possible, fine grain the converters, so astrinput value of{}doesn’t end up asstr({});Getdateanddatetimeconverters to be customizable, instead of anif isinstancestatement;Implement more validators and a registerable for more metadata options;Implement a better “type dispatcher” based on more complex rules (other thantype(field.type)delivered byfunctools.singledispatch) because thetypingmodule has changeda bitbetween Python 3.6 and 3.7;Support more types (typing.Tuple,decimal.Decimal);Get 100% (or closer) in code coverage;Lots of documentation;Python 3.5 support (with the exception of Windows platforms, see warning for Windows developers below);Future discussionsIn Python 3.7, a neat feature was added:dataclasses. I know it sounds really awesome to not depend on a 3rd-party library - such asattrs, but the latest provides a lot of functionalities that can’t be found on Python 3.7dataclasses(for now), so I’ll leave this open for further discussion.Warning for Windows developersIf you’re using Windows and Python 3.5, I thinkmiddlewould not work well for you. CI in AppVeyor was disabled for Python 3.5 because ofthis issue. If Guido doesn’t care, why should I (or you) ?Documentationhttps://middle.readthedocs.io/en/latest/Useful linksSource codeIssuesInspirations and thanksSome libs that inspired the creation ofmiddle:attrs: how such a simple library can be such flexible, extendable and fast?cattrs: for its speed on creatingattrsinstances fromdictand to instances again;pydantic: for such pythonic and beautiful approach on creating classes usingtypinghints;mashmallow: it is one of the most feature rich modelling APIs I’ve seen;apistar: it’s almost magical!Sanic: “Gotta go fast!”ionelmc/cookiecutter-pylibrary: The most complete (or interesting)cookiecuttertemplate I found so far (make sure toread this articletoo);Licensemiddleis a free software distributed under theMITlicense.Changelogv0.2.2 on 2018-10-28Added the possibility for models to have methods, functions, properties and etc.v0.2.1 on 2018-07-26Quick fix related to the change log and MANIFEST.in filesv0.2.0 on 2018-07-26Released (part) of the documentationGot 99% coverage (finally combined)Python 3.5 support addedv0.1.1 on 2018-07-02Add proper unit testing and support for Python 3.6 and 3.7Made the API a bit more flexibleCode format and check done withblackv0.1.0 on 2018-06-21First release on PyPI.