{"id":13468052,"url":"https://github.com/Pebaz/nimporter","last_synced_at":"2025-03-26T03:31:28.179Z","repository":{"id":41142050,"uuid":"224948450","full_name":"Pebaz/nimporter","owner":"Pebaz","description":"Compile Nim Extensions for Python On Import!","archived":false,"fork":false,"pushed_at":"2024-06-14T06:04:49.000Z","size":2112,"stargazers_count":841,"open_issues_count":8,"forks_count":29,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-03-20T01:49:04.248Z","etag":null,"topics":["compiler","cython","cython-alternative","nim","nim-compiler","nim-source","nimporter-libraries","nimpy","performance","python","transpiler"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/Pebaz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["pebaz"]}},"created_at":"2019-11-30T02:24:53.000Z","updated_at":"2025-03-19T12:47:06.000Z","dependencies_parsed_at":"2024-01-14T03:50:28.158Z","dependency_job_id":"4a91a35b-e60f-44bc-a73e-64c63c6a850b","html_url":"https://github.com/Pebaz/nimporter","commit_stats":{"total_commits":523,"total_committers":10,"mean_commits":52.3,"dds":"0.22562141491395793","last_synced_commit":"f9db9bef97149278258008700ae77434eb6d31a2"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pebaz%2Fnimporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pebaz%2Fnimporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pebaz%2Fnimporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pebaz%2Fnimporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Pebaz","download_url":"https://codeload.github.com/Pebaz/nimporter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245584885,"owners_count":20639639,"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":["compiler","cython","cython-alternative","nim","nim-compiler","nim-source","nimporter-libraries","nimpy","performance","python","transpiler"],"created_at":"2024-07-31T15:01:04.771Z","updated_at":"2025-03-26T03:31:27.563Z","avatar_url":"https://github.com/Pebaz.png","language":"Python","readme":"\n\u003cp align=\"center\"\u003e\n    \u003cimg src=misc/nimporter-logo.svg\u003e\n\u003c/p\u003e\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;![License](https://img.shields.io/github/license/Pebaz/nimporter?color=F6B5A4)\n![Latest Release](https://img.shields.io/github/v/release/Pebaz/nimporter?sort=semver\u0026color=EB7590)\n![Lines of Code](https://img.shields.io/tokei/lines/github/Pebaz/Nimporter?label=lines%20of%20code\u0026color=C8488A)\n![Downloads each Month](https://img.shields.io/pypi/dm/Nimporter?label=pypi%20downloads\u0026color=872E93)\n![GitHub Repository Star Count](https://img.shields.io/github/stars/Pebaz/Nimporter?label=github%20stars\u0026color=581D7F)\n![GitHub Sponsor Count](https://img.shields.io/github/sponsors/Pebaz?label=github%20sponsors\u0026color=3A1353)\n\n# Nimporter\n\n\u003e *Directly import [Nim](\u003chttps://nim-lang.org/\u003e) extensions for Python and\nseamlessly package them for distribution in **1 line of code.***\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=misc/Nimporter-Functionality.png\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=misc/Nimporter-Setup.py.png\u003e\n\u003c/p\u003e\n\n## 🍱 Benefits\n\n* **🐆 Performance**: Nim compiles to C\n\n* **🚚 Distribution**: Packaging Nimporter libraries is the primary use case\n\n* **📦 Invisible**: End users do not need to install Nim for source or binary\n    distributions\n\n* **♻️ Ecosystem**: Leverage [Python](https://pypi.org/) libraries for breadth\n    and [Nim](https://nimble.directory/) libraries for performance.\n\n* **🧣 Seamless**: Integration with existing Nim code uses the\n    [Nimpy](https://github.com/yglukhov/nimpy) library.\n\n* **🎈 Simple**: Nimporter barely has a user interface at all\n\n## 🐣 Installation\n\n```bash\n# 🐍 From Pypi:\n$ pip install nimporter\n\n# ⚙️ From GitHub:\n$ pip install git+https://github.com/Pebaz/Nimporter\n```\n\n**Library Author Dependencies:**\n\n 1. [Nim Compiler](\u003chttps://nim-lang.org/install.html\u003e) (for compiling Nim\n    source files)\n 2. [Nimpy library](https://github.com/yglukhov/nimpy) (installed automatically\n    if `nimporter init lib` is used)\n 3. [Nimporter library](https://github.com/Pebaz/nimporter) (distributed\n    libraries will need access to Nimporter).\n\nNimporter can work seamlessly when Nim is installed via\n[Choosenim](https://nim-lang.org/install_unix.html#installation-using-choosenim)\nor manually. No additional configuration is necessary once installed since\nNimporter can find the Nim standard library and install\n[Nimpy library](https://github.com/yglukhov/nimpy) if Nimble is on your path.\n\n**End User Dependencies:**\n\nUsers of Nimporter libraries only need Nimporter! 🎉\n\n## 📚 Documentation\n\nTo get started, first look at the [Nimpy](https://github.com/yglukhov/nimpy)\nproject as that is how Nim libraries are created that can be imported into\nPython. During development, Python can directly import the Nim file and build\nthe public user-facing Python API in tandem with the Nim library extension. For\nassistance with the Nim language, look at\n[Nim For Python Programmers](https://github.com/nim-lang/Nim/wiki/Nim-for-Python-Programmers#table-of-contents)\nas it is a great resource for getting up to speed quickly with Nim. Finally,\nNimporter's unit tests all make use of a\n[reference project](https://github.com/Pebaz/nimporter/tree/master/tests/data)\nthat was designed to use each of Nimporter's features.\n\n* 🦔 [Nim For Python Programmers](https://github.com/nim-lang/Nim/wiki/Nim-for-Python-Programmers#table-of-contents)\n* 🦊 [Nimpy](https://github.com/yglukhov/nimpy)\n* 🔅 [Reference Project](https://github.com/Pebaz/nimporter/tree/master/tests/data)\n\nAdditionally, the\n[Nimpy tests folder](https://github.com/yglukhov/nimpy/tree/master/tests)\ncontains code examples on these topics:\n\n* Passing/Returning None, booleans, integers, floats, strings, lists, tuples, dictionaries, JSON, and objects.\n* Defining/Raising Python exceptions from Nim.\n* Yielding values back to Python using iterators in Nim.\n* Exposing Nim functions with custom names.\n* Exposing Nim extension modules with customized names and docstrings.\n* Using Python builtin functions in Nim.\n* Using passed Python objects and accessing methods and fields.\n* Passing keyword arguments to a Python function.\n\n## 📋 Features\n\n* Directly import Nim Extension Modules \u0026 Extension Libraries using Nimpy\n* Cache build artifacts for quicker subsequent runs\n* Invalidate cache using hash files\n* Stores artifacts and hash files in `__pycache__` to not clutter project\n* Build Source \u0026 Binary Distributions using Nimporer with 1 line of code\n* Command Line Interface for introspecting, initializing, and compiling\n    projects\n* Nimporter does not require that library end-users install a Nim compiler\n\n## 🛠️ Usage\n\n![Nimporter Structure](misc/NimporterStructure.png)\n\nNimporter is a library that allows the seamless import \u0026 packaging of Nim\nextensions for Python built with [Nimpy](https://github.com/yglukhov/nimpy).\nNimpy is a library that is used on the Nim side for iteroperability with\nPython. All Nimporter libraries rely on Nimpy in order to expose Nim functions\nto Python. Nimporter's role in this is to formalize a method of distributing\nNimpy libraries to ease the burden on library maintainers and end users so that\nthey do not have to even have knowledge of Nim in order to use the library.\n\nNimpy is a complete library by itself. For information on how to integrate Nim\nand Python, look at the\n[Nimpy documentation](https://github.com/yglukhov/nimpy) as it will be the Nim\nday-to-day development experience. Nimporter's role comes into play when a\nlibrary is ready to be distributed. **Nimporter handles the entire packaging\nfor source and binary distributions in 1 line of code.**\n\n**Important Considerations**\n\nNimporter was designed to help bridge the ecosystem gap between Python and Nim\nwhile utilizing Nimpy so that library authors could seamlessly develop and\ndistribute their libraries. Due to this fact, there are important limitations\nto consider when using Nimporter. They are described below:\n\n1. Importing: Nimporter uses the C compiler that was used to build Python when\n    importing a Nim module/library. This can be overridden in a\n    `\u003clib name\u003e.nim.cfg` but doing so means that the library will most likely\n    not work on other platforms.\n\n2. Distributing Sources: Nimporter sets the C compiler automatically by\n    iterating through MSVC and GCC for each platform and architecture combo.\n    This means that there will likely be several copies of the generated C\n    source code for each supported platform (given in `get_nim_extensions()`).\n\n3. Distributing Binaries: Nimporter uses the same process described for direct\n    import of Nim code and will use the same C compiler that was used to build\n    Python itself.\n\n### 🎻 Instrumentation\n\nTo enable Nimporter debug traces, define `NIMPORTER_INSTRUMENT` in the\nenvironment and Nimporter will use\n[IceCream](https://github.com/gruns/icecream) to show output from Nim and other\ninteresting bits necessary for debugging any issues that could arise.\n\n### 🦓 Extension Modules \u0026 Extension Libraries\n\nExtension Modules are distinct from Extension Libraries. Nimporter (not Nimpy)\nmakes a distinction here. However, it is of special note that distribution of\neither extension type is the same (`nimporter.get_nim_extensions()`).\n\n**🦄 Extension Libraries**\n\nExtension Libraries are entire Nim projects exposed as a single module from the\nperspective of Python. They are comprised of a single folder containing all\ncode and configuration for the extension. *It is important to note that they\nare a concept formalized by the Nimporter project and must accept some\nlimitations.*\n\nThese limitations (and capabilities) are listed below:\n\n* ✔️ Can have external Nim dependencies: inside the Extension Library folder,\n    use a `\u003clibrary name\u003e.nimble` in order to depend upon other Nim libraries.\n\n* ✔️ Can be split up into any number of Nim modules: the Extension Library\n    folder can contain any desired inner folder structure.\n\n* ✔️ CLI switches used by Nim \u0026 the C compiler can be customized: this can be\n    useful but be cognizant about cross-platform compatibility. Remember, if\n    the C compiler used by Python is different than the one used by Nim, there\n    *will definitely without a doubt* be strange issues arising from this. Note\n    that choosing a different C compiler may result in the `setup.py` not being\n    able to compile the extension. Use a `\u003clibrary name\u003e.nim.cfg` for this use\n    case.\n\n* ❌ Must use folder structure known to Nimporter: the below folder structure\n    is generated when `nimporter init lib` is used:\n\n    ```\n    the_library_name/\n        the_library_name.nim  # Must be present\n        the_library_name.nim.cfg  # Must be present even if empty\n        the_library_name.nimble  # Must contain `requires \"nimpy\"`\n    ```\n**🐴 Extension Modules**\n\nExtension Modules are the simplest form of using Nimpy libraries with existing\nPython code. Once Nimporter is imported, Nimpy libraries can be directly\nimported like normal Python modules. However, there are a few restrictions on\nwhat is supported when importing a Nim module in this way. It is important to\nremember that Nim compiles to C and therefore could theoretically integrate\nwith a build system that is extremely brittle. To completely solve this,\nNimporter disallows certain use cases that are technically possible but would\notherwise prevent widespread use of the resulting technology.\n\nBelow are the restrictions present when importing a Nim Extension Module:\n\n* ❌ Cannot have any dependencies other than `Nimpy`: this is due to the fact\n    that Nimporter disallows multiple `*.nimble` files strewn about in a Python\n    project. Use an Extension Library for this use case.\n\n* ❌ Cannot import other Nim modules in same directory: this is because there\n    is no way to tell which files pertain to each extension and knowing this is\n    a prerequisite to packaging the extension up for distribution.\n    Additionally, Nimporter moves extensions to temporary directories during\n    compilation in order to control where the Nim compiler places the resultant\n    C sources.\n\n* ❌ Cannot customize Nim or C compiler switches: proliferating a Python\n    package with these extra files would be unsightly and it is possible to\n    have two different Nim modules with custom configurations collide in\n    awkward ways. If CLI configuration is required, use an Extension Library.\n\n* ❌ Cannot override the C compiler used to build the extension: Although this\n    practice is certainly and technically possible, it is unequivocally a bad\n    decision when integrating software originating from a different compilers.\n    If an expert user is in need of this capability, use an Extension Library.\n\nAlthough these restrictions limit the number of possible use cases for the\nintegration of Nim \u0026 Python, portability, compatibility, and stability were\nchosen as the guiding principles for Nimporter.\n\n## 📦 Distribution\n\nThere are a few ways to use Nimporter to integrate Nim \u0026 Python code:\n\n1. 🥇 Library uses Nim code internally but exposes a Python API: this is the\n    reason why Nimporter was built. It was built to allow Python library\n    authors to use Nim to speed up their library.\n\n2. 🥈 Application uses Nim code: this is very possible but it is recommended to\n    pull out the Nim code into a Python library that imports that Nim code in\n    order to take advantage of the amazing distribution features of Nimporter.\n    Having a separately-updatable library that the application imports greatly\n    streamlines development and reduces packaging difficulty (the Python\n    library dependency that imports Nim code behaves exactly like a pure-Python\n    dependency).\n\n3. 🥉 Docker: this is a possible application of Nimporter, but it requires the\n    use of `nimporter compile` in order to let the Docker container not have to\n    contain a Nim \u0026 C compiler and to ensure that the builds are cached.\n\nAmazingly, Nimporter allows the end user installing a library built with\nNimporter to not have to install Nim! 🥳 This is incredible and is accomplished\nby recompiling the same Nim extension to every desired platform, architecture,\nand C compiler that the library is supported on. Specifically, Nimporter tells\nthe Nim compiler to compile the extension to C once for Windows, MacOS, and\nLinux and and then bundles all of the resulting C source files into the source\ndistribution. At the time of the installation on the end user's machine, the\nappropriate set of C source files is selected that matches the user's\nenvironment! 🙂\n\nFor binary distributions, this process just skips to the one set of C source\nfiles that matches the host's environment. One binary distribution per\nsupported platform must then be built.\n\nThis might sound complicated but Nimporter accomplishes this by requesting that\nthe `setup.py` contain 1 line of code to find, compile, and bundle all of the C\nfiles necessary to be portable across platform, architecture, and C compilers.\n\n### 📧 Source Distributions\n\nTo create a source distribution, it is assumed that the `setup.py` contains a\ndependency on Nimporter as well as a call to `get_nim_extensions()`.\n\n```python\n# Example setup.py\n\nimport setuptools\nfrom nimporter import get_nim_extensions, WINDOWS, MACOS, LINUX\n\nsetuptools.setup(\n    name='calculatorlib',\n    install_requires=['nimporter'],\n    py_modules=['calculatorlib.py'],\n    ext_modules=get_nim_extensions(platforms=[WINDOWS, LINUX, MACOS])\n)\n```\n\nThe below command will create a source distribution in the `dist/` directory\nand can be easily uploaded to PyPI.\n\n```bash\n$ python setup.py sdist  # Contains entire matrix of supported platforms, etc.\n```\n\n\u003e Note: when an end-user tries to install a Nimporter library from GitHub\n    directly, it is required that the Nim compiler and a compatible C compiler\n    is installed because `setup.py install` is invoked which is equivalent to a\n    binary distribution but does require the Nim \u0026 C compilers to be installed.\n\n### 💿 Binary Distributions\n\nBinary distributions use the same `setup.py` structure mentioned above.\n\nThe below command will create a Python Wheel in the `dist/` directory that can\nbe easily uploaded to PyPI.\n\n```bash\n$ python setup.py bdist_wheel  # Contains a single supported platform, etc.\n```\n\n\u003e Note: A Nim compiler and C compiler is required when creating a binary\n    distribution.\n\n\u003e Special note for Linux users: Unfortunately, PyPi will not allow you to\n    upload just any Linux wheel. There is a special compilation process that\n    can be explained [here](https://github.com/pypa/manylinux). Interestingly\n    enough, I got around this by simply renaming the resulting Linux build\n    according to the **manylinux1** naming convention. You can see my solution\n    in the `examples/github_actions_template.yml` file for the `build-linux`\n    job. I expect that there could be many downsides of using this hack but it\n    worked for me on 2 different Linux platforms.\n\n### ⭕ Publish Build Artifacts to PyPi Automatically\n\nFor a dead-simple way to publish Windows, MacOS, and Linux packages to PyPi\nautomatically, use the `github_actions_template.yml` template found in the\n`examples/` directory. This template integrates with your repository's GitHub\nActions runner to build, package, and deploy your library on Windows, MacOS,\nand Linux automatically when you create a new \"Release\" is created.\n\n## 💽 Computer Hardware Actually Exists\n\nDynamic, safe programming languages are great, but naturally, when integrating\nwith native code, there are limitations to what is possible to accomplish in\ncertain situations. On Windows, a DLL that has been loaded into a process\ncannot be deleted while it is in use. Additionally, Windows has a path length\nlimit of 260 characters by default (and therefore relying on the user having\ndisabled this limit in the system registry is not possible). This severely\nlimits how deep a Nim extension can be placed into a Python package hierarchy.\nFurthermore, generously-named Nim extensions may fail to compile with a message\nthat resembles:\n\n```\nfailed to open compiler generated file: ''\n```\n\n\u003e If this message occurs, it is due to the path length limit of 260 characters.\n    Shorten the name of the Nim extension and make the package hierarchy\n    shallower. More information about the 260 character path limit can be found\n    [here](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd).\n\nNimporter comes with a defense against this behavior by automatically renaming\nthe generated C sources to not contain the `@m` and `@s` symbols that\nproliferate the filename and soak up most of the 260 character budget. For\ninstance, the filename:\n\n```\n@m..@s..@s..@s..@s..@s..@sUsers@s\u003cUSERNAME\u003e@s.nimble@spkgs@snimpy-0.2.0@snimpy@spy_utils.nim.c\n```\n\nGets turned into:\n\n```\nNIMPORTER@nimpy-0.2.0@nimpy@py_utils.nim.c\n```\n\nMuch shorter! 🚀\n\n## 🧑‍💻 Nimporter Command Line Interface\n\nNimporter provides a CLI that you can use to easily clean all cached build and\nhash files from your project recursively. This can be very useful for debugging\nsituations arising from stale builds.\n\nUsage example:\n\n```bash\n# Removes all __pycache__ directories with .hash, .pyd/.so, and .pyc files\n$ nimporter clean\n```\n\nThe Nimporter CLI can also precompile all extensions within a project without\nneeding to run the project. This is useful in situations where you do not want\nto package your application using a `setup.py` (such as a zip file) or for use\nwithin Docker containers.\n\n```bash\n# Recursively compile all Nim extension modules and libraries:\n$ nimporter compile\n```\n\nFinally, the CLI has provisions for listing out the extensions that it can\nauto-detect. This is useful to identify if an extension folder structure is\nproperly setup.\n\n```bash\n# List all extensions that Nimporter will find when handling imports\n$ nimporter list\n```\n\n## ⚓ Usage with Docker\n\nNimporter can easily be used within a Docker container. To prevent the need for\na Nim compiler toolchain to be installed into the container to run Nim code,\nthe extensions can be precompiled and copied into the container. This process\nis roughly as follows:\n\n1. Create a project that uses Python and Nim\n2. Run `nimporter compile` to recursively-compile all extensions in the project\n3. Ensure that in your Dockerfile that the `__pycache__` directories are\n   included as they will contain the Nim shared objects as well as the\n   Nimporter hash files to prevent a recompilation (which would fail without a\n   Nim \u0026 C compiler installed in the container).\n\n## 🧪 Running The Tests\n\nTo run Nimporter's test suite on your local machine, you will need to install a\nNim compiler. This example will assume you are cloning the GitHub repository.\n\n```bash\n$ git clone https://github.com/Pebaz/Nimporter\n$ cd Nimporter\n$ pip install -r requirements_dev.txt\n$ pip install .  # Nimporter is needed for the integration tests\n$ pytest --cov=. --cov-report=html tests\n```\n\n## ❓ How Does Nimporter Work?\n\nNimporter provides essentially two capabilities:\n\n* The ability to directly import Nim code\n* The ability to bundle Python-compatible extensions for any supported platform\n\nThe way it accomplishes the ability to import Nim code is by adding two custom\nimporters to the Python import machinery. This is why it is required to import\nNimporter before importing any Nim code because the Python import machinery\nmust be amended with the custom importers.\n\nThe first one is for the ability to search and import Nim modules. When a Nim\nmodule is found, Nimporter first looks in the `__pycache__` directory to see if\nthere is already a built version of the module. If there is not, it builds a\nnew one and stores it in the `__pycache__` directory.\n\nIf one is found, it could be stale, meaning the Nim file could have been\nmodified since it was built. To keep track of this, a hash of the source file\nis also kept in the `__pycache__` directory and is consulted whenever there is\na possibility that a stale build could be imported.\n\nWhen a Nim module and a Python module have the same name and reside in the same\nfolder, the Python module is given precedence. *Please don't do this.*\n\nThe second custom importer has the exact same purpose of the first one except\nit is used to import Nim extension libraries. A library is any folder within a\nPython project that contains a `\u003clib name\u003e.nim`, a `\u003clib name\u003e.nimble`, and a\n`\u003clib name\u003e.nim.cfg`.\n\nThese files mark that the folder should be treated as one unit. It also makes\nit so that Nimble dependencies can be installed.\n\nAs for the second capability, Nimporter helps you bundle and distribute Nim\ncode as part of a source or binary distribution extremely easily.\n\nThe way it works is by iterating through your entire project and identifying\nany Nim module and Nim library that it finds and compiling them to C using a\nfeature of Nim that specifically supports this.\n\nWhy compile to C? Because Python already has extensive infrastructure to\nsupport the compilation and distribution of C extensions.\n\nOnce each Nim module and library is compiled to C, Python deals with them the\nexact same way as a typical C extension. These extensions are then bundled into\nthe resulting binary distribution and can be uploaded to PyPi or similar.\n\nFor source distributions, Nimporter instructs the Nim compiler to output a copy\nof the generated C code for each platform, architecture, and C compiler that is\nsupported by the library author (some libraries only make sense to work on\nWindows for example like DirectX). It then bundles all of these as individual C\nextensions into the source distribution. At installation time, Nimporter then\nselects the C extension that matches the end-user's host machine target triple.\n\n## 👷 Contributing\n\n[Pull requests](https://github.com/Pebaz/nimporter/pulls) are welcome,\nespecially for fixing bugs! 😁\n\nFeel free to [open an issue](https://github.com/Pebaz/nimporter/issues) if\nsomething seems to be broken but please look through the README first if time\nallows.\n\n## 👏 Special Thanks\n\nNimporter would not be possible without\n[Nimpy](https://github.com/yglukhov/nimpy). Thank you\n[Yuriy Glukhov](https://github.com/yglukhov) for making this project possible!\n\n## 🌠 Stargazers Over Time\n\n[![Stargazers Over Time](https://starchart.cc/Pebaz/nimporter.svg)](https://starchart.cc/Pebaz/nimporter)\n\n\u003e Made using \u003chttps://starchart.cc/\u003e\n","funding_links":["https://github.com/sponsors/pebaz"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPebaz%2Fnimporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPebaz%2Fnimporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPebaz%2Fnimporter/lists"}