{ "info": { "author": "Andrew Yurisich", "author_email": "andrew.yurisich@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7" ], "description": "# python-module-resources\n\nImport non-python files in a project directory as python namedtuple objects.\n\nIf you've ever worked in node, you might be familiar with a language feature which allows you to pull in a json file as an imported module.\n\n```node\nimport { dataStuff } from 'myProjectResources/jsonFiles'\n\ndataStuff.contents === \"A rich javascript object\"\n```\n\nWith `module_resources`, you can achieve something similar in python.\n\n```py\nfrom my_project_resources.json_files import data_stuff\n\ndata_stuff.contents == 'A python namedtuple instance'\n```\n\n## Getting Started\n\nTo use this in your own project, install with pip.\n\n```\npip install module-resources\n# supports yaml files too\npip install module-resources[yaml]\n```\n\nCreate a module location in your project where your desired importable resource files will live. I will use [this project as an example](./module_resources/examples).\n\n```\nmkdir module_resources/examples/json/\ntouch module_resources/examples/json/__init__.py\n```\n\nYour module's [`__init__.py` file does the heavy lifting](./module_resources/examples/json/__init__.py).\n\n```py\nfrom module_resources import JsonModuleResource\n__all__ = JsonModuleResource(__name__, __file__).intercept_imports()\n```\n\nFrom there, move the resources you'd like to import as python objects into that directory.\n\n```\ntree ./module_resources/examples/json/\nmodule_resources/examples/json/\n\u251c\u2500\u2500 __init__.py\n\u2514\u2500\u2500 logging_config.json\n\n0 directories, 2 files\n```\n\nYou can now import some logger object's configuration json as a python namedtuple. It has a few interesting properties about it that will hightlight some caveats about this tool.\n\n```\n> python\nPython 3.7.2 (default, Jan 14 2019, 16:30:40)\n[Clang 10.0.0 (clang-1000.10.44.4)] on darwin\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n```\n\n```py\n>>> from module_resources.examples.json import logging_config\n>>> logging_config.formatters.simple\njson(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n```\n\nYou may refer to any valid namedtuple property by using dot-attribute notation.\n\n```py\n>>> logger.formatters.simple.format\n'%(asctime)s - %(name)s - %(levelname)s - %(message)s'\n```\n\nYaml configuration files work as well, [with the `module_resources.YamlResourceModule` class](./module_resources/examples/yaml/__init__.py).\n\n```py\n>>> from module_resources.examples.yaml import logging_config as yaml_logging_config\n>>> yaml_logging_config.formatters\nyaml(simple=yaml(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'))\n```\n\nTo turn this object into a dictionary, pass it to `dict()`.\n\n```py\n>>> import logging.config\n>>> logging.config.dictConfig(dict(yaml_logging_config))\n>>> logging.getLogger('test').info('testing')\n```\n\n```\n2019-07-23 11:43:57,296 - test - INFO - testing\n```\n\n## Caveats\n\nThere are some caveats to be aware of.\n\n#### Valid vs. invalid namedtuple field names\n\n```py\n>>> from module_resources.examples.json import logging_config\n>>> logging_config.loggers.__main__\n```\n\n```\nTraceback (most recent call last):\n File \"\", line 1, in \nAttributeError: 'ImportableFallbackDict' object has no attribute '__main__'\n```\n\nIn namedtuple fields, `__main__` is not a legal name. It gets exposed as a dictionary type, `ImportableFallbackDict`.\n\n```py\n>>> logging_config.loggers['__main__'].level\n'INFO'\n```\n\nIt does store valid property names in that dictionary as namedtuples, however.\n\n#### Exporting only a portion of a file\n\nYou may export from the top level namespace of a resource.\n\n```py\n>>> from module_resources.examples.json.logging_cofig import formatters\n>>> formatters.simple.format\n'INFO'\n```\n\nYou can't export arbitrarily deep from a json or yaml file. Only one level deep is supported.\n\n#### Type hints for module resources\n\nUsing this tool is going to make pylint unhappy.\n\n```py\nfrom module_resources.examples.json import logging_config\n\nimport logging.config\nlogging.config.dictConfig(dict(logger))\n```\n\nThe above code is going to raise complaints from pylint.\n\n```\npylint: Unable to import 'module_resources.example.json.logging_config' (\"import-error\") [E0401]\n```\n\nThis tool leverages highly dynamic features of the python language to accomplish its work, and as such properties and types won't be available until runtime. You will need to include exceptions for these objects in your codebase if you want to maintain a high lint score while using this tool.\n\n# Development\n\nA Linux or Mac environment is assumed for development, running python version 3.\n\n### Prerequisites\n\n```\nmake preqres\n```\n\nThis script will help ensure you have the necessary tools for developing against the project locally.\n\n### Installing\n\n```\nmake virtualenv\n. .venv/bin/activate\n```\n\nRun the tests after installing the dependencies.\n\n## Running the tests\n\n```\nmake tests\n```\n\n### And coding style tests\n\n```\nmake lint\nmake mypy\nmake bandit\n```\n\n## Deployment\n\nOpen a pull request against the master branch. Travis-CI will publish a preview version after all tests pass. You can install this preview version of your branch build from test.pypi.org.\n\n```\npip install -i https://test.pypi.org/simple/ module-resources==0.0.${TRAVIS_BUILD_NUMBER}\n```\n\nNote that if you open a pull request from a fork, this step won't run.\n\nTo publish a new official version, tag a commit and push it up to the master branch.\n\n```\ngit checkout master\ngit pull origin master\n# examples of preparing a new tag for release\nmake tag-patch # also accepts: tag-minor, tag-major\ngit push origin --tags\n```\n\nNote that you must create and push tags from the master branch only. Tags found in pull requests won't do anything.\n\n## Contributing\n\nSmall pull requests are fine to submit directly as pull requests. Larger changes should first be submitted as issues and mapped out before starting work on the proposal.\n\nPlease read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on the code of conduct, and the process for submitting pull requests.\n\n## Versioning\n\nThis project uses [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).\n\n## Authors\n\nSee the list of [contributors](./CONTRIBUTORS.txt) who have participated in this project.\n\nThis list can be updated with `make contributors`.\n\n## License\n\nThis project [is licensed under the MIT License](./LICENSE.md).\n\n## Acknowledgments\n\n* @PurpleBooth for [the README.md](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2) and [the CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) template files.", "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/captain-kark/module_resources", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "module-resources", "package_url": "https://pypi.org/project/module-resources/", "platform": "", "project_url": "https://pypi.org/project/module-resources/", "project_urls": { "Homepage": "https://github.com/captain-kark/module_resources" }, "release_url": "https://pypi.org/project/module-resources/0.2.0/", "requires_dist": null, "requires_python": "", "summary": "Import non-python files in a project directory as python namedtuple objects.", "version": "0.2.0" }, "last_serial": 5582374, "releases": { "0.1.11": [ { "comment_text": "", "digests": { "md5": "3df633720f65d547a73b81dfd43bd003", "sha256": "f609f1c7676cce61ecd3a8291e4ca54e097740773968dbeada968dc7e409dfb0" }, "downloads": -1, "filename": "module-resources-0.1.11.tar.gz", "has_sig": false, "md5_digest": "3df633720f65d547a73b81dfd43bd003", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5892, "upload_time": "2019-07-24T10:41:45", "url": "https://files.pythonhosted.org/packages/7e/ce/056ff0b9794044a1c9b10e0e2f739d1db93cf86dba3e9c3bf5c48d7f8fbc/module-resources-0.1.11.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "11d0aed876f0525f98d4a4d0a39c8779", "sha256": "f7282f06f20f817127cb81926519eb3ea29d6ecda2f4016e35bb8539869f6377" }, "downloads": -1, "filename": "module-resources-0.2.0.tar.gz", "has_sig": false, "md5_digest": "11d0aed876f0525f98d4a4d0a39c8779", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6051, "upload_time": "2019-07-25T09:41:13", "url": "https://files.pythonhosted.org/packages/bb/b3/8fb8bbb15e2084c6b7d1567c9f848dd8676e6e9a2f3df7535d444fd8b2f5/module-resources-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "11d0aed876f0525f98d4a4d0a39c8779", "sha256": "f7282f06f20f817127cb81926519eb3ea29d6ecda2f4016e35bb8539869f6377" }, "downloads": -1, "filename": "module-resources-0.2.0.tar.gz", "has_sig": false, "md5_digest": "11d0aed876f0525f98d4a4d0a39c8779", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6051, "upload_time": "2019-07-25T09:41:13", "url": "https://files.pythonhosted.org/packages/bb/b3/8fb8bbb15e2084c6b7d1567c9f848dd8676e6e9a2f3df7535d444fd8b2f5/module-resources-0.2.0.tar.gz" } ] }