{"id":14324777,"url":"https://github.com/pyprojectx/pyprojectx","last_synced_at":"2026-01-14T07:56:44.290Z","repository":{"id":43257112,"uuid":"428161239","full_name":"pyprojectx/pyprojectx","owner":"pyprojectx","description":"All-Inclusive Python Projects","archived":false,"fork":false,"pushed_at":"2025-10-08T12:54:03.000Z","size":2334,"stargazers_count":131,"open_issues_count":3,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-08T13:18:01.634Z","etag":null,"topics":["build-tool","cli","python"],"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/pyprojectx.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,"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":"2021-11-15T07:20:21.000Z","updated_at":"2025-10-08T11:12:10.000Z","dependencies_parsed_at":"2023-11-08T13:33:29.594Z","dependency_job_id":"8e3fa0d5-e7b6-4a4e-ab03-99c01117ab59","html_url":"https://github.com/pyprojectx/pyprojectx","commit_stats":{"total_commits":65,"total_committers":5,"mean_commits":13.0,"dds":"0.12307692307692308","last_synced_commit":"13f184fd5f8b9eda81e80f577db09b84138a628d"},"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"purl":"pkg:github/pyprojectx/pyprojectx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyprojectx%2Fpyprojectx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyprojectx%2Fpyprojectx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyprojectx%2Fpyprojectx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyprojectx%2Fpyprojectx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyprojectx","download_url":"https://codeload.github.com/pyprojectx/pyprojectx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyprojectx%2Fpyprojectx/sbom","scorecard":{"id":751738,"data":{"date":"2025-08-11","repo":{"name":"github.com/pyprojectx/pyprojectx","commit":"b120985cd9070dfe6249916ee9de3c016816a5c0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"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":"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":10,"reason":"21 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/30 approved changesets -- score normalized to 0","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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/docs.yml:1","Warn: no topLevel permission defined: .github/workflows/release.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":"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/build.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/docs.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/docs.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docs.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/docs.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/pyprojectx/pyprojectx/release.yml/main?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction 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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE: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":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 3.2.9 not signed: https://api.github.com/repos/pyprojectx/pyprojectx/releases/238999732","Warn: release artifact 3.2.8 not signed: https://api.github.com/repos/pyprojectx/pyprojectx/releases/238996756","Warn: release artifact 3.2.7 not signed: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236831028","Warn: release artifact 3.2.6 not signed: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236814570","Warn: release artifact 3.2.5 not signed: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236809136","Warn: release artifact 3.2.9 does not have provenance: https://api.github.com/repos/pyprojectx/pyprojectx/releases/238999732","Warn: release artifact 3.2.8 does not have provenance: https://api.github.com/repos/pyprojectx/pyprojectx/releases/238996756","Warn: release artifact 3.2.7 does not have provenance: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236831028","Warn: release artifact 3.2.6 does not have provenance: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236814570","Warn: release artifact 3.2.5 does not have provenance: https://api.github.com/repos/pyprojectx/pyprojectx/releases/236809136"],"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":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"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":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 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"}}]},"last_synced_at":"2025-08-22T20:34:07.807Z","repository_id":43257112,"created_at":"2025-08-22T20:34:07.807Z","updated_at":"2025-08-22T20:34:07.807Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["build-tool","cli","python"],"created_at":"2024-08-24T23:01:21.495Z","updated_at":"2026-01-14T07:56:44.275Z","avatar_url":"https://github.com/pyprojectx.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"![pyprojectx](https://pyprojectx.github.io/assets/px.png)\n\n# Pyprojectx: All-inclusive Python Projects\n\nExecute scripts from pyproject.toml, installing tools on-the-fly\n\n## [Full documentation](https://pyprojectx.github.io)\n\n## Introduction\nPyprojectx makes it easy to create all-inclusive Python projects; no need to install any tools upfront,\nnot even Pyprojectx itself!\n\nTools that are specified within your pyproject.toml file will be installed on demand when invoked from Pyprojectx:\n```shell\n\u003e ./pw ruff check src\nInstalled 1 package in 149ms\n + ruff==0.12.7\n\nAll checks passed!\n```\n\n## Feature highlights\n* Reproducible builds by treating tools and utilities as (locked) dev-dependencies\n* No global installs, everything is stored inside your project directory (like npm's _node_modules_)\n* Bootstrap your entire build process with a small wrapper script (like Gradle's _gradlew_ wrapper)\n* Configure shortcuts for routine tasks\n* Simple configuration in _pyproject.toml_\n\nProjects can be build/tested/used immediately without explicit installation nor initialization:\n```bash\ngit clone https://github.com/pyprojectx/px-demo.git\ncd px-demo\n./pw build\n```\n![Clone and Build](https://raw.githubusercontent.com/pyprojectx/pyprojectx/main/docs/docs/assets/build.png)\n\n## Installation\nOne of the key features is that there is no need to install anything explicitly (except a Python 3.9+ interpreter).\n\n`cd` into your project directory and download the\n[wrapper scripts](https://github.com/pyprojectx/pyprojectx/releases/latest/download/wrappers.zip):\n\n**Linux/Mac**\n```bash\ncurl -LO https://github.com/pyprojectx/pyprojectx/releases/latest/download/wrappers.zip \u0026\u0026 unzip wrappers.zip \u0026\u0026 rm -f wrappers.zip\n```\n\n**Windows**\n```powershell\nInvoke-WebRequest https://github.com/pyprojectx/pyprojectx/releases/latest/download/wrappers.zip -OutFile wrappers.zip; Expand-Archive -Path wrappers.zip -DestinationPath .; Remove-Item -Path wrappers.zip\n```\n\n## Getting started\nInitialize a new or existing project by adding tools (on Windows, replace `./pw` with `pw`):\n```bash\n./pw --add uv,ruff,pre-commit,px-utils\n./pw --install-context main\n# invoke a tool via the wrapper script\n./pw uv --version\n./pw ruff check src\n# or activate the tool context\nsource .pyprojectx/main/activate\nuv --version\nruff check src\n```\n\nFor reproducible builds and developer experience, it is recommended to lock the versions of the tools\nand add the generated _pw.lock_ file to your repository:\n```bash\n./pw --lock\n```\n\n## Create command shortcuts\nThe _tool.pyprojectx.aliases_ section in _pyproject.toml_ can contain commandline aliases:\n```toml\n[tool.pyprojectx.aliases]\n# convenience shortcuts\nrun = \"uv run\"\ntest = \"uv run pytest\"\nlint = [\"ruff check\"]\ncheck = [\"@lint\", \"@test\"]\n```\n\n## Usage\nInstead of calling the CLI of a tool directly, prefix it with `./pw` (`pw` on Windows).\n\nExamples:\n```shell\n./pw uv add --dev pytest\ncd src\n../pw lint\n```\n\nAliases can be invoked as is or with extra arguments:\n```shell\n./pw uv run my-script --foo bar\n# same as above, but using the run alias\n./pw run my-script --foo bar\n```\n\n## Why yet another tool?\n* As Python noob I had hard times setting up a project and building existing projects\n* There is always someone in the team having issues with his setup, either with a specific tool, with Homebrew, pipx, ...\n* Using (uv, PDM or Poetry) dev-dependencies to install tools, impacts your production dependencies and can even lead to dependency conflicts\n* Different projects often require different versions of the same tool\n\n## Example projects\n* This project (using uv)\n* [px-demo](https://github.com/pyprojectx/px-demo) (using uv, PDM or Poetry)\n\n## Development\n* Build/test:\n```shell\ngit clone https://github.com/pyprojectx/pyprojectx.git\ncd pyprojectx\n./pw build\n```\n\n* Use your local pyprojectx copy in another project: set the path to pyprojectx in the _PYPROJECTX_PACKAGE_ environment variable\n  and create a symlink to the wrapper script.\n```shell\n# Linux, Mac\nexport PYPROJECTX_PACKAGE=path/to/pyprojectx\nln -s $PYPROJECTX_PACKAGE/src/pyprojectx/wrapper/pw.py pw\n# windows\nset PYPROJECTX_PACKAGE=path/to/pyprojectx\nmklink pw %PYPROJECTX_PACKAGE%\\src\\pyprojectx\\wrapper\\pw.py\n# or copy the wrapper script if you can't create a symlink on windows\ncopy %PYPROJECTX_PACKAGE%\\src\\pyprojectx\\wrapper\\pw.py pw\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyprojectx%2Fpyprojectx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyprojectx%2Fpyprojectx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyprojectx%2Fpyprojectx/lists"}