# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['sauron', 'sauron_rule_engine']

package_data = \
{'': ['*']}

install_requires = \
['mypy>=0.711.0,<0.712.0',
 'pydantic>=0.29.0,<0.30.0',
 'ruamel.yaml>=0.16.5,<0.17.0']

setup_kwargs = {
    'name': 'sauron-rule-engine',
    'version': '1.0.2',
    'description': 'A simple rule engine implemented in python',
    'long_description': '<h1 align="center">Sauron Rule engine - One engine to rule them all </h1>\n<p>\n  <img src="https://img.shields.io/badge/version-0.1-blue.svg?cacheSeconds=2592000" />\n  <img src="https://circleci.com/gh/jlugao/sauron-rule-engine/tree/master.svg?style=svg" />\n  <a href=\'https://coveralls.io/github/jlugao/sauron-rule-engine?branch=master\'><img src=\'https://coveralls.io/repos/github/jlugao/sauron-rule-engine/badge.svg?branch=master&service=github\' alt=\'Coverage Status\' /></a>\n\n<img alt="GitHub" src="https://img.shields.io/github/license/jlugao/sauron-rule-engine.svg?style=plastic">\n  <a href="https://twitter.com/joaovoce">\n    <img alt="Twitter: joaovoce" src="https://img.shields.io/twitter/follow/joaovoce.svg?style=social" target="_blank" />\n  </a>\n</p>\n\n[![Build Status](https://dev.azure.com/jlugao/Sauron%20Engine/_apis/build/status/jlugao.sauron-rule-engine?branchName=master)](https://dev.azure.com/jlugao/Sauron%20Engine/_build/latest?definitionId=1&branchName=master)\n\n> A simple rule engine to be used in python, it is based on simple rules and actions that can be chained with each other. The idea is to run the rule processor on events and have it mutate data or trigger actions\n\nHeavily inspired on FastAPI. We use type annotations in our engine so that we can export data to other systems or frontends to convey what conditions and actions are possible using that engine\n\n## Install\n\n```sh\npip install sauron-rule-engine\n```\n\n## Concepts\n\nSauron rule engine is based on custom functions that can be called by a rule.\n\n### Condition\n\nCondition to be satisfied in order for the actions to run, they can take some or no parameters at all\nMultiple conditions can be chained in order to create more complex ones, currently all chained conditions must be satisfied\n\n### Action\n\nAn Action is the intented result. Usually they are there to mutate state or trigger/schedule other kinds of actions in your system. Actions can also be chained and will run in order.\n\n### Rule\n\nA Rule is a dict or json string containing the conditions and actions and the arguments they should be run with. Usually those rules will be built by a frontend to match complex and adaptable business rules from your customer\n\n## Use it\n\nA simple example of the usage\n\n```python\nfrom sauron.rule_engine import RuleEngine\n\nengine = RuleEngine()\n\n\n@engine.condition("First Condition")\ndef first_condition(session,lower_number: int = 10, greater_number: int = 20) -> bool:\n    """\n    Checks if first number is lower than the first\n    - lower_number: Number expected to be low\n    - higher_number: Number expected to be high\n    """\n    return lower_number < greater_number\n\n\n@engine.condition()\ndef second_condition(session):\n    """\n    Takes no argument and always returns True\n    """\n    return True\n\n\n@engine.action("The Action")\ndef print_the_equation(\n    session, lower_number: int = 10, greater_number: int = 20\n) -> None:\n    """\n    Prints a statement Asserting that the first number is lower than the second number\n    - lower_number: Number expected to be low\n    - higher_number: Number expected to be high\n    """\n    print(f"{lower_number} < {greater_number}")\n\n\nrule = {\n    "conditions": [\n        {\n            "name": "first_condition",\n            "args": {"lower_number": 3, "greater_number": 10},\n        }\n    ],\n    "actions": [\n        {\n            "name": "print_the_equation",\n            "args": {"lower_number": 3, "greater_number": 10},\n        }\n    ],\n}\n\n\nengine.run(rule)\n```\n\n## Choices Fields\n\nChoices fields are supported through python\'s built-in Enum type. Example:\n\n```python\nfrom sauron.rule_engine import RuleEngine\nfrom enum import Enum\n\nclass Color(str, Enum):\n    red = "R"\n    green = "G"\n    blue = "B"\n\n\n@engine.condition("is it red?")\ndef is_red(session, color: Color) -> bool:\n    """\n    Checks if the color is red\n    """\n    return color == color.red\n\n```\n\n## Export Conditions and Actions\n\nYou can use the function export_metadata to export your data in a dict or as a json string (just pass `json=True`). Here is an Example and the output:\n\n```python\nfrom sauron_rule_engine.rule_engine import RuleEngine\nfrom enum import Enum\n\nengine = RuleEngine()\n\n\n@engine.condition("First Condition")\ndef first_condition(lower_number: int = 10, greater_number: int = 20) -> bool:\n    """\n    Checks if first number is lower than the first\n    - lower_number: Number expected to be low\n    - higher_number: Number expected to be high\n    """\n    return lower_number < greater_number\n\n\n@engine.condition()\ndef second_condition():\n    """\n    Takes no argument and always returns True\n    """\n    return True\n\n\n@engine.action("The Action")\ndef print_the_equation(\n    lower_number: int = 10, greater_number: int = 20\n) -> None:\n    """\n    Prints a statement Asserting that the first number is lower than the second number\n    - lower_number: Number expected to be low\n    - higher_number: Number expected to be high\n    """\n    print(f"{lower_number} < {greater_number}")\n\n\nclass Color(str, Enum):\n    red = "R"\n    green = "G"\n    blue = "B"\n\n\n@engine.condition("is it red?")\ndef is_red(color: Color) -> bool:\n    """\n    Checks if the color is red\n    """\n    return color == color.red\n\n\nmetadata = engine.export_metadata(json=True)\nprint(metadata)\n\n```\n\nResults in the following json to be served to your frontend:\n\n```json\n{\n  "actions": {\n    "print_the_equation": {\n      "args": {\n        "lower_number": { "default": 10, "type": "int", "choices": null },\n        "greater_number": { "default": 20, "type": "int", "choices": null }\n      },\n      "doc": "Prints a statement Asserting that the first number is lower than the second number\\n- lower_number: Number expected to be low\\n- higher_number: Number expected to be high",\n      "name": "The Action"\n    }\n  },\n  "conditions": {\n    "first_condition": {\n      "args": {\n        "lower_number": { "default": 10, "type": "int", "choices": null },\n        "greater_number": { "default": 20, "type": "int", "choices": null }\n      },\n      "doc": "Checks if first number is lower than the first\\n- lower_number: Number expected to be low\\n- higher_number: Number expected to be high",\n      "name": "First Condition"\n    },\n    "second_condition": {\n      "args": {},\n      "doc": "Takes no argument and always returns True",\n      "name": "second_condition"\n    },\n    "is_red": {\n      "args": {\n        "color": {\n          "default": null,\n          "type": "Color",\n          "choices": ["red", "green", "blue"]\n        }\n      },\n      "doc": "Checks if the color is red",\n      "name": "is it red?"\n    }\n  }\n}\n```\n\n## Sessions\n\nResults are stored in a result stack inside the session, so that jobs can share data with each other. \n\n\n## More Features coming to town\n\n- Support pydantic types\n- Support for complex types with hints to the frontend (like a range for an int type)\n\n## Contribute\n\n- We need all the help we can get. Please read [CONTRIBUTE.md](CONTRIBUTING.md) for instructions\n\n## Author\n\n👤 **João Ricardo Lhullier Lugão**\n\n- Twitter: [@joaovoce](https://twitter.com/joaovoce)\n- Github: [@jlugao](https://github.com/jlugao)\n\n## Show your support\n\nGive a ⭐️ if this project helped you!\n\n---\n\n_This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_\n',
    'author': 'jlugao',
    'author_email': 'joaolhullier@gmail.com',
    'url': 'https://github.com/jlugao/sauron-rule-engine',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
