{ "info": { "author": "Nikolas Valerkos", "author_email": "n.valerkos@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2" ], "description": "# cronio\n\nINTRO\n\n>This project has a sender and a receiver, the sender sends commands through RabbitMQ on the queue of a worker (receiver), the receiver executes them either with OS or Python2.7\n\n## NOTE\n\n>Following a test I did, I discovered many issues maintaining the code, I started recode the whole thing because it was not an easy thing to understand, my plan is to finish it as soon as possible and be able to make as easy as possible to understand.\n\n## Objectives\n\n- [x] Prototype - Send some commands in OS or in Python and execute them, bring back the log or errors if any\n- [x] Package Structure\n- [x] Dependent Commands ie. dependancy: [1,2,3,200, cmd_id]\n- [x] Multiple Workers with one Sender, dependency on different workers to run a task with negation. \nie. Complete Task A on Worker 1, and when done do Task B on Worker 2. If not done, do Task C on Worker 3.\ncheck examples/sender_complex_multi_worker.py\n- [ ] Time to be executed ie. using python-crontab would be a good thing\n- [ ] ENVs needs to be tested with docker that it can be set and read from this app.py\n\n\n## Requirements\n\n1. STOMP Python Library \n2. SQLAlchemy (use of sqlite)\n3. RabbitMQ Server (see myrabbitmq\\ folder for details on raising a container with it.- You are welcome!)\n\tYou can get one using our docker image - default username and password is guest.\n\tIf you want the dockerfile for it, you can go to the folder's repository myrabbitmq.\n\nInstall Required packages (1,2)\n\n\tpip install -r requirements.txt \n\n\n## Installation \n\nPyPi\n\n\tpip install cronio\n\n\n\n## Examples\n\nFor Code see examples\\ directory\n\nWorker:\n\n\tpython worker1.py # this will start the worker process, see inline comments\n\n\nSender:\n\n\tpython sender_complex_multi_workers_example2.py # this has everything in it\n\n\n## Custom Listener for Sender\n\nModify it based on your current needs on listening for worker's messages to act accordingly.\n\n\tWORKER_ID_1 = \"worker_1\"\n\tCS_1 = CronioSender({\n\t# To Enable Viewer Log, uncomment the below in worker and sender:\n\t# 'CRONIO_SENDER_EXCHANGE_LOG_INFO': \"cronio_log_info\",\n\t# 'CRONIO_SENDER_EXCHANGE_LOG_ERROR': \"cronio_log_error\",\n\t'CRONIO_SENDER_AMQP_USERNAME': \"sender1\",\n\t'CRONIO_SENDER_AMQP_PASSWORD': \"somepass\",\n\t'CRONIO_SENDER_WORKER_QUEUE': \"cronio_queue\"+WORKER_ID_1,\n\t'CRONIO_SENDER_AMQP_HOST': 'localhost',\n\t'CRONIO_SENDER_AMQP_VHOST': '/',\n\t'CRONIO_SENDER_AMQP_PORT': 61613,\n\t'CRONIO_SENDER_AMQP_USE_SSL': False,\n\t'CRONIO_SENDER_LOGGER_LEVEL': logging.DEBUG, #logging.DEBUG\n\t'CRONIO_SENDER_LOGGER_FORMATTER': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',\n\t'CRONIO_SENDER_RUNTIME_SECONDS': 5})\n\n\tclass CronioSenderListener1(stomp.ConnectionListener):\n\t\tdef on_error(self, headers, message):\n\t\t\tpprint.pprint(headers)\n\t\t\tpprint.pprint(message)\n\t\t\tCS_1.logger_sender.debug('Cronio Sender Listener received an error \"%s\"' % message)\n\t\tdef on_message(self, headers, message):\n\t\t\t# Use the below to your discretion on receiving new messages\n\t\t\t# CS_1.logger_sender.debug(' %s' % str(headers['message-id']))\n\t\t\t# CS_1.logger_sender.debug(' Log %s' % str(message))\n\t\t\t# CS_1.logger_sender.debug('ACK Log - Remove from Queue %s' % str(headers['message-id']))\n\t\t\t# MESSAGE IS IN JSON\n\t\t\tmessage_obj = json.loads(message)\n\t\t\tpprint.pprint(message_obj)\n\t\t\t# if headers['subscription'] == \"api_log\":\n\t\t\t# \tpprint.pprint(message_obj)\n\t\t\t# if headers['subscription'] == \"api_log\":\n\t\t\t\t# This here is where the magic happens\n\t\t\t\t# print \"API LOG ==================================\"\n\t\t\t\t# pprint.pprint(message_obj)\n\t\t\t\t# print \"API LOG ENDS =============================\"\n\t\t\t# else:\n\t\t\t\t# a bunch of other messages\n\t\t\t\t# print \"view_log - or error\"\n\n\t\t\t# remove from queue\n\t\t\tCS_1.conn.ack(headers['message-id'],1)\n\n\tCS_1.conn.disconnect()\n\tCS_1.conn.remove_listener('default')\n\tCS_1.cronio_sender_listener = CronioSenderListener1() \n\tCS_1.initConnectSenderSTOMP()\n\tCS_1.conn.subscribe(destination=CS_1.CRONIO_SENDER_API_LOG, id=\"api_log1\", ack='client')\n\n\n\n## Worker Queues\n> After version 1.1.0, the worker queues are modified in a more standardized way to enable the multiworker dependancy, if you want to do such a thing!:\nie.\n\n\tself.CRONIO_WORKER_ID = 'worker_1'\n\tself.CRONIO_WORKER_PREFIX = '/queue/cronio/'\n\tself.CRONIO_WORKER_QUEUE = self.CRONIO_WORKER_PREFIX + self.CRONIO_WORKER_ID\n\n> Hence that, the CRONIO_WORKER_QUEUE param in class and settings needs to be avoided if you want to have the multiworker dependancy to work. Otherwise we will need to add namespaces for it. Which are going a bit off topic.\n> Ensure that you set CRONIO_WORKER_ID and CRONIO_WORKER_PREFIX on each worker and have the same CRONIO_WORKER_PREFIX in all workers. \n> Avoid using CRONIO_WORKER_ID in the format: worker1 and worker11 otherwise you might end up having difficulty setting permissions for specific workers.\n\n\n## Dependency Checks\n\nEach worker (ie. worker_1) has a specific log which receives notices when one a workers job (ie. worker_2) has finished which is a dependency on the other worker (ie. worker_1). \nie.\n\n\tqueue_cronio_workers_dependency_worker_1\n\n\n\n\n## Execute OS commands and pass a cmd_id (ID)\n\n>Generate cmd_ids to use for each:\n\n\timport pprint\n\tcmd_ids = [str(uuid.uuid4()),str(uuid.uuid4()),str(uuid.uuid4()),str(uuid.uuid4()),str(uuid.uuid4()),str(uuid.uuid4())]\n\tpprint.pprint(cmd_ids)\n\n\n>Execute a git command and get the result in the listener\n\n\t# Use those on the following commands:\n\n\t# clear database of worker\n\tCS_1.sendCMD('cleardb',WORKER_ID_1,'operation',0)\n\n\t# git clone a repo\n\tCS_1.sendCMD(\"git clone https://gitlab.com/doctormo/python-crontab.git\", WORKER_ID_1, \"os\", cmd_ids[1])\n\n>or just a simple listing\n\n\t#execute ls command on the current folder\n\tCS_1.sendCMD(\"ls\", WORKER_ID_1, \"os\", cmd_ids[2])\n\n\n>Can send files if you want to execute those:\n\n\t# Absolute Path only\n\tPythonFile = \"/opt/cronio/examples/test.py\"\n\tCmdFile = \"/opt/cronio/examples/test.sh\"\n\tCS_1.sendPythonFile(PythonFile,WORKER_ID_1,1)\n\tCS_1.sendCmdFile(CmdFile,WORKER_ID_1,2)\n\n\n\t# Clear Database of its commands\n\tCS_1.sendCMD('cleardb',WORKER_ID_1,'operation',cmd_ids[4])\n\n\n>Use workflow to run on the worker.\n\n\t# Workflow Example - Set of commands related with each other.\n\tcommands = [ {\"cmd\": \"ls\", \"worker_id\": \"worker_1\", type\": \"os\", \"cmd_id\": 1, \"dependencies\": None}, {\"cmd\": \"mkdir test_1\", \"worker_id\": \"worker_1\", type\": \"os\", \"cmd_id\": 2, \"dependencies\": None}, {\"cmd\": \"cd test_1\", \"worker_id\": \"worker_1\", type\": \"os\", \"cmd_id\": 3, \"dependencies\": [2]},{\"cmd\": \"print \\\"hello cronio\\\"\", \"worker_id\": \"worker_1\", type\": \"python\", \"cmd_id\": 4,\"dependencies\" : None}]\n\tCS_1.sendWorkflow(commands)\n\n\n>Just add the python commands and add \\n after each line\n\n\tCS_1.sendCMD(\"iter2=[2,3,4,5,6,7]\\nfor item2 in iter2:\\n\\tprint item2\",WORKER_ID_1,\"python\",2)\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/nvalerkos/cronio", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "cronio", "package_url": "https://pypi.org/project/cronio/", "platform": "", "project_url": "https://pypi.org/project/cronio/", "project_urls": { "Homepage": "https://github.com/nvalerkos/cronio" }, "release_url": "https://pypi.org/project/cronio/1.2.0/", "requires_dist": [ "stomp-py", "sqlalchemy" ], "requires_python": "", "summary": "This project has a sender and a receiver, the sender sends commands through RabbitMQ on the queue of a worker (receiver), the receiver executes them either with OS or Python2.7", "version": "1.2.0" }, "last_serial": 5381041, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "1e3a04a0a544d1062424198b5bf5b0b0", "sha256": "ead0881d668afa5c298c1a74160dc703f81d9e392ed3be448ec2f5122c44ab20" }, "downloads": -1, "filename": "cronio-1.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "1e3a04a0a544d1062424198b5bf5b0b0", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 8689, "upload_time": "2018-08-06T14:27:20", "url": "https://files.pythonhosted.org/packages/ab/30/5272a3f087b0f4729294a2a1babe02509806487313d293e592a43857c283/cronio-1.0.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "114a76dfe13206879aa880123a5c8ffe", "sha256": "9b92089e381e21aa98098d9f64066e8e5df2ef2ccd677af6828cb72251619dc7" }, "downloads": -1, "filename": "cronio-1.0.0.tar.gz", "has_sig": false, "md5_digest": "114a76dfe13206879aa880123a5c8ffe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7103, "upload_time": "2018-08-06T14:27:21", "url": "https://files.pythonhosted.org/packages/2d/57/8784d53b0f205a7c9efb67ed5cc70b9cebf5ec14c9036942fa1192de9075/cronio-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "2366733ac782a5115694f7ef90b5cdcc", "sha256": "50dfcc41b979d51e4c215ca940b4fe32fa2e3ea16b0a3854a49e31b5f2d514d5" }, "downloads": -1, "filename": "cronio-1.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "2366733ac782a5115694f7ef90b5cdcc", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 8697, "upload_time": "2018-08-07T13:21:35", "url": "https://files.pythonhosted.org/packages/a8/09/eca05d6f513074413302d8f32fb02916ccb86f49a35437a6883608364260/cronio-1.0.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1cda227045ad34c2850467c80a89152b", "sha256": "f56609aecf295d9b0dbd89b891878aa76ec168fdedd0f008d10e9365382dbf11" }, "downloads": -1, "filename": "cronio-1.0.1.tar.gz", "has_sig": false, "md5_digest": "1cda227045ad34c2850467c80a89152b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7171, "upload_time": "2018-08-07T13:21:37", "url": "https://files.pythonhosted.org/packages/23/7c/d1f0216fec86e9f4975e25ccae06df066c60b3c427e11e3e3a2af1556401/cronio-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "b12af1bdf55d9515dbd060bc14b021a1", "sha256": "6f9a097fab918c74461acea0c7ffb24f21792f250ad2fa08c9bce9d344131770" }, "downloads": -1, "filename": "cronio-1.1.0-py2-none-any.whl", "has_sig": false, "md5_digest": "b12af1bdf55d9515dbd060bc14b021a1", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 12078, "upload_time": "2018-08-09T11:15:42", "url": "https://files.pythonhosted.org/packages/c3/9b/e6dcd573455de81f9f6657f4f035ecf725e7d76f6f0c23393bd16ef2e02d/cronio-1.1.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d4c6ee44d5d8b2d90a3b8bdeca0c2e4", "sha256": "b36f6df7bcad898856a6a53c7611fd9ec3db60ee759b2c2a9e9284922f877107" }, "downloads": -1, "filename": "cronio-1.1.0.tar.gz", "has_sig": false, "md5_digest": "9d4c6ee44d5d8b2d90a3b8bdeca0c2e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11889, "upload_time": "2018-08-09T11:15:44", "url": "https://files.pythonhosted.org/packages/53/d6/00c17d002946ed517c19fe3f70c228ede2d10950a9485ce5c7e932339c98/cronio-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "180e88eac61ee100a97756a6d9f23e86", "sha256": "eca6959c5afeca256d488ad7936938871462df93e9359b058dec7c97cf0d55d7" }, "downloads": -1, "filename": "cronio-1.1.1-py2-none-any.whl", "has_sig": false, "md5_digest": "180e88eac61ee100a97756a6d9f23e86", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 17868, "upload_time": "2018-08-31T16:11:28", "url": "https://files.pythonhosted.org/packages/90/b3/d8f345c8ae9d140b5409a7ed8b0a272492585894d96f68d92d77ac8f5650/cronio-1.1.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "19f6819667a075764f1b2e327d3f50ad", "sha256": "8366c27f654af3b8e14ccdae886ebcad0f4b48fb06667b63491a572a6602da64" }, "downloads": -1, "filename": "cronio-1.1.1.tar.gz", "has_sig": false, "md5_digest": "19f6819667a075764f1b2e327d3f50ad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12692, "upload_time": "2018-08-31T16:11:29", "url": "https://files.pythonhosted.org/packages/6d/d1/2ee694870fae49ada07fd6e7f7716855c8a1ff8286b39d0c4920e3f92f33/cronio-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "6f7e862e966ad8298081fef87fa8464e", "sha256": "f86a0dcfaba94454540e539b336adb001343724148b4162569e48c640126a65b" }, "downloads": -1, "filename": "cronio-1.2.0-py2-none-any.whl", "has_sig": false, "md5_digest": "6f7e862e966ad8298081fef87fa8464e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 17828, "upload_time": "2019-06-10T13:34:50", "url": "https://files.pythonhosted.org/packages/ee/3f/5c57c07d0ee97be42003e693aa9122a387b4d4bfe7871171f96b0156a76e/cronio-1.2.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6e80e50ddb4f542e8fab4ebd6f743775", "sha256": "aa4fed019e041e387469e866fa687b996d87d90659b6196160440e3415c7051d" }, "downloads": -1, "filename": "cronio-1.2.0.tar.gz", "has_sig": false, "md5_digest": "6e80e50ddb4f542e8fab4ebd6f743775", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18407, "upload_time": "2019-06-10T13:34:51", "url": "https://files.pythonhosted.org/packages/d8/87/d51649d583333968d39b03c60db81dc2ab6050bf2da53a77cc1aad1d51c3/cronio-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6f7e862e966ad8298081fef87fa8464e", "sha256": "f86a0dcfaba94454540e539b336adb001343724148b4162569e48c640126a65b" }, "downloads": -1, "filename": "cronio-1.2.0-py2-none-any.whl", "has_sig": false, "md5_digest": "6f7e862e966ad8298081fef87fa8464e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 17828, "upload_time": "2019-06-10T13:34:50", "url": "https://files.pythonhosted.org/packages/ee/3f/5c57c07d0ee97be42003e693aa9122a387b4d4bfe7871171f96b0156a76e/cronio-1.2.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6e80e50ddb4f542e8fab4ebd6f743775", "sha256": "aa4fed019e041e387469e866fa687b996d87d90659b6196160440e3415c7051d" }, "downloads": -1, "filename": "cronio-1.2.0.tar.gz", "has_sig": false, "md5_digest": "6e80e50ddb4f542e8fab4ebd6f743775", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18407, "upload_time": "2019-06-10T13:34:51", "url": "https://files.pythonhosted.org/packages/d8/87/d51649d583333968d39b03c60db81dc2ab6050bf2da53a77cc1aad1d51c3/cronio-1.2.0.tar.gz" } ] }