{"id":20466029,"url":"https://github.com/withprecedent/miller","last_synced_at":"2026-05-26T23:03:53.665Z","repository":{"id":65434899,"uuid":"414282766","full_name":"WithPrecedent/miller","owner":"WithPrecedent","description":"Easy-to-use Python introspection tools with a consistent, intuitive syntax","archived":false,"fork":false,"pushed_at":"2023-09-29T16:42:47.000Z","size":1015,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-16T22:34:53.762Z","etag":null,"topics":["introspection","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WithPrecedent.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2021-10-06T16:10:13.000Z","updated_at":"2023-07-18T09:07:26.000Z","dependencies_parsed_at":"2024-11-15T13:32:22.609Z","dependency_job_id":null,"html_url":"https://github.com/WithPrecedent/miller","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":0.04166666666666663,"last_synced_commit":"9777a712434001cee6cb76322d28b91ac660b40e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fmiller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fmiller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fmiller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fmiller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WithPrecedent","download_url":"https://codeload.github.com/WithPrecedent/miller/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242027456,"owners_count":20060100,"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":["introspection","python"],"created_at":"2024-11-15T13:21:07.780Z","updated_at":"2026-05-26T23:03:48.632Z","avatar_url":"https://github.com/WithPrecedent.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# miller\n\n| | |\n| --- | --- |\n| Version | [![PyPI Latest Release](https://img.shields.io/pypi/v/miller.svg?style=for-the-badge\u0026color=steelblue\u0026label=PyPI\u0026logo=PyPI\u0026logoColor=yellow)](https://pypi.org/project/miller/) [![GitHub Latest Release](https://img.shields.io/github/v/tag/WithPrecedent/miller?style=for-the-badge\u0026color=navy\u0026label=GitHub\u0026logo=github)](https://github.com/WithPrecedent/miller/releases)\n| Status | [![Build Status](https://img.shields.io/github/actions/workflow/status/WithPrecedent/miller/ci.yml?branch=main\u0026style=for-the-badge\u0026color=cadetblue\u0026label=Tests\u0026logo=pytest)](https://github.com/WithPrecedent/miller/actions/workflows/ci.yml?query=branch%3Amain) [![Development Status](https://img.shields.io/badge/Development-Active-seagreen?style=for-the-badge\u0026logo=git)](https://www.repostatus.org/#active) [![Project Stability](https://img.shields.io/pypi/status/miller?style=for-the-badge\u0026logo=pypi\u0026label=Stability\u0026logoColor=yellow)](https://pypi.org/project/miller/)\n| Documentation | [![Hosted By](https://img.shields.io/badge/Hosted_by-Github_Pages-blue?style=for-the-badge\u0026color=navy\u0026logo=github)](https://WithPrecedent.github.io/miller)\n| Tools | [![Documentation](https://img.shields.io/badge/MkDocs-magenta?style=for-the-badge\u0026color=deepskyblue\u0026logo=markdown\u0026labelColor=gray)](https://squidfunk.github.io/mkdocs-material/) [![Linter](https://img.shields.io/endpoint?style=for-the-badge\u0026url=https://raw.githubusercontent.com/charliermarsh/Ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/Ruff) [![Dependency Manager](https://img.shields.io/badge/PDM-mediumpurple?style=for-the-badge\u0026logo=affinity\u0026labelColor=gray)](https://PDM.fming.dev) [![Pre-commit](https://img.shields.io/badge/pre--commit-darkolivegreen?style=for-the-badge\u0026logo=pre-commit\u0026logoColor=white\u0026labelColor=gray)](https://github.com/TezRomacH/python-package-template/blob/master/.pre-commit-config.yaml) [![CI](https://img.shields.io/badge/GitHub_Actions-navy?style=for-the-badge\u0026logo=githubactions\u0026labelColor=gray\u0026logoColor=white)](https://github.com/features/actions) [![Editor Settings](https://img.shields.io/badge/Editor_Config-paleturquoise?style=for-the-badge\u0026logo=editorconfig\u0026labelColor=gray)](https://editorconfig.org/) [![Repository Template](https://img.shields.io/badge/snickerdoodle-bisque?style=for-the-badge\u0026logo=cookiecutter\u0026labelColor=gray)](https://www.github.com/WithPrecedent/miller) [![Dependency Maintainer](https://img.shields.io/badge/dependabot-navy?style=for-the-badge\u0026logo=dependabot\u0026logoColor=white\u0026labelColor=gray)](https://github.com/dependabot)\n| Compatibility | [![Compatible Python Versions](https://img.shields.io/pypi/pyversions/miller?style=for-the-badge\u0026color=steelblue\u0026label=Python\u0026logo=python\u0026logoColor=yellow)](https://pypi.python.org/pypi/miller/) [![Linux](https://img.shields.io/badge/Linux-lightseagreen?style=for-the-badge\u0026logo=linux\u0026labelColor=gray\u0026logoColor=white)](https://www.linux.org/) [![MacOS](https://img.shields.io/badge/MacOS-snow?style=for-the-badge\u0026logo=apple\u0026labelColor=gray)](https://www.apple.com/macos/) [![Windows](https://img.shields.io/badge/windows-blue?style=for-the-badge\u0026logo=Windows\u0026labelColor=gray\u0026color=orangered)](https://www.microsoft.com/en-us/windows?r=1)\n| Stats | [![PyPI Download Rate (per month)](https://img.shields.io/pypi/dm/miller?style=for-the-badge\u0026color=steelblue\u0026label=Downloads%20💾\u0026logo=pypi\u0026logoColor=yellow)](https://pypi.org/project/miller) [![GitHub Stars](https://img.shields.io/github/stars/WithPrecedent/miller?style=for-the-badge\u0026color=navy\u0026label=Stars%20⭐\u0026logo=github)](https://github.com/WithPrecedent/miller/stargazers) [![GitHub Contributors](https://img.shields.io/github/contributors/WithPrecedent/miller?style=for-the-badge\u0026color=navy\u0026label=Contributors%20🙋\u0026logo=github)](https://github.com/WithPrecedent/miller/graphs/contributors) [![GitHub Issues](https://img.shields.io/github/issues/WithPrecedent/miller?style=for-the-badge\u0026color=navy\u0026label=Issues%20📘\u0026logo=github)](https://github.com/WithPrecedent/miller/graphs/contributors) [![GitHub Forks](https://img.shields.io/github/forks/WithPrecedent/miller?style=for-the-badge\u0026color=navy\u0026label=Forks%20🍴\u0026logo=github)](https://github.com/WithPrecedent/miller/forks)\n| | |\n\n-----\n\n## What is miller?\n\n*This package is under heavy construction. Use at your own risk*\n\n*\"I'm a tool that finds things.\"* - Detective Josephus Miller\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://media.giphy.com/media/l44Q6pEdnMOQqHgek/giphy.gif\" height=\"300\"/\u003e\n\u003c/p\u003e\n\nNamed after the erstwhile inspector from *The Expanse*, this package provides convenient, introspection tools using a consistent, intuitive syntax for packages, modules, classes, objects, attributes, and containers. \n\n## Why use miller?\n\n### Universal\n\nConsider the different and often difficult-to-read syntax that Python uses for\nintrospection of different objects.\n\n``` python\n\"\"\"Returns a list of function names in the module 'item'.\"\"\"\n[m[0] for m in inspect.getmembers(item, inspect.isfunction) \n if m[1].__module__ == item.__name__]\n\n\"\"\"Returns names of properties of the instance 'item'.\"\"\"\n[a for a in dir(item) if isinstance(getattr(a, item), property)] \n\n\"\"\"Returns names of fields of the dataclass 'item'.\"\"\"\n[f.name for f in dataclasses.fields(item)] \n```\n\nThat code can be difficult to remember, requires importing a range of packages, and is not easy to understand if you are not familiar with the relevant imported packages. \n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://media.giphy.com/media/3oz8xxBsDMZWcMCHoQ/giphy.gif\" height=\"300\"/\u003e\n\u003c/p\u003e\n\nIn contrast, **miller** uses simple, easy-to-read code for each of the above requests:\n\n``` python\nname_functions(item)\nname_properties(item)\nname_fields(item)\n```\n\nIn addition, each of those **miller** functions includes a boolean parameter `include_privates` which indicates whether you want to include any matching items that have str names beginning with an underscore.\n\n### Intuitive\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://media.giphy.com/media/PiqvXUF6UI6enzyNY9/giphy.gif\" height=\"300\"/\u003e\n\u003c/p\u003e\n\nUnlike the default Python instrospection functions and methods, **miller** uses a consistent syntax and structure that is far more intuitive. This allows users to guess what the appropriate syntax should by following a simple, consistent structure.\n\n**miller** uses five basic prefixes for its introspection functions:\n\n| prefix   | what it does   | returns   |\n|---|---|---|\n| `map`  |combines results of corresponding  `name` and `get` functions into a `dict`  | `dict[str, Any]`   |\n| `get`  | gets sought types from an item  |   `list[Any]`   |\n| `has`  | whether an item has specified types  |   `bool`   |\n| `is` | whether an item is a type  |   `bool`   |\n| `name` | gets `str` names of sought types from an item  |   `list[str]`   |\n\nThose prefixes are followed by an underscore and a suffix indicating what information is sought. **miller** has XXX possible suffixes for each of those prefixes:\n| suffix  | what it concerns   | what types it inspects   |\n|---|---|---|\n| `annotations`  | class, function, or method annotations   | `object`, `Type`, or `ModuleType`  |\n| `attribute`  | an attribute (including methods) of a class  | attribute in an `object` or `Type` |\n| `attributes`  | attributes (including methods or functions)  |  `object`, `Type`, or `ModuleType`  |\n| `class`  | a class (not an instance)  | `object` or `Type` |\n| `classes`  | classes in a module    | `ModuleType`   |\n| `class_attribute`  | attributes of a class (not an instance)  | `object` or `Type` |\n| `class_attributes`  | attributes of a class (not an instance)    | `object` or `Type`    |\n| `field`  | field in a dataclass  | `dataclass` or `Type[dataclass]` |\n| `fields`  | fields in a dataclass  | `dataclass` or `Type[dataclass]`  |\n| `file_path`  | path of a file | `str` or `Path`  |\n| `file_paths`  | paths of files in a path  | `str` or `Path`  |\n| `folder_path`  | path of a folder  | `str` or `Path`  |\n| `folder_paths`  | paths of folders in a path   | `str` or `Path`  |\n| `function`  | a callable function  | `object`|\n| `functions`  | functions in a module  | `ModuleType`  |\n| `instance`  | a class instance (not a class)  | `object` or `Type` |\n| `method`  | method in a class  | attribute in an `object` or `Type` |\n| `methods`  | class or instance methods  | `object` or `Type`   |\n| `module`  | module types  | `object` or `Type` |\n| `modules`  | paths of modules in a path   |  `str` or `Path`  |\n| `path`  | path on disk  | `str` or `Path` |\n| `paths`  | combination of file_paths and folder_paths  | `str` or `Path`   |\n| `property`  | attributes of a class  | attribute in an `object` |\n| `properties`  | properties of a class  | `object` or `Type`   |\n| `signatures`  | class, function, or method signatures  | `object`, `Type`, or `ModuleType`    |\n| `variable`  | attributes (excluding methods) of a class | `object`, `Type`, or `ModuleType`   |\n| `variables`  | an attribute (excluding methods or functions)  |  `object`, `Type`, or `ModuleType`   |\n\nThe following functions are available in **miller** for the `map`, `get`, `has`, and `name`  suffixes :\n\n| prefix/suffix | `map`  | `get`  | `has`  | `name`  |\n|---|---|---|---|---|\n| `annotations` | X | X | X | X |\n| `attributes` | X | X | X | X |\n| `classes` | X | X | X | X |\n| `fields` | X | X | X | X |\n| `file_paths` | X | X | X | X |\n| `folder_paths` | X | X | X | X |\n| `functions` | X | X | X | X |\n| `methods` | X | X | X | X |\n| `modules` | X | X | X | X |\n| `paths`  | X | X | X | X |\n| `properties` | X | X | X | X |\n| `signatures` | X | X | X | X |\n| `variables` | X | X | X | X |\n\nFor the `is` prefix, functions with the following suffixes are included: \n\n So, for example, \n\n* `map_methods`: returns a dict of the method names and methods of an object.\n* `list_methods`: returns a list of methods of an object.\n* `has_methods`: returns whether an object has all of the named methods passed to the `methods` parameter.\n* `is_method`: returns whether an item is a method of an object.\n* `name_methods`: returns a list of names of methods of an object.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://media.giphy.com/media/l0Ex6Yb0meOZQloWs/giphy.gif\" height=\"300\"/\u003e\n\u003c/p\u003e\n\n\n## Getting started\n\n*“Go into a room too fast, kid… The room eats you.”*  - Detective Josephus\nMiller\n\n\n### Requirements\n\n[TODO: List any OS or other restrictions and pre-installation dependencies]\n\n### Installation\n\nTo install `miller`, use `pip`:\n\n```sh\npip install miller\n```\n\n### Usage\n\n[TODO: Describe common use cases, with possible example(s)]\n\n## Contributing\n\nContributors are always welcome. Feel free to grab an [issue](https://www.github.com/WithPrecedent/miller/issues) to work on or make a suggested improvement. If you wish to contribute, please read the [Contribution Guide](https://www.github.com/WithPrecedent/miller/contributing.md) and [Code of Conduct](https://www.github.com/WithPrecedent/miller/code_of_conduct.md).\n\n## Similar Projects\n\n[TODO: If they exist, it is always nice to acknowledge other similar efforts]\n\n## Acknowledgments\n\n[TODO: Mention any people or organizations that warrant a special acknowledgment]\n\n## License\n\nUse of this repository is authorized under the [Apache Software License 2.0](https://www.github.com/WithPrecedent/miller/blog/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithprecedent%2Fmiller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwithprecedent%2Fmiller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithprecedent%2Fmiller/lists"}