{"id":47588483,"url":"https://github.com/cielong/pyfx","last_synced_at":"2026-04-01T16:57:57.090Z","repository":{"id":43242440,"uuid":"227418780","full_name":"cielong/pyfx","owner":"cielong","description":"A python-native JSON Viewer TUI.","archived":false,"fork":false,"pushed_at":"2026-03-18T05:15:44.000Z","size":3436,"stargazers_count":35,"open_issues_count":2,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-18T20:44:18.439Z","etag":null,"topics":["cli","fx","json","json-viewer-tui","jsonpath","pyfx","python3","tui","urwid"],"latest_commit_sha":null,"homepage":"","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/cielong.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-12-11T17:06:57.000Z","updated_at":"2026-03-18T05:12:32.000Z","dependencies_parsed_at":"2023-01-27T05:16:05.566Z","dependency_job_id":"a22c2436-f6db-4958-ae26-5142e02d55f0","html_url":"https://github.com/cielong/pyfx","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/cielong/pyfx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cielong%2Fpyfx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cielong%2Fpyfx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cielong%2Fpyfx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cielong%2Fpyfx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cielong","download_url":"https://codeload.github.com/cielong/pyfx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cielong%2Fpyfx/sbom","scorecard":{"id":282623,"data":{"date":"2025-08-11","repo":{"name":"github.com/cielong/pyfx","commit":"89407c1bb54851ef62ebe690f7952b1949066e59"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 1/8 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/cielong/pyfx/codeql-analysis.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:31","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":2,"reason":"8 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: GHSA-gmj6-6f8f-6699","Warn: Project is vulnerable to: GHSA-q2x7-8rv6-6q7h","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-48p4-8xcf-vxj5","Warn: Project is vulnerable to: GHSA-pq67-6m6q-mj2v","Warn: Project is vulnerable to: PYSEC-2024-187 / GHSA-rqc4-2hc7-8c8v"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T16:18:31.082Z","repository_id":43242440,"created_at":"2025-08-17T16:18:31.082Z","updated_at":"2025-08-17T16:18:31.082Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cli","fx","json","json-viewer-tui","jsonpath","pyfx","python3","tui","urwid"],"created_at":"2026-04-01T16:57:55.004Z","updated_at":"2026-04-01T16:57:56.900Z","avatar_url":"https://github.com/cielong.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pyfx\n![Build Status](https://github.com/cielong/pyfx/actions/workflows/ci.yml/badge.svg?branch=main)\n![Documentation Status](https://readthedocs.org/projects/python-fx/badge/?version=latest)\n![PyPI version](https://badge.fury.io/py/python-fx.svg)\n![Python](https://img.shields.io/badge/python-3.9-green.svg)\n![Python](https://img.shields.io/badge/python-3.10-green.svg)\n![Python](https://img.shields.io/badge/python-3.11-green.svg)\n![GitHub](https://img.shields.io/github/license/cielong/pyfx)\n![codecov](https://codecov.io/gh/cielong/pyfx/branch/main/graph/badge.svg?token=QRA9CDTRTJ)\n\nA python-native JSON Viewer TUI, inspired by [fx](https://github.com/antonmedv/fx).  \n*Pyfx* supports:\n* Read JSON files in terminal from several sources (file, pipe or clipboard).\n* Query JSON files using JSONPath query.\n\n![](docs/demo.gif)\n\n## Table of Content\n\n* [Prerequisite](#prerequisites)\n* [Installation](#installation)\n  * [PIP](#pip)\n  * [Build from Source](#build-from-source)\n* [Quick Start](#quick-start)\n  * [CLI](#cli)\n  * [Python Module](#python-module)\n* [Configuration](#configuration)\n  * [Default Configuration](#default-configuration)\n* [License](#license)\n* [Changelog](#changelog)\n* [How to Contribute](#how-to-contribute)\n\n## Prerequisites\n* OS: MacOS / Linux\n* python: \u003e= 3.9\n* pip\n\n## Installation\n### Pip\n```bash\npip install python-fx\n```\n### Build from Source\nClone the this [repo](https://github.com/cielong/pyfx.git), change directory into the project and run\n```bash\npip install -U autopep8 tox build\nmake install\n```\n### Local Development\n1. Download and install the latest [ANTLR v4](https://www.antlr.org/)\n\n* It is required that ANTLR version installed matches the version of the Python ANTLR runtime version.  \n\n2. Clone the this [repo](https://github.com/cielong/pyfx.git), change directory into the project and run\n```bash\npip install -U pipenv\npipenv install --dev\n```\n\n## Quick Start\nYou can use *Pyfx* in two ways:\n* A standalone CLI tool\n* A python module which can be integrated in any python CLI application\n\nFor details, please check the hosted [documentation](https://python-fx.readthedocs.io/en/latest/).\n### CLI\nCheck [Key Bindings](#key-bindings) section for default key bindings.  \n*Pyfx* comes with a CLI, use it\n* To open a JSON file\n  ```bash\n   pyfx JSON_FILE\n  ```\n* To read JSON data from pipe\n  ```bash\n   cat JSON_FILE | pyfx\n  ```\n* To read JSON data from clipboard\n  ```bash\n   pyfx -x / --from-clipboard\n  ```\n\n### Python Module\nCheck [Key Bindings](#key-bindings) section for default key bindings.\n  \n#### Directly Attach *Pyfx* Simple TUI\nDirectly integrate *Pyfx*'s TUI into your own project.  \n```python\nfrom pyfx import PyfxApp\n\ndata = [1]\n# data is the JSON data to be rendered in the TUI\nPyfxApp(data=data).run()\n```\n\n#### Integrate with Your Own Urwid-based TUI\nIntegrate *Pyfx* native JSON widgets into your own urwid-based TUI.\n```python\nfrom pyfx.view.json_lib import JSONListBox, JSONListWalker\n\ndata = [1]\n\n# 1. create JSONListBox from data\nlistbox = JSONListBox(JSONListWalker(data))\n\n# 2. use listbox in your own TUI\n```\n\n## Configuration\n*Pyfx* is configured using YAML. There are two ways to provide a configuration file: \n* Pass directly through CLI option (`-c` | `--config`).\n* Create a config file in predefined folders and *Pyfx* will load it with best effort.  \n  The predefined folders are searched in following order, with the first exist one has high priority.  \n  1. `~/.config/pyfx/config.yml`\n  2. `src/pyfx/config/yaml/config.yml` [default config](src/pyfx/config/yaml/config.yml)\n\nFor available configuration, see [configuration](https://python-fx.readthedocs.io/en/latest/configuration/index.html).\n\n### Default Configuration\n#### Theme\nAlternative key bindings, see [Theme Configuration](https://python-fx.readthedocs.io/en/latest/configuration/theme.html).   \n\n| Name                          | Description                                            | Foreground Color   |\n|-------------------------------|--------------------------------------------------------|--------------------|\n| body                          | Pyfx body (JSON Browser)                               | terminal default   |\n| foot                          | Pyfx footer (Query Bar and Help Bar)                   | gray               |\n| focused                       | focused display                                        | gray               |\n| **Auto Complete PopUp**                                                                                     |\n| autocomplete_popup            | autocomplete popup                                     | black              |\n| autocomplete_popup_focused    | focused display for autocomplete popup                 | white              |\n| **JSON Browser**                                                                                            |\n| json_key                      | object key                                             | blue               |\n| json_string                   | *string* type value                                    | green              |\n| json_integer                  | *integer* type value                                   | cyan               |\n| json_numeric                  | *numeric* type value                                   | cyan               |\n| json_bool                     | *boolean* type value                                   | yellow             |\n| json_null                     | *null* type value                                      | red                |\n| json_focused                  | focused display for JSON                               | gray               |\n\n#### Key Bindings\nAlternative key bindings, see [Key Bindings Configuration](https://python-fx.readthedocs.io/en/latest/configuration/keymap.html).   \n\n| Key              | Function                                          |\n|------------------|---------------------------------------------------|\n| q                | exit pyfx (except in Query Bar)                   |\n| ?                | open help page (except in Query Bar)              |\n| **JSON Browser**                                                     |\n| up               | move cursor up one line                           |\n| down             | move cursor down one line                         |\n| e                | expand all                                        |\n| c                | collapse all                                      |\n| enter            | toggle expansion                                  |\n| .                | enter query window (used to input JSONPath query) |\n| **Query Bar**                                                        |\n| enter            | apply JSONPath query and switch to JSON Browser   |\n| esc              | cancel query and restore to state before query    |\n| **Autocomplete PopUp**                                               |\n| up               | move cursor up one line                           |\n| down             | move cursor down one line                         |\n| enter            | select option and complete the query              |\n| esc              | close pop up                                      |\n| **Help PopUp**                                                       |\n| up               | move cursor up one line                           |\n| down             | move cursor down one line                         |\n| esc              | close the help popup                              |\n\n## Known Limitation\nWhen open with very large JSON files, Pyfx will freeze on JSONPath query.  \n\nThe following statistics is tested at a MacBook Air (1.1GHz Quad-Core Intel Core i5\nand 8GB RAM).\n\n| File Size        | Functionality       | Usability                                    |\n|------------------|---------------------|----------------------------------------------|\n| 57MB             | Display JSON        | Fairly good                                  |\n| ^^               | Query Autocomplete  | Latency \u003c= 200ms                             |\n| ^^               | Query JSONPath      | Roughly 1~2s latency                         |\n| 570MB            | Display JSON        | Slow loading                                 |\n| ^^               | Query Autocomplete  | Latency \u003c= 200ms. Give up with large data    |\n| ^^               | Query JSONPath      | UI may freeze depend on the search space     |\n\n## License\nThe code is under [The MIT License](LICENSE.txt).\n\n## Changelog\nSee the [changelog](CHANGELOG.md) for a history of notable changes to *Pyfx*.\n\n## Contributors\n[Avery (@nullableVoidPtr)](https://github.com/nullableVoidPtr)  \n[Zephyr Lykos (@mochaaP)](https://github.com/mochaaP)  \n[@jcaesar](https://github.com/jcaesar)  \n\n## How to Contribute\nIf you run into any issues, please let me know by creating a GitHub issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcielong%2Fpyfx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcielong%2Fpyfx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcielong%2Fpyfx/lists"}