{ "info": { "author": "William Laroche", "author_email": "william.laroche@tackv.ca", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.6", "Topic :: Software Development", "Topic :: Software Development :: Testing", "Topic :: Utilities" ], "description": "# Incremental Module Loader\n\nProposes a injection pattern for your modules. Each module is simply a callable which takes other named modules as arguments. It is very simple with less than 40 statements of code and allows a great deal of flexibility while still removing frequent boilerplate we had to write on each of our projects. \n\nThis module is used by our SpinHub App (https://www.spinhub.ca) which is currently in development. It is the main building block of our module/service based architecture.\n\n## Use-Case 1: Modularize a flask app\n\nYou have an auth service, a database service and an blueprint creator function. How do you hook all of these together while keeping good separation of concerns and allowing injection of mocked services ? Let's see:\n\n```python\n\nfrom incremental_module_loader import IncrementalModuleLoader\n\nfrom flask import request, jsonify\n\nclass RequestParsingModule(object):\n def get_authorization_header(self):\n return request.headers.get('Authorization', None)\n\nclass MyAuthModule(object):\n def __init__(self, config, request_parser):\n self.url = config['AUTH_URL']\n self.request_parser = request_parser\n \n def get_user_id_from_token(self):\n header = self.request_parser.get_authorization_header()\n pass # Extract user id from header token...\n\nclass MyDatabaseModule(object):\n def __init__(self, config, auth):\n self.db_uri = config['SQLALCHEMY_DATABASE_URI']\n self.auth = auth\n\n def get_user(self):\n user_id = self.auth.get_user_id_from_token()\n pass # Retrieve user data from database...\n\n# Note the name of the arguments here:\ndef route_app(app, config, database):\n\n @app.route('/userinfo')\n def userinfo():\n # This triggers the auth verification from the header extracted from the request parser\n user = database.get_user()\n return jsonify(user.dump())\n # ...\n\n\ndef create_app():\n app = # (...) Standard app creation with config loading\n\n module_loader = IncrementalModuleLoader()\n\n # First init the modules with already created objects:\n module_loader.update(\n app=app,\n config=app.config\n )\n\n # Then load in order (\"incrementally\")\n # Make sure to specify a CALLABLE object (function or class)\n # The module_loader will call the parameter with the modules it is asking as parameters.\n module_loader.load(request_parser=RequestParsingModule)\n module_loader.load(auth=MyAuthModule)\n module_loader.load(database=MyDatabaseModule)\n\n # Can be loaded anonymously, returns nothing.\n module_loader.load(route_app)\n\n # There you have it !\n\n```\n\n# Creators\n\nCreated by Tack Verification, a company dedicated to reducing operational costs related to hardware systems verification. \nhttps://www.tackv.ca", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://gitlab.com/tackv/incremental-module-loader", "keywords": "", "license": "MIT", "maintainer": "William Laroche", "maintainer_email": "william.laroche@tackv.ca", "name": "incremental-module-loader", "package_url": "https://pypi.org/project/incremental-module-loader/", "platform": "", "project_url": "https://pypi.org/project/incremental-module-loader/", "project_urls": { "Homepage": "https://gitlab.com/tackv/incremental-module-loader" }, "release_url": "https://pypi.org/project/incremental-module-loader/1.1.1/", "requires_dist": null, "requires_python": "", "summary": "Micro-framework to allow incremental dependencies injection in inter-related modules.", "version": "1.1.1", "yanked": false, "yanked_reason": null }, "last_serial": 7374530, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "b1d2ea3d3308dca88ff18f44f7fb5961", "sha256": "f9be75b4e00a5f66d86fe5cd6165a142eecf4ecbf8ad5887f16ee31962268dab" }, "downloads": -1, "filename": "incremental_module_loader-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "b1d2ea3d3308dca88ff18f44f7fb5961", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4708, "upload_time": "2019-10-24T19:16:34", "upload_time_iso_8601": "2019-10-24T19:16:34.348978Z", "url": "https://files.pythonhosted.org/packages/47/e7/fa7d93d19564f43f7d79c4ac15c60f8799101d968c2f683cb4b30d726256/incremental_module_loader-1.0.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3f12a78c640cc3ae2cdd460fd2c9f922", "sha256": "eec7614771c9b1bf0844e5028d2ccb08eb5949b8011cca8717b3b38e3dadd256" }, "downloads": -1, "filename": "incremental_module_loader-1.0.0.tar.gz", "has_sig": false, "md5_digest": "3f12a78c640cc3ae2cdd460fd2c9f922", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3861, "upload_time": "2019-10-24T19:16:36", "upload_time_iso_8601": "2019-10-24T19:16:36.734571Z", "url": "https://files.pythonhosted.org/packages/3e/0d/726fb78255e17819ce3669aa53ff675fa25eb58675862c85fa35143fe596/incremental_module_loader-1.0.0.tar.gz", "yanked": false, "yanked_reason": null } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "7112e06caaca5ffc0f0cdd8d88f1cd03", "sha256": "777b870b985010c7730ab8c36dfff16e45e71254771eb50fc9837cb59f03c442" }, "downloads": -1, "filename": "incremental_module_loader-1.1.0.tar.gz", "has_sig": false, "md5_digest": "7112e06caaca5ffc0f0cdd8d88f1cd03", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4089, "upload_time": "2020-06-01T22:18:46", "upload_time_iso_8601": "2020-06-01T22:18:46.494968Z", "url": "https://files.pythonhosted.org/packages/f4/31/049bc69358ada5f51a090b4e352a58f2b7bc510c82d19c4fd0d27006434b/incremental_module_loader-1.1.0.tar.gz", "yanked": false, "yanked_reason": null } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "85c496964f51e9b308abbc62172ff35f", "sha256": "64eb466e02f9cd407df108136f92b0bd09b2b43ac579c95c5b717421daa7764a" }, "downloads": -1, "filename": "incremental_module_loader-1.1.1.tar.gz", "has_sig": false, "md5_digest": "85c496964f51e9b308abbc62172ff35f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4106, "upload_time": "2020-06-01T23:09:09", "upload_time_iso_8601": "2020-06-01T23:09:09.401162Z", "url": "https://files.pythonhosted.org/packages/35/f1/96ff7bddb7fc2ad509bec9cbe2d3a659fbaea3b1a13704679a2d670b6ef7/incremental_module_loader-1.1.1.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "85c496964f51e9b308abbc62172ff35f", "sha256": "64eb466e02f9cd407df108136f92b0bd09b2b43ac579c95c5b717421daa7764a" }, "downloads": -1, "filename": "incremental_module_loader-1.1.1.tar.gz", "has_sig": false, "md5_digest": "85c496964f51e9b308abbc62172ff35f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4106, "upload_time": "2020-06-01T23:09:09", "upload_time_iso_8601": "2020-06-01T23:09:09.401162Z", "url": "https://files.pythonhosted.org/packages/35/f1/96ff7bddb7fc2ad509bec9cbe2d3a659fbaea3b1a13704679a2d670b6ef7/incremental_module_loader-1.1.1.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }