{"id":13770547,"url":"https://github.com/neithere/monk","last_synced_at":"2026-01-10T19:34:47.473Z","repository":{"id":10124389,"uuid":"12194481","full_name":"neithere/monk","owner":"neithere","description":"An unobtrusive data modeling, manipulation and validation library.","archived":false,"fork":false,"pushed_at":"2015-10-11T21:51:18.000Z","size":1110,"stargazers_count":13,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-26T17:47:54.735Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://monk.rtfd.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"lincanbin/Sina-Weibo-Album-Downloader","license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neithere.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-08-18T11:44:22.000Z","updated_at":"2025-03-17T09:22:35.000Z","dependencies_parsed_at":"2022-09-05T06:01:47.070Z","dependency_job_id":null,"html_url":"https://github.com/neithere/monk","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neithere%2Fmonk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neithere%2Fmonk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neithere%2Fmonk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neithere%2Fmonk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neithere","download_url":"https://codeload.github.com/neithere/monk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253514352,"owners_count":21920327,"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:38.952Z","updated_at":"2025-05-11T03:32:48.545Z","avatar_url":"https://github.com/neithere.png","language":"Python","readme":"~~~~\nMonk\n~~~~\n\n.. image:: https://img.shields.io/coveralls/neithere/monk.svg\n    :target: https://coveralls.io/r/neithere/monk\n\n.. image:: https://img.shields.io/travis/neithere/monk.svg\n    :target: https://travis-ci.org/neithere/monk\n\n.. image:: https://img.shields.io/pypi/format/monk.svg\n    :target: https://pypi.python.org/pypi/monk\n\n.. image:: https://img.shields.io/pypi/status/monk.svg\n    :target: https://pypi.python.org/pypi/monk\n\n.. image:: https://img.shields.io/pypi/v/monk.svg\n    :target: https://pypi.python.org/pypi/monk\n\n.. image:: https://img.shields.io/pypi/pyversions/monk.svg\n    :target: https://pypi.python.org/pypi/monk\n\n.. image:: https://img.shields.io/pypi/dd/monk.svg\n    :target: https://pypi.python.org/pypi/monk\n\nAn unobtrusive data modeling, manipulation and validation library.\n\nSupports MongoDB out of the box. Can be used for any other DB (or even without one).\n\nInstallation\n------------\n\n    $  pip install monk\n\nDependencies\n------------\n\n`Monk` is tested against the following versions of Python:\n\n* CPython 2.6, 2.7, 3.2, 3.5\n* PyPy 2.0\n\nOptional dependencies:\n\n* The MongoDB extension requires `pymongo` ≥ 3.0 (older may work too).\n\nDocumentation\n-------------\n\nSee the complete `documentation`_ for details.\n\nExamples\n--------\n\nModeling\n........\n\nThe schema is defined as a template using native Python data types:\n\n.. code-block:: python\n\n    # we will reuse this structure in examples below\n\n    spec = {\n        'title': 'Untitled',\n        'comments': [\n            {\n                'author': str,\n                'date': datetime.datetime.utcnow,\n                'text': str\n            }\n        ],\n    }\n\nYou are free to design as complex a document as you need.\nThe `manipulation` and `validation` functions (described below) support\narbitrary nested structures.\n\nWhen this \"natural\" pythonic approach is not sufficient, you can mix it with\na more verbose notation, e.g.:\n\n.. code-block:: python\n\n    title_spec = IsA(str, default='Untitled') | Equals(None)\n\nThere are also neat shortcuts:\n\n.. code-block:: python\n\n    spec = {\n        'url': nullable(str),\n        'status': one_of(['new', 'in progress', 'closed']),\n        'comments': [str],\n        'blob': None,\n    }\n\nThis could be written a bit more verbosely:\n\n.. code-block:: python\n\n    spec = {\n        'url': IsA(str) | Equals(None),\n        'status': Equals('new') | Equals('in progress') | Equals('closed'),\n        'comments': ListOf(IsA(str)),\n        'blob': Anything(),\n    }\n\nIt is even possible to define schemata for dictionary keys:\n\n.. code-block:: python\n\n    CATEGORIES = ['books', 'films', 'toys']\n    spec = {\n        'title': str,\n        opt_key('price'): float,    # key is optional; value is mandatory\n        'similar_items': {\n            one_of(CATEGORIES): [    # suggestions grouped by category\n                {'url': str, 'title': str}\n            ],\n        }\n    }\n\n    # (what if the categories should be populated dynamically?\n    #  well, the schema is plain Python data, just copy/update on the fly.)\n\nAnd, yes, you can mix notations.  See FAQ.\n\nThis very short intro shows that Monk requires almost **zero learning to\nstart** and then provides very **powerful tools when you need them**;\nyou won't have to rewrite the \"intuitive\" code, only augment complexity\nexactly in places where it's inevitable.\n\nValidation\n..........\n\nThe schema can be used to ensure that the document has correct structure\nand the values are of correct types.\n\n.. code-block:: python\n\n    from monk.validation import validate\n\n    # correct data: staying silent\n\n    \u003e\u003e\u003e validate(spec, data)\n\n    # a key is missing\n\n    \u003e\u003e\u003e validate(spec, {'title': 'Hello'})\n    Traceback (most recent call last):\n       ...\n    MissingKeys: must have keys: 'comments'\n\n    # a key is missing in a dictionary in a nested list\n\n    \u003e\u003e\u003e validate(spec, {'comments': [{'author': 'john'}]}\n    Traceback (most recent call last):\n       ...\n    DictValueError: 'comments' value item #0: must have keys: 'text', 'date'\n\n\n    # type check; also works with functions and methods (by return value)\n\n    \u003e\u003e\u003e validate(spec, {'title': 123, 'comments': []})\n    Traceback (most recent call last):\n        ...\n    DictValueError: 'title' value must be str\n\nCustom validators can be used.  Behaviour can be fine-tuned.\n\nThe `validate()` function translates the \"natural\" notation to a validator\nobject under the hood.  To improve performance you can \"compile\" the validator\nonce (using `translate()` function or by creating a validator instance in place)\nand use it multiple times to validate different values:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from monk import *\n    \u003e\u003e\u003e translate(str) == IsA(str)\n    True\n    \u003e\u003e\u003e validator = IsA(str) | IsA(int)\n    \u003e\u003e\u003e validator('hello')\n    \u003e\u003e\u003e validator(123)\n    \u003e\u003e\u003e validator(5.5)\n    Traceback (most recent call last):\n        ...\n    AllFailed: must be str or must be int\n\nManipulation\n............\n\nThe same schema can be used to create full documents from incomplete data.\n\n.. code-block:: python\n\n    from monk import merge_defaults\n\n    # default values are set for missing keys\n\n    \u003e\u003e\u003e merge_defaults(spec, {})\n    {\n        'title': 'Untitled',\n        'comments': [],\n    }\n\n    # it's easy to override the defaults\n\n    \u003e\u003e\u003e merge_defaults(spec, {'title': 'Hello'})\n    {\n        'title': 'Hello',\n        'comments': [],\n    }\n\n    # nested lists of dictionaries can be auto-filled, too.\n    # by the way, note the date.\n\n    \u003e\u003e\u003e merge_defaults(spec, {'comments': [{'author': 'john'}]})\n    {\n        'title': 'Untitled',\n        'comments': [\n            {\n                'author': 'john',\n                'date': datetime.datetime(2013, 3, 3, 1, 8, 4, 152113),\n                'text': None,\n            }\n        ]\n    }\n\nObject-Document Mapping\n-----------------------\n\nThe library can be also viewed as a framework for building ODMs\n(object-document mappers).  See the MongoDB extension and note how it reuses\nmixins provided by DB-agnostic modules.\n\nHere's an example of the MongoDB ODM bundled with Monk:\n\n.. code-block:: python\n\n    from monk.mongo import Document\n\n    class Item(Document):\n        structure = {\n            'text': unicode,\n            'slug': unicode,\n        }\n        indexes = {\n            'text': None,\n            'slug': {'unique': True},\n        }\n\n    # this involves manipulation (inserting missing fields)\n    item = Item(text=u'foo', slug=u'bar')\n\n    # this involves validation\n    item.save(db)\n\nLinks\n-----\n\n* `Project home page`_ (Github)\n* `Documentation`_ (Read the Docs)\n* `Package distribution`_ (PyPI)\n* Questions, requests, bug reports, etc.:\n\n  * `Issue tracker`_\n  * Direct e-mail (neithere at gmail com)\n\n.. _project home page: http://github.com/neithere/monk/\n.. _documentation: http://monk.readthedocs.org\n.. _package distribution: http://pypi.python.org/pypi/monk\n.. _issue tracker: http://github.com/neithere/monk/issues/\n\nAuthor\n------\n\nOriginally written by Andrey Mikhaylenko since 2011.\n\nPlease feel free to submit patches, report bugs or request features:\n\n    http://github.com/neithere/monk/issues/\n\nLicensing\n---------\n\nMonk is free software: you can redistribute it and/or modify\nit under the terms of the GNU Lesser General Public License as published\nby the Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nMonk is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License\nalong with Monk.  If not, see \u003chttp://gnu.org/licenses/\u003e.\n","funding_links":[],"categories":["Python","Model, Schema"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneithere%2Fmonk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneithere%2Fmonk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneithere%2Fmonk/lists"}