{ "info": { "author": "Denis Lisovik", "author_email": "cyberlis@rccraft.ru", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "\nDictQuery\n========================\n\nLibrary to query python dicts\n\n\nSeveral syntax examples:\n\n```\n\"age >= 12\"\n\"`user.name` == 'cyberlis'\"\n\"`user.email` MATCH /\\w+@\\w+\\.com/ AND age != 11\"\n\"`user.friends.age` > 12 AND `user.friends.name` LIKE 'Ra*ond'\"\n\"email LIKE 'mariondelgado?bleendot?com'\"\n\"eyeColor IN ['blue', 'green', 'black']\"\n\"isActive AND (gender == 'female' OR age == 27)\"\n\"latitude != longitude\"\n```\n\nSupported data types\n====================\n| type | example |\n|-----------|---------|\n| KEY | name, age, \\`friends.name.firstname\\`, \\`friends.age\\` |\n| NUMBER | 42, -12, 34.7 |\n| STRING | 'hello', \"hellow\" |\n| BOOLEAN | true, false |\n| NONE | none, null |\n| NOW | utc current datetime |\n| REGEXP | /\\d+\\d+\\w+/ |\n| ARRAY | list of any items and any types |\n\n\nKeys\n===========\nKey literals must start with a letter or an underscore, such as:\n * `_underscore`\n * `underscore_`\n\nThe remainder of your variable name may consist of letters, numbers and underscores.\n * `password1`\n * `n00b`\n * `un_der_scores`\n\nIf you need a key with separator character (`.` or `/`) because you use nested keys, or need spaces or other punctuation characters in key, use back-ticks (\\`\\`)\n\nDictQuery supports nested dicts splited by dot `.` or any separator specified in `key_separator` param. Default `key_separator='.'`\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"`friends.age` <= 26\")\nTrue\n>>> compiled = dq.compile(\"`friends/age` <= 26\", key_separator='/')\n>>> compiled.match(data)\nTrue\n```\n\nif you don't need nested keys parsing and want get keys as is or if your keys contain separator char, you can disable nested keys behaviour by setting `use_nested_keys=False`\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"`user.address`\")\nFalse\n>>> dq.match(data, \"age\")\nTrue\n>>> compiled = dq.compile(\"`user.address`\", use_nested_keys=False)\n>>> compiled.match(data)\nTrue\n```\n\nIn query you can use dict keys 'as is' without any binary operation. DictQuery will get value by the key and evaluate it to bool\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"isActive\")\nFalse\n>>> dq.match(data, \"isActive == false\")\nTrue\n```\n\nif key is not found by default this situation evaluates to boolean `False` (no exception raised).\nYou can set `raise_keyerror=True` to raise keyerror if key would not be found.\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"favoriteFruit\")\nFalse\n>>> compiled = dq.compile(\"`favoriteFruit`\", raise_keyerror=True)\n>>> compiled.match(data)\nTraceback (most recent call last):\n File \"\", line 1, in \n File \".../dictquery/dictquery/visitors.py\", line 41, in match\n return self.evaluate(data)\n File \".../dictquery/dictquery/visitors.py\", line 35, in evaluate\n result = bool(self.ast.accept(self))\n File \".../dictquery/dictquery/parsers.py\", line 80, in accept\n return visitor.visit_key(self)\n File \".../dictquery/dictquery/visitors.py\", line 84, in visit_key\n values=self._get_dict_value(expr.value),\n File \".../dictquery/dictquery/visitors.py\", line 30, in _get_dict_value\n self.key_separator, self.raise_keyerror)\n File \".../dictquery/dictquery/datavalue.py\", line 112, in query_value\n raise DQKeyError(\"Key '{}' not found\".format(data_key))\ndictquery.exceptions.DQKeyError: \"Key 'favoriteFruit' not found\"\n\n```\n\nComparisons\n===========\n\n\n| Operation | Meaning |\n|-----------|---------|\n| < | strictly less than |\n| <= | less than or equal |\n| > | strictly greater than |\n| >= | greater than or equal |\n| == | equal |\n| != | not equal |\n\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"age == 26\")\nTrue\n>>> dq.match(data, \"latitude > 12\")\nTrue\n>>> dq.match(data, \"longitude < 30\")\nTrue\n>>> dq.match(data, \"`friends.age` <= 26\")\nTrue\n>>> dq.match(data, \"longitude >= -130\")\nTrue\n>>> dq.match(data, \"id != 0\")\nTrue\n>>> dq.match(data, \"gender == 'male'\")\nFalse\n```\n\nString comparisons and matching\n===============================\n\nString literals are written in a variety of ways:\n* Single quotes: 'allows embedded \"double\" quotes'\n* Double quotes: \"allows embedded 'single' quotes\".\n\n| Operation | Meaning |\n|-----------|---------|\n| MATCH | regexp matching |\n| LIKE | glob like matching |\n| IN | dict item substring in string |\n| CONTAINS | dict item substring contains string |\n\n< , <= , > , >= , == , != works same way with strings as python\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"eyeColor == 'green'\")\nTrue\n>>> dq.match(data, \"`name.firstname` != 'Ratliff'\")\nTrue\n>>> dq.match(data, \"eyeColor IN 'string with green color'\")\nTrue\n>>> dq.match(data, \"email CONTAINS '.com'\")\nTrue\n>>> dq.match(data, r\"email MATCH /\\w+@\\w+\\.\\w+/\")\nTrue\n>>> dq.match(data, r\"email LIKE 'mariondelgado@*'\")\nTrue\n>>> dq.match(data, r\"email LIKE 'mariondelgado?bleendot?com'\")\nTrue\n```\n\nBy default all string related operations are case sensitive. To change this behaviour you have to create instance of DictQuery with `case_sensitive=False`\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"`name.firstname` == 'marion'\")\nFalse\n>>> compiled = dq.compile(\"`name.firstname` == 'marion'\", case_sensitive=False)\n>>> compiled.match(data)\nTrue\n```\n\nArray comparisons\n=================\n| Operation | Meaning |\n|-----------|---------|\n| IN | dict item in array |\n| CONTAINS | dict item contains matching item |\n\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"tags CONTAINS 'dolor'\")\nTrue\n>>> dq.match(data, \"eyeColor IN ['blue', 'green', 'black']\")\nTrue\n```\n\nKey presence in dict\n=====================\n`CONTAINS` can be used with dict items to check if key in dict\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"name CONTAINS 'firstname'\")\nTrue\n>>> dq.match(data, \"name CONTAINS 'thirdname'\")\nFalse\n```\n\nDatetime comparisons with `NOW`\n===============================\n`NOW` returns current utc datetime\n\ndict item can be compared with `NOW` using standard operations (< , <= , > , >= , == , !=)\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"registered < NOW\")\nTrue\n>>> dq.match(data, \"registered != NOW\")\nTrue\n```\n\nLogical operators\n=================\n|Operator|\tMeaning|\tExample|\n|--------|---------|---------|\n|and\t|True if both the operands are true|\tx and y|\n|or\t|True if either of the operands is true|\tx or y|\n|not\t|True if operand is false (complements the operand)|\tnot x |\n\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"isActive AND gender == 'female'\")\nFalse\n>>> dq.match(data, \"isActive OR gender == 'female'\")\nTrue\n>>> dq.match(data, \"NOT isActive AND gender == 'female'\")\nTrue\n```\n\nYou can use parentheses to group statements or change evaluation order\n```\n>>> import dictquery as dq\n>>> dq.match(data, \"isActive AND gender == 'female' OR age == 27\")\nTrue\n>>> dq.match(data, \"isActive AND (gender == 'female' OR age == 27)\")\nFalse\n```\n\n\nData for examples above:\n=================\n\n\n```\nfrom datetime import datetime\ndata = {\n \"_id\": 10,\n \"isActive\": False,\n \"age\": 27,\n \"eyeColor\": \"green\",\n \"name\": {\n \"firstname\": \"Marion\",\n \"secondname\": \"Delgado\",\n },\n \"gender\": \"female\",\n \"email\": \"mariondelgado@bleendot.com\",\n \"registered\": datetime.strptime(\"2015-03-29T06:07:58\", \"%Y-%m-%dT%H:%M:%S\"),\n \"latitude\": 74.785608,\n \"longitude\": -112.366088,\n \"tags\": [\n \"voluptate\",\n \"ex\",\n \"dolor\",\n \"aute\"\n ],\n \"user.address\": \"155 Village Road, Enetai, Puerto Rico, 2634\",\n \"friends\": [\n {\n \"id\": 0,\n \"name\": {\n \"firstname\": \"Ratliff\",\n \"secondname\": \"Becker\",\n },\n \"age\": 27,\n \"eyeColor\": \"green\"\n },\n {\n \"id\": 1,\n \"name\": {\n \"firstname\": \"Raymond\",\n \"secondname\": \"Albert\",\n },\n \"age\": 19,\n \"eyeColor\": \"brown\"\n },\n {\n \"id\": 2,\n \"name\": {\n \"firstname\": \"Mavis\",\n \"secondname\": \"Sheppard\",\n },\n \"age\": 34,\n \"eyeColor\": \"blue\"\n }\n ]\n}\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cyberlis/dictquery", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "dictquery", "package_url": "https://pypi.org/project/dictquery/", "platform": "", "project_url": "https://pypi.org/project/dictquery/", "project_urls": { "Homepage": "https://github.com/cyberlis/dictquery" }, "release_url": "https://pypi.org/project/dictquery/0.4.0/", "requires_dist": null, "requires_python": "", "summary": "Library to query python dicts", "version": "0.4.0" }, "last_serial": 4450493, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9ea07a5fa9ce95be1bd9bcd93f308bb1", "sha256": "15b56f512da037e0ae502d2268dc2a3f93da391fb6df4607d0b7af5f7848ace7" }, "downloads": -1, "filename": "dictquery-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9ea07a5fa9ce95be1bd9bcd93f308bb1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9978, "upload_time": "2018-03-20T22:12:34", "url": "https://files.pythonhosted.org/packages/98/c2/f8742ede9b2e83fbfb911501ddc6b34561eb8055630d79590d1177708bbf/dictquery-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d947cd06abbb9d950cbe4ca586e4b3ab", "sha256": "4eab5045989c00c34554e9a3d162f012fa6260c3671f7f2cf50078ce5406d0c2" }, "downloads": -1, "filename": "dictquery-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d947cd06abbb9d950cbe4ca586e4b3ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11770, "upload_time": "2018-03-20T22:12:36", "url": "https://files.pythonhosted.org/packages/be/1e/e0389256b9c1c7962db16827b980685c3781b5f69d323b3bf11b6b404871/dictquery-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "a86ecf4c0cc15e662abf8cb3f3436fec", "sha256": "eab6cbc3c3a253f7be2284d2aeac3f4d1d71b83713d694a7ddbd484d21820b1b" }, "downloads": -1, "filename": "dictquery-0.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a86ecf4c0cc15e662abf8cb3f3436fec", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10463, "upload_time": "2018-03-26T22:50:47", "url": "https://files.pythonhosted.org/packages/05/47/ea24b587bb212dad3a7097c1c7e64a189743f36071440844cb0bd69bdcfc/dictquery-0.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8b4adc5c15b93242307edf36b725c3cd", "sha256": "6bfa0730aa0e22e2edd479805cda3a495efff82e749e93befc05ac22d12dffab" }, "downloads": -1, "filename": "dictquery-0.2.0.tar.gz", "has_sig": false, "md5_digest": "8b4adc5c15b93242307edf36b725c3cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12326, "upload_time": "2018-03-26T22:50:48", "url": "https://files.pythonhosted.org/packages/1a/1c/3ae11371e9953c56d6f6f4617f45467ad4f429335bde66e8a8822b7c276a/dictquery-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "30580a1f67fdd580f38ea20d772609c2", "sha256": "23badebe7d6acc15f20962ed5a916b9a52955495476ca0abd45ef2e774ec3286" }, "downloads": -1, "filename": "dictquery-0.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "30580a1f67fdd580f38ea20d772609c2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11036, "upload_time": "2018-10-30T22:15:55", "url": "https://files.pythonhosted.org/packages/61/15/e6843bcd091b0e26c2f2dd509032bfc71e66d07502d0e938ac7e1baed1c6/dictquery-0.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1b37727125911b4bd8b97366827b71dd", "sha256": "13169a713e25065fd73048583fa7c416487ea0248e4e66a8e41c3ffe9dcb1dd3" }, "downloads": -1, "filename": "dictquery-0.3.0.tar.gz", "has_sig": false, "md5_digest": "1b37727125911b4bd8b97366827b71dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13026, "upload_time": "2018-10-30T22:15:56", "url": "https://files.pythonhosted.org/packages/52/c8/9d9acbd3df4c5a706ad5627807a7571c1402715a394c980af1941f7c0e6a/dictquery-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "ffa50730b579344d1374dec8429b3509", "sha256": "f570d006295409ad61ac85b26ad8237dc2ede6efacf37142b6181047bf860f5d" }, "downloads": -1, "filename": "dictquery-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ffa50730b579344d1374dec8429b3509", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11240, "upload_time": "2018-11-04T20:19:29", "url": "https://files.pythonhosted.org/packages/c4/14/4a6e1ab16be07ec2c26b5d6f92619d1cf64adbb605ffc9c3911edad52d77/dictquery-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "488203fc6d5bfd1a20a26fcf1180c7ef", "sha256": "c989baa4f74edfdeb19688457ba39ce7e963a0a5a6a54415ac062b3b966ac3d5" }, "downloads": -1, "filename": "dictquery-0.4.0.tar.gz", "has_sig": false, "md5_digest": "488203fc6d5bfd1a20a26fcf1180c7ef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13437, "upload_time": "2018-11-04T20:19:30", "url": "https://files.pythonhosted.org/packages/30/bf/f2bfae9b5a672f53bc89846de3bbf974107aa917be5dc2c710a4908704c4/dictquery-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ffa50730b579344d1374dec8429b3509", "sha256": "f570d006295409ad61ac85b26ad8237dc2ede6efacf37142b6181047bf860f5d" }, "downloads": -1, "filename": "dictquery-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ffa50730b579344d1374dec8429b3509", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11240, "upload_time": "2018-11-04T20:19:29", "url": "https://files.pythonhosted.org/packages/c4/14/4a6e1ab16be07ec2c26b5d6f92619d1cf64adbb605ffc9c3911edad52d77/dictquery-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "488203fc6d5bfd1a20a26fcf1180c7ef", "sha256": "c989baa4f74edfdeb19688457ba39ce7e963a0a5a6a54415ac062b3b966ac3d5" }, "downloads": -1, "filename": "dictquery-0.4.0.tar.gz", "has_sig": false, "md5_digest": "488203fc6d5bfd1a20a26fcf1180c7ef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13437, "upload_time": "2018-11-04T20:19:30", "url": "https://files.pythonhosted.org/packages/30/bf/f2bfae9b5a672f53bc89846de3bbf974107aa917be5dc2c710a4908704c4/dictquery-0.4.0.tar.gz" } ] }