{ "info": { "author": "Armon Dadgar", "author_email": "armon@kiip.me", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries" ], "description": "PyPred\n======\n[![Build Status](https://travis-ci.org/armon/pypred.png)](https://travis-ci.org/armon/pypred)\n\nPyPred is a package to do predicate evaluation in Python. It uses a\nPLY (Lex/Yacc for Python) to parse inputs into an AST tree which it\nthen evaluates. The PyPred provides simple APIs to do the evaluation\nis most sitations, but allows for customized evaluation techniques for\nmore complex situations.\n\nAdditionally, PyPred supports the notion of predicate \"sets\". This is\na collection of predicates that are all simultaneously evaluated against\na single input document. For example, in a Pub/Sub system, each subscription\ncan be modeled as a predicate. When a new event arrives, the predicate set\nof all subscriptions can be evaluated to find all matching subscriptions.\n\nPyPred provides a PredicateSet model as well as an OptimizedPredicateSet.\nThe optimized variant trades memory for speed. It extracts common\nsub-expressions into a branch, and conditionally executes different sets\nof predicates to prune the predicates that will not match most efficiently.\nThe parameters of the optimization can be tweaked to find a speed/memory\nbalance.\n\nGrammar\n=======\n\nThe grammar that PyPred understands is limited to simple comparisons\nand boolean logic.\n\nIt supports the following:\n\n* Logical operators `not`, `and`, `or`\n* Comparison operators >, >=, <, <=, =, !=, 'is', 'is not'\n* Parenthesis to disambiguate\n* The subset check operator `contains`\n* The regular expression matcher `matches`\n* String literals, quoted if they include spaces\n* Numeric literals\n* Constants true, false, undefined, null, empty\n* Set literal, containing string literals, numeric and constant values\n\nGrammar Examples\n================\n\nTo demonstate the capabilities of the pypred grammar, the following\nexamples are provided.\n\n name is 'Jack' and friend_name is 'Jill'\n\nThis predicate checks that the input document has a field name equal to\n\"Jack\", and a field friend\\_name equal to \"Jill\"\n\n event is \"Record Score\" and ((score >= 500 and highest_score_wins) or (score < 10 and lowest_score_wins))\n\nThis is a slightly more advanced predicate. It checks that this is a \"Record Score\" event,\nand that the score is either greater than or equal to 500 in the case that a high score is desireable,\nor that the score is less than 10 if a low score is desirable.\n\n server matches \"east-web-([\\d]+)\" and errors contains \"CPU load\" and environment != test\n\nThis checks for any webserver hostname matching a numeric suffix, such as \"east-web-001\", with\n\"CPU load\" being reported as an error in a non-test environment.\n\nLiteral sets can be used to check for multiple clauses:\n\n {\"WARN\" \"ERR\" \"CRIT\"} contains error_level or {500 501 503} contains status_code\n\nThis provides two literal sets which are used to check against the dynamic values\nof error\\_level and status\\_code.\n\nAPI\n===\n\nPredicates themselves have a single interface, which is the `Predicate` class.\nIt is instantiated with a string predicate.\n\nThe main API's for it are:\n* Predicate(Pred) : Creates a new predicate object\n\n* Predicate.description(): Returns a human readable version of the tree if valid\n\n* Predicate.is\\_valid() : Returns if the predicate is valid\n\n* Predicate.errors(): If not valid, returns a list of tokenization, syntax, and semantic errors\n\n* Predicate.evaluate(document) : Evaluates the given document against the predicate\n\n* Predicate.analyze(document) : Evaluates the given document against the predicate,\n returns the results, as well as the evaluation context that includes more information about\n the evaluation, including the failure reasons. This is generally much slower than\n evaluate in the failure cases.\n\nOne of the critical aspects of evaluating a predicate is the resolution of\nliterals. When the AST needs a value to substitute a variable, it calls the\n`resolve_identifier` method of the Predicate. The default behavior is flexible,\nand support string literals, dictionary lookups, nested dictionaries, and\ncall back resolution via `set_resolver`. However, if a client wants to customize\nthe resolution of identifier, they can simply override this method.\n\nPredicate Sets have two main interfaces, either the `PredicateSet` or `OptimizedPredicateSet`.\n\nBoth share part a subset of their calls:\n\n* Set(preds=None) : Instantiate the set, optionally with a list of predicates\n\n* Set.add(predicate) : Adds a predicate to the set\n\n* Set.update(predicates) : Extends to include a list of predicates\n\n* Set.evaluate(document) : Evaluates the document against the predicates and returns a list of matches\n\nThe OptimizedPredicateSet supports an extended set of API's:\n\n* OptSet.description() : Returns ahuman readable version of the optimized tree\n\n* OptSet.analyze(document) : Like Predicate.analyze(), but returns a boolean, a list, and the evaluation context.\n\n* OptSet.compile\\_ast() : Forces compilation of the interal AST\n\n* OptSet.finalize() : Prunes the AST of sub-predicates, and removes any instance data that is not used\n as part of the evaluation of the optimized set. Not usually needed, but can reduce the total memory\n footprint, and is useful if the object is going to be pickled.\n\nThe standard PredicateSet relies on the underlying predicates to do\nresolution of literals, however the OptimizedPredicateSet implements\n`resolve_identifier` to do so. Thus if custom behavior is wanted, the\noptimized set must be sub-classed.\n\n\nHuman Readable Outputs\n======================\n\nPyPred tries to make it possible to provide human readable output of\nboth predicates as well as any error messages that are encountered.\nHere is an example of a human readable description of:\n\n p = Predicate('server matches \"east-web-([\\d]+)\" and errors contains \"CPU load\" and environment != test')\n print p.description()\n\n AND operator at line: 1, col 34\n MatchOperator at line: 1, col 7\n Literal server at line: 1, col 0\n Regex 'east-web-([\\\\d]+)' at line: 1, col 15\n AND operator at line: 1, col 65\n ContainsOperator at line: 1, col 45\n Literal errors at line: 1, col 38\n Literal \"CPU load\" at line: 1, col 54\n != comparison at line: 1, col 81\n Literal environment at line: 1, col 69\n Literal test at line: 1, col 84\n\nHere is an example of the output during a failed evaluation:\n\n p = Predicate('server matches \"east-web-([\\d]+)\" and errors contains \"CPU load\" and environment != test')\n res, ctx = p.analyze({'server': 'east-web-001', 'errors': [], 'environment': 'prod'})\n assert res == False\n\n pprint.pprint(ctx.failed)\n [\"Right side: 'CPU load' not in left side: [] for ContainsOperator at line: 1, col 45\",\n 'Left hand side of AND operator at line: 1, col 65 failed',\n 'Right hand side of AND operator at line: 1, col 34 failed']\n\n pprint.pprint(ctx.literals)\n {'\"CPU load\"': 'CPU load',\n 'errors': [],\n 'server': 'east-web-001'}", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/armon/pypred/", "keywords": "python,predicate,natural language", "license": "MIT License", "maintainer": null, "maintainer_email": null, "name": "pypred", "package_url": "https://pypi.org/project/pypred/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/pypred/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/armon/pypred/" }, "release_url": "https://pypi.org/project/pypred/0.4.0/", "requires_dist": null, "requires_python": null, "summary": "A Python library for simple evaluation of natural language predicates", "version": "0.4.0" }, "last_serial": 2265175, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "ac9a333a0a856b973bf280f1ab5dd0fa", "sha256": "6923dcfd15ab8da1860d29ea48c9c04d28073483b5b603ae316c2a32f3ad3bdf" }, "downloads": -1, "filename": "pypred-0.1.0.tar.gz", "has_sig": false, "md5_digest": "ac9a333a0a856b973bf280f1ab5dd0fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11764, "upload_time": "2013-02-11T23:52:10", "url": "https://files.pythonhosted.org/packages/25/a3/b5b7cb159df103dab147baca765a345733cff6431f664563e635865db6ed/pypred-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "99d5a686467a1ebcff3564690d5a1d68", "sha256": "2afcd899514d7a261652cd8d14cb1c26d8f590c9b071b9b306cc24a15206f553" }, "downloads": -1, "filename": "pypred-0.2.0.tar.gz", "has_sig": false, "md5_digest": "99d5a686467a1ebcff3564690d5a1d68", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23423, "upload_time": "2013-03-26T22:18:09", "url": "https://files.pythonhosted.org/packages/d2/09/05fdd1e21d4e0b12a11a561bae91895eb76adab2d46e1b11dfc373a9f4c1/pypred-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "f3ad0367b29c1694c49b7477afe41a18", "sha256": "825b10f254f88fb111bfda4116e467e18da89db83f3aabc368e21a7c4aedd783" }, "downloads": -1, "filename": "pypred-0.2.1.tar.gz", "has_sig": false, "md5_digest": "f3ad0367b29c1694c49b7477afe41a18", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23548, "upload_time": "2013-04-03T00:09:55", "url": "https://files.pythonhosted.org/packages/06/83/d30f825bf03b39ca73b3c677377d8f675fb8941efbe5e73c45a97576ef4d/pypred-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "0a8ecc3bc8f47a4d57ba0f224e169ed0", "sha256": "a2226bdc1329045eb79178b53c6cec37f71520347bcb730745aee14c43c2c070" }, "downloads": -1, "filename": "pypred-0.2.2.tar.gz", "has_sig": false, "md5_digest": "0a8ecc3bc8f47a4d57ba0f224e169ed0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23580, "upload_time": "2013-04-17T18:21:31", "url": "https://files.pythonhosted.org/packages/5a/21/623bced0b62c107bdac0f7549b68de579cd12364278030052baf2de68d44/pypred-0.2.2.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "8d97c3b11c419a109618a50800afb107", "sha256": "3567efbab8083f498996b2ef4b8274fc7a45ff934363e303e67b80c371f5916b" }, "downloads": -1, "filename": "pypred-0.3.0.tar.gz", "has_sig": false, "md5_digest": "8d97c3b11c419a109618a50800afb107", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24354, "upload_time": "2013-05-09T18:06:25", "url": "https://files.pythonhosted.org/packages/c0/63/3a6571bfc93f5c231a068e5576125315b9cf99a0ee21053fc78d498fbfd4/pypred-0.3.0.tar.gz" } ], "0.3.5": [ { "comment_text": "", "digests": { "md5": "be2f8563111a20714c667f52988fff91", "sha256": "6e877b71d0f8fc2fdfff91da2ddf6d14411c0d94afc45a4f89c913980164a437" }, "downloads": -1, "filename": "pypred-0.3.5.tar.gz", "has_sig": false, "md5_digest": "be2f8563111a20714c667f52988fff91", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25912, "upload_time": "2013-07-10T00:17:01", "url": "https://files.pythonhosted.org/packages/e9/9a/0316c6e7faa5e1b57e04932809d5a6be4fa469f1741103d43ae377ffab3a/pypred-0.3.5.tar.gz" } ], "0.3.6": [ { "comment_text": "", "digests": { "md5": "9e0e71f6480ef14bf00c89c1fc4b9797", "sha256": "ee334a32e8637889f7999f161f91465dae1f7eb171998cc5e48c6ba72c4ddb0c" }, "downloads": -1, "filename": "pypred-0.3.6.tar.gz", "has_sig": false, "md5_digest": "9e0e71f6480ef14bf00c89c1fc4b9797", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26270, "upload_time": "2013-07-10T18:59:55", "url": "https://files.pythonhosted.org/packages/e5/01/8558cd0127d7ef2dc9f4dd6e7402c718737d4ee9856128c65aa924c20a77/pypred-0.3.6.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "4d882a6c9b70a6aa599d3e7f7e07388b", "sha256": "110d9807727d5b0f50994a9c220e6fc592a1eeed5652bed2c857c7941818aa80" }, "downloads": -1, "filename": "pypred-0.4.0.tar.gz", "has_sig": false, "md5_digest": "4d882a6c9b70a6aa599d3e7f7e07388b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26880, "upload_time": "2016-08-06T00:59:54", "url": "https://files.pythonhosted.org/packages/78/69/c417952444c03a8aed83f3a2cc836218aa4d3079516aba327ba8e0b4ddd7/pypred-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4d882a6c9b70a6aa599d3e7f7e07388b", "sha256": "110d9807727d5b0f50994a9c220e6fc592a1eeed5652bed2c857c7941818aa80" }, "downloads": -1, "filename": "pypred-0.4.0.tar.gz", "has_sig": false, "md5_digest": "4d882a6c9b70a6aa599d3e7f7e07388b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26880, "upload_time": "2016-08-06T00:59:54", "url": "https://files.pythonhosted.org/packages/78/69/c417952444c03a8aed83f3a2cc836218aa4d3079516aba327ba8e0b4ddd7/pypred-0.4.0.tar.gz" } ] }