{"id":24635070,"url":"https://github.com/desty2k/paker","last_synced_at":"2025-05-08T20:57:50.253Z","repository":{"id":45185702,"uuid":"368455658","full_name":"desty2k/paker","owner":"desty2k","description":"Import Python modules from dicts and JSON formatted documents.","archived":false,"fork":false,"pushed_at":"2022-02-15T18:45:12.000Z","size":561,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-08T20:57:38.889Z","etag":null,"topics":["finder","importer","in-memory","json","loader","memimporter","modules","packages","paker","python"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/desty2k.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-18T08:26:45.000Z","updated_at":"2024-11-06T12:10:46.000Z","dependencies_parsed_at":"2022-09-02T06:43:39.837Z","dependency_job_id":null,"html_url":"https://github.com/desty2k/paker","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desty2k%2Fpaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desty2k%2Fpaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desty2k%2Fpaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desty2k%2Fpaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/desty2k","download_url":"https://codeload.github.com/desty2k/paker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253149568,"owners_count":21861719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["finder","importer","in-memory","json","loader","memimporter","modules","packages","paker","python"],"created_at":"2025-01-25T09:14:19.656Z","updated_at":"2025-05-08T20:57:50.227Z","avatar_url":"https://github.com/desty2k.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Paker\n\n[![Build](https://github.com/desty2k/paker/actions/workflows/build.yml/badge.svg)](https://github.com/desty2k/paker/actions/workflows/build.yml)\n[![Version](https://img.shields.io/pypi/v/paker)](https://pypi.org/project/paker/)\n[![Version](https://img.shields.io/pypi/dm/paker)](https://pypi.org/project/paker/)\n\n\nPaker is module for importing Python packages/modules from dictionaries and JSON formatted documents. \nIt was inspired by [httpimporter](https://github.com/operatorequals/httpimport).\n\n__Important:__ Since v0.6.0 `paker` supports importing `.pyd` and `.dll` modules directly from memory. \nThis was achieved by using `_memimporter` from [py2exe](https://github.com/py2exe/py2exe) project.\nImporting `.so` files on Linux still requires writing them to disk.\n\n## Installation\nFrom PyPI\n\n```shell\npip install paker -U\n```\n\nFrom source\n\n```shell\ngit clone https://github.com/desty2k/paker.git\ncd paker\npip install .\n```\n\n## Usage\n\nLet's use `paker` to dump `print_lib` module with following directory structure:\n```\nprint_lib/\n├── __init__.py\n├── capitalize.py\n└── decapitalize.py\n ```\n`capitalized.py` contains `Print` function and `decapitalized.py` contains `pRINT` function. `__init__.py` file is empty.\n\n### Dumping to JSON\nTo dump the library to a file use `paker dump` command:\n```shell\npaker dump print_lib --indent 4\n```\nPaker will create new file `print_lib.json` in the current directory.\n```json\n{\n    \"print_lib\": {\n        \"type\": \"package\",\n        \"extension\": \"py\",\n        \"code\": \"\",\n        \"modules\": {\n            \"capitalize\": {\n                \"type\": \"module\",\n                \"extension\": \"py\",\n                \"code\": \"def Print(text: str, *args, **kwargs):\\n    print(text.capitalize(), *args, **kwargs)\\n\"\n            },\n            \"decapitalize\": {\n                \"type\": \"module\",\n                \"extension\": \"py\",\n                \"code\": \"def pRINT(text: str, *args, **kwargs):\\n    print(text[0].lower() + text[1:].upper(), *args, **kwargs)\\n\"\n            }\n        }\n    }\n}\n```\n### Listing modules\nTo list all modules in the JSON use `paker list` command:\n```shell\npaker list print_lib.json\n```\n\nOutput:\n```text\nP print_lib\nM print_lib.capitalize\nM print_lib.decapitalize\n```\n\n### Recreating package from JSON\nTo recreate the package from the JSON use `paker load` command.\n```shell\npaker load print_lib.json\n```\n`print_lib` package will be created in the current directory. To set custom output path use `--output` option.\n\n### Importing from `.json`\n__Note:__ Importing from original source code has higher priority than importing from JSON. \nRemember to remove module from disk before importing the library with `paker`.\n\n```python\nimport paker\nimport logging\n\nlogging.basicConfig(level=logging.NOTSET)\n\nif __name__ == '__main__':\n    with open(\"print_lib.json\", \"r\") as f:\n        with paker.load(f) as loader:\n            # print_lib will be available only in this context\n            from print_lib.capitalize import Print\n            from print_lib.decapitalize import pRINT\n            Print(\"hello world!\")\n            pRINT(\"hello world!\")\n```\n\nThis script produces the following output:\n```text\nDEBUG:jsonimporter:searching for print_lib\nINFO:jsonimporter:print_lib has been imported successfully\nDEBUG:jsonimporter:searching for print_lib.capitalize\nINFO:jsonimporter:print_lib.capitalize has been imported successfully\nDEBUG:jsonimporter:searching for print_lib.decapitalize\nINFO:jsonimporter:print_lib.decapitalize has been imported successfully\n\nHello world!\nhELLO WORLD!\n\nINFO:jsonimporter:unloaded all modules\n```\n\n### Importing from memory\n\nYou can also import Python modules directly from memory. \nLibraries can be loaded not only from Python `dict` objects, but also from `str`, `bytes` and `bytearray` objects. \n\n```python\nimport paker\nimport logging\n\n# paker.loads accepts dict, str, bytes and bytearray objects\nPOW = {\"pow\": {\"type\": \"module\", \"extension\": \"py\", \"code\": \"pow = lambda x, y: x**y\"}}\nSQR = '{\"sqr\": {\"type\": \"module\", \"extension\": \"py\", \"code\": \"from pow import pow\\\\nsqr = lambda x: pow(x, 2)\"}}'\nTRI = b'{\"tri\": {\"type\": \"module\", \"extension\": \"py\", \"code\": \"from pow import pow\\\\ntri = lambda x: pow(x, 3)\"}}'\n\nlogging.basicConfig(level=logging.NOTSET)\n\nif __name__ == '__main__':\n    # you can use nested loaders\n    with paker.loads(POW) as pow_loader:\n        # pow will be available only in this context\n        with paker.loads(SQR) as sqr_loader:\n            # sqr will be available only in this context\n            from sqr import sqr\n            assert sqr(2), 4\n            assert sqr(5), 25\n            print(\"6**2 is {}\".format(sqr(6)))\n\n        with paker.loads(TRI) as tri_loader:\n            # tri will be available only in this context\n            from tri import tri\n            assert tri(2), 8\n            assert tri(5), 125\n            print(\"6**3 is {}\".format(tri(6)))\n        print(\"It works!\")\n\n```\nThis script produces the following output:\n```text\nDEBUG:jsonimporter:searching for sqr\nINFO:jsonimporter:sqr has been added successfully\nDEBUG:jsonimporter:searching for sqr\nDEBUG:jsonimporter:searching for pow\nINFO:jsonimporter:pow has been imported successfully\nINFO:jsonimporter:sqr has been imported successfully\n\n6**2 is 36\n\nINFO:jsonimporter:sqr has been unloaded successfully\nDEBUG:jsonimporter:searching for tri\nINFO:jsonimporter:tri has been added successfully\nDEBUG:jsonimporter:searching for tri\nINFO:jsonimporter:tri has been imported successfully\n\n6**3 is 216\n\nINFO:jsonimporter:tri has been unloaded successfully\n\nIt works!\n\nINFO:jsonimporter:unloaded all modules\n```\n\n\n## How it works\n\nWhen importing modules or packages Python iterates over [importers](https://docs.python.org/3/glossary.html#term-importer) in `sys.meta_path` and calls `find_module` method on each object.\nIf the importer returns itself, it means that the module can be imported and `None` means that importer did not find searched package.\nIf any importer has confirmed the ability to import module, Python executes another method on it - `load_module`.\nPaker implements its own importer called `jsonimporter`, which instead of searching for modules in directories, looks for them in Python dictionaries\n\nTo dump module or package to JSON document, Paker recursively iterates over modules and creates dict with \ncode and type of each module and submodules if object is package.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesty2k%2Fpaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdesty2k%2Fpaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesty2k%2Fpaker/lists"}