{"id":13770990,"url":"https://github.com/afriemann/simple_model","last_synced_at":"2025-04-15T08:42:04.876Z","repository":{"id":57467521,"uuid":"73867617","full_name":"AFriemann/simple_model","owner":"AFriemann","description":"a very simple model framework for python.","archived":false,"fork":false,"pushed_at":"2018-06-24T11:24:22.000Z","size":106,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-12T13:16:02.509Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AFriemann.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-16T00:25:50.000Z","updated_at":"2019-04-15T13:10:36.000Z","dependencies_parsed_at":"2022-09-19T08:51:08.038Z","dependency_job_id":null,"html_url":"https://github.com/AFriemann/simple_model","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFriemann%2Fsimple_model","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFriemann%2Fsimple_model/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFriemann%2Fsimple_model/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFriemann%2Fsimple_model/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AFriemann","download_url":"https://codeload.github.com/AFriemann/simple_model/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249038887,"owners_count":21202803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T17:00:46.071Z","updated_at":"2025-04-15T08:42:04.858Z","avatar_url":"https://github.com/AFriemann.png","language":"Python","readme":"simple_model\n============\n\n.. image:: https://travis-ci.org/AFriemann/simple_model.svg?branch=master\n    :target: https://travis-ci.org/AFriemann/simple_model\n.. image:: https://badge.fury.io/py/simple_model.svg\n    :target: https://badge.fury.io/py/simple_model\n\nAs the name suggests, this is a very simple model framework. It can be used for data\nvalidation and (de-)serialization.\n\n**New** Head over to `v2 \u003chttps://github.com/AFriemann/simple_model/blob/master/README.v2.rst\u003e`_ now!\n\nInstallation\n------------\n\nInstall with pip::\n\n    $ pip install --user simple_model\n\nUsage\n-----\n\nThis allows me to test the examples by taking care of sorting the dictionaries, it is not required for simple_model\nto work:\n\n.. code:: python\n\n    \u003e\u003e\u003e from pprint import pprint\n\nExamples:\n\n.. code:: python\n\n    \u003e\u003e\u003e from simple_model import Model, Attribute\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     name = Attribute(str)\n    ...     some_value = Attribute(str, optional=True)\n    ...     another_value = Attribute(int, fallback=0)\n\n    \u003e\u003e\u003e pprint(dict(Data(name = 'test', some_value = None, another_value = 12)))\n    {'another_value': 12, 'name': 'test', 'some_value': None}\n\n    \u003e\u003e\u003e pprint(dict(Data(name = 'test')))\n    {'another_value': 0, 'name': 'test', 'some_value': None}\n\n    \u003e\u003e\u003e init_dict = {'name': 'test', 'some_value': 'val', 'another_value': 3}\n    \u003e\u003e\u003e pprint(dict(Data(**init_dict)))\n    {'another_value': 3, 'name': 'test', 'some_value': 'val'}\n\nInitializing with missing attributes while not specifying them as optional or providing a fallback value\nwill result in a *ValueError* containing all failed attributes.\nNote that *fallback* takes precedence over *optional*, specifying both is unnecessary.\n\nUnknown values will be ignored\n\n.. code:: python\n\n    \u003e\u003e\u003e pprint(dict(Data(name = 'test', unknown_value = True)))\n    {'another_value': 0, 'name': 'test', 'some_value': None}\n\n\nSerialization can be achieved easily, for example\n\n.. code:: python\n\n    \u003e\u003e\u003e import json\n    \u003e\u003e\u003e def serialize(model):\n    ...     return json.dumps(dict(model))\n\n    \u003e\u003e\u003e def deserialize(string):\n    ...     return Data(**json.loads(string))\n\nSince the Model class simply calls the Attribute class for each parameter and the Attribute class in turn calls the\ngiven 'type', one could easily use functions instead of types to achieve more complex results and value parsing\n\n.. code:: python\n\n    \u003e\u003e\u003e from datetime import datetime\n    \u003e\u003e\u003e def parse_date(string):\n    ...     return datetime.strptime(string, '%Y-%m-%d')\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     date = Attribute(parse_date)\n\n    \u003e\u003e\u003e dict(Data(date='2015-11-20'))\n    {'date': datetime.datetime(2015, 11, 20, 0, 0)}\n\nFallback values can also be given as functions\n\n.. code:: python\n\n    \u003e\u003e\u003e def fun():\n    ...     return \"foo\"\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     point = Attribute(str, fallback=fun)\n\n    \u003e\u003e\u003e dict(Data())\n    {'point': 'foo'}\n\nIf you need to verify Lists of objects, use functions\n\n.. code:: python\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     points = Attribute(lambda l: list(map(str, l)))\n\n    \u003e\u003e\u003e dict(Data(points=['abc', 'def', 'ghi']))\n    {'points': ['abc', 'def', 'ghi']}\n\nOr the included *list_type* helper class\n\n.. code:: python\n\n    \u003e\u003e\u003e from simple_model.helpers import list_type\n    \u003e\u003e\u003e class Data(Model):\n    ...     points = Attribute(list_type(str))\n\n    \u003e\u003e\u003e dict(Data(points=['abc', 'def', 'ghi']))\n    {'points': ['abc', 'def', 'ghi']}\n\nFor more complex data, use Models to verify\n\n.. code:: python\n\n     \u003e\u003e\u003e class SubData(Model):\n     ...     some_value = Attribute(str)\n     ...     some_other_value = Attribute(int)\n\n     \u003e\u003e\u003e class Data(Model):\n     ...     point = Attribute(SubData)\n\n     \u003e\u003e\u003e pprint(dict(Data(point={'some_value': 'abc', 'some_other_value': 12})))\n     {'point': {'some_other_value': 12, 'some_value': 'abc'}}\n\nTo allow uncommon names, use the Attribute name keyword\n\n.. code:: python\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     point = Attribute(str, name='@point')\n\n    \u003e\u003e\u003e dict(Data(point='something'))\n    {'@point': 'something'}\n\n    \u003e\u003e\u003e dict(Data(**{ '@point': 'something' }))\n    {'@point': 'something'}\n\nTo easily check against expected values you can use the helper function *one_of*\n\n.. code:: python\n\n    \u003e\u003e\u003e from simple_model.helpers import one_of\n    \u003e\u003e\u003e class Data(Model):\n    ...     foo = Attribute(one_of('bar', 'foobar'))\n\n    \u003e\u003e\u003e dict(Data(foo='bar'))\n    {'foo': 'bar'}\n\n    \u003e\u003e\u003e dict(Data(foo='foo')) # doctest: +ELLIPSIS\n    Traceback (most recent call last):\n        ...\n    ValueError: {...'exception': \"ValueError: must be one of ('bar', 'foobar') but was 'foo'\"...}\n\nIf you want to disallow unknown values, set the __ignore_unknown__ attribute to False\n\n.. code:: python\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     __ignore_unknown__ = False\n    ...\n    ...     point = Attribute(str)\n\n    \u003e\u003e\u003e Data(point = 'abc', other = 'def')\n    Traceback (most recent call last):\n        ...\n    ValueError: Unknown key \"other\" with value \"def\"\n\nYou can now set Models to be mutable and change Attribute values after creation\n\n.. code:: python\n\n    \u003e\u003e\u003e class Data(Model):\n    ...     point = Attribute(int)\n\n    \u003e\u003e\u003e d = Data(point = 1)\n    \u003e\u003e\u003e d.point\n    1\n    \u003e\u003e\u003e d.point = 2\n    \u003e\u003e\u003e d.point\n    2\n    \u003e\u003e\u003e d.__mutable__ = False\n    \u003e\u003e\u003e d.point = 3\n    Traceback (most recent call last):\n        ...\n    AttributeError: Model is immutable\n\nTests\n-----\n\nTo run the tests use tox::\n\n    $ tox\n\nIssues\n------\n\nPlease submit any issues on `GitHub \u003chttps://github.com/afriemann/simple_model/issues\u003e`_.\n\nChangelog\n---------\n\nsee `CHANGELOG \u003chttps://github.com/AFriemann/simple_model/blob/master/CHANGELOG.rst\u003e`_\n\nLicense\n-------\n\nsee `LICENSE \u003chttps://github.com/AFriemann/simple_model/blob/master/LICENSE.txt\u003e`_\n","funding_links":[],"categories":["Model, Schema"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafriemann%2Fsimple_model","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafriemann%2Fsimple_model","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafriemann%2Fsimple_model/lists"}