{"id":34045902,"url":"https://github.com/cfclrk/py-demo","last_synced_at":"2026-04-01T20:19:27.111Z","repository":{"id":62579840,"uuid":"248990634","full_name":"cfclrk/py-demo","owner":"cfclrk","description":"Example python project with pyinstaller","archived":false,"fork":false,"pushed_at":"2022-03-11T14:36:53.000Z","size":40,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-11T09:18:51.949Z","etag":null,"topics":["cli","example","pyinstaller","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cfclrk.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-21T14:16:48.000Z","updated_at":"2023-12-11T16:13:56.000Z","dependencies_parsed_at":"2022-11-03T21:00:57.497Z","dependency_job_id":null,"html_url":"https://github.com/cfclrk/py-demo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/cfclrk/py-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfclrk%2Fpy-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfclrk%2Fpy-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfclrk%2Fpy-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfclrk%2Fpy-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cfclrk","download_url":"https://codeload.github.com/cfclrk/py-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfclrk%2Fpy-demo/sbom","scorecard":{"id":271853,"data":{"date":"2025-08-11","repo":{"name":"github.com/cfclrk/py-demo","commit":"b59a84db92033e6715e45b99806e7ef2f914cf99"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"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":"Code-Review","score":0,"reason":"Found 0/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":"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/on_push.yaml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_push.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_push.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_push.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/on_tag.yaml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/cfclrk/py-demo/on_tag.yaml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/on_push.yaml:22","Warn: pipCommand not pinned by hash: .github/workflows/on_push.yaml:23","Warn: pipCommand not pinned by hash: .github/workflows/on_tag.yaml:22","Warn: pipCommand not pinned by hash: .github/workflows/on_tag.yaml:23","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/on_push.yaml:1","Warn: no topLevel permission defined: .github/workflows/on_tag.yaml: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":"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":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"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 v0.0.2 not signed: https://api.github.com/repos/cfclrk/py-demo/releases/24736680","Warn: release artifact v0.0.2 does not have provenance: https://api.github.com/repos/cfclrk/py-demo/releases/24736680"],"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"}}]},"last_synced_at":"2025-08-17T13:35:58.387Z","repository_id":62579840,"created_at":"2025-08-17T13:35:58.387Z","updated_at":"2025-08-17T13:35:58.387Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31018635,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T03:51:26.850Z","status":"ssl_error","status_checked_at":"2026-03-27T03:51:09.693Z","response_time":164,"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","example","pyinstaller","python","python3"],"created_at":"2025-12-13T23:26:52.029Z","updated_at":"2026-03-27T04:25:20.202Z","avatar_url":"https://github.com/cfclrk.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+PROPERTY: header-args+  :exports  both\n#+PROPERTY: header-args+  :eval     never-export\n#+OPTIONS: toc:nil\n\n#+NAME: ReleaseBadge\n[[https://github.com/cfclrk/py-demo/workflows/Release/badge.svg]]\n\nA minimal python project to demonstrate what I think are best practices for\npython project structure, deployment, testing, etc. I am trying to document\ndesign decisions in the [[https://github.com/cfclrk/py-demo/wiki][wiki]].\n\nFeatures include:\n\n- Create a binary using [[https://pythonhosted.org/PyInstaller/index.html][Pyinstaller]]\n- Correctly handle data files\n- GitHub Actions to test and [[https://github.com/cfclrk/py-demo/releases][release]]\n\n* Installation\n\n  Here are three options for installation.\n\n  1. *From source* (requires Python 3.8+). Clone this project from GitHub\n     and =pip install= it.\n\n     #+begin_src bash :results output\n       git clone git@github.com:cfclrk/py-demo.git\n       cd py-demo\n       pip install .  # or: \"make dev\"\n     #+end_src\n\n  2. *From PyPI* (requires Python 3.8+). Use =pip= to install the latest [[https://pypi.org/project/py-demo/][release]]\n     from PyPI:\n\n     #+begin_src bash\n       pip install py-demo\n     #+end_src\n\n  3. *Standalone binary*. No local Python installation is needed. Download a\n     binary from the [[https://github.com/cfclrk/py-demo/releases][releases]] page.\n\n* Example\n\n  #+begin_src bash :results output\n    py-demo --foo bar\n  #+end_src\n\n  #+RESULTS:\n  : {\n  :   \"cli_opts\": {\n  :     \"version\": false,\n  :     \"foo\": \"bar\"\n  :   },\n  :   \"python_version\": \"3.12\",\n  :   \"data_from_file\": \"This is some text\"\n  : }\n\n* Testing\n\n  First ensure all test dependencies are installed (=make dev=), then run unit\n  tests (=make test=).\n\n  #+begin_src bash\n    make dev\n    make test\n  #+end_src\n\n  To run tests exactly as they will be run in GitHub Actions, use [[https://github.com/nektos/act][act]]:\n\n  #+begin_src bash\n    act -j test\n  #+end_src\n\n* Create a new project from this one\n\n  This will create a new directory (under the current directory) called\n  =$PROJECT_NAME=.\n\n  1. Set =PROJECT_NAME=\u003cmy-new-project-name\u003e=\n  2. Run the following script:\n\n  #+header: :dir ~/Work :mkdirp yes\n  #+header: :var PROJECT_NAME=\"feutil\"\n  #+begin_src bash\n    # Download source code\n    git clone --depth 1 git@github.com:cfclrk/py-demo.git $PROJECT_NAME\n    cd $PROJECT_NAME\n    rm -rf .git .github README.org\n\n    # Update the project name from \"py-demo\" to the new $PROJECT_NAME\n    find . -type f -exec sed -i \"\" \"s/py-demo/$PROJECT_NAME/g\" {} \";\"\n\n    # Update the python module name from \"py-demo\" to the new $PROJECT_NAME. Module\n    # names cannot have dashes, so first replace dashes with underscores.\n    moduleName=$(echo $PROJECT_NAME | sed s/-/_/g)\n    mv src/py_demo src/$moduleName\n    find . -type f -exec sed -i \"\" \"s/py_demo/$moduleName/g\" {} \";\"\n\n    # Set version back to 0.0.1\n    sed -i \"\" 's/^version = .*/version = 0.0.1/' setup.cfg\n\n    # Delete lines 7-10 in setup.cfg, which have project URL\n    sed -i \"\" 7,10d setup.cfg\n  #+end_src\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfclrk%2Fpy-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcfclrk%2Fpy-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfclrk%2Fpy-demo/lists"}