ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenMed 贡献指南与发布工作流:从本地开发到 PyPI 与 GitHub Pages 的完整实战

OpenMed 贡献指南与发布工作流:从本地开发到 PyPI 与 GitHub Pages 的完整实战 OpenMed 贡献指南与发布工作流从本地开发到 PyPI 与 GitHub Pages 的完整实战【免费下载链接】openmedLocal-first healthcare AI: clinical NER HIPAA PII de-identification that runs 100% on-device. 2,200 medical models, 21 languages, Apple MLX Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmedOpenMed 是一个本地优先local-first的医疗 AI 项目聚焦临床 NER 与 HIPAA 级 PII 脱敏。本指南围绕仓库的 docs/contributing.md 展开完整梳理贡献者从搭建开发环境、通过质量门禁、维护公共 API 文档字符串到打版本标签、发布 PyPI/npm 包与部署文档站点的全流程。读完本文你将掌握 OpenMed 的规范化贡献流程、可复现的本地工具链uv Makefile pre-commit、100% 覆盖的公共 API 文档门禁以及安全处理医疗数据日志的硬性红线。本地开发工作流以 uv 与 Makefile 为骨架OpenMed 将 uv 作为唯一的规范本地开发工具链配合仓库根目录的Makefile将绝大多数重复任务脚本化。提交到仓库的uv.lock保证了可编辑安装、测试工具与 lint 工具在每台机器和 CI 上的可复现性。创建锁定开发环境从仓库根目录执行uv sync --frozen --extra dev该命令创建.venv以可编辑模式安装 OpenMed 包并严格使用已提交的 lockfile--frozen表示拒绝任何未写入 lock 的漂移。如需追加可选能力可在同一命令中叠加 extra例如uv sync --frozen --extra dev --extra hf # 追加 Hugging Face 开发 extra uv sync --frozen --extra dev --extra docs # 追加 MkDocs 文档构建依赖对应地所有 Python 工具都通过uv run --frozen --extra dev ...调用或者直接使用 Makefile 目标见 Makefile。Makefile中的install目标即为uv sync --frozen --extra dev的封装lock-check目标则执行uv lock --check来校验uv.lock与pyproject.toml的一致性——CI 同样运行该检查。启用 pre-commit 本地钩子uv run --frozen --extra dev pre-commit install根据 .pre-commit-config.yaml钩子包括pre-commit-hooks家族trailing-whitespace、end-of-file-fixer、check-yaml排除mkdocs.yml、check-added-large-files上限 3000 KB、check-case-conflict、check-merge-conflict、check-toml、debug-statements、mixed-line-ending强制 LFruff-pre-commitv0.15.22ruff-check --fix与ruff-format在提交前自动格式化暂存的 Python 文件Bandit 安全扫描针对openmed/目录high 严重级别 / medium 置信度gitleaks 密钥泄漏检测。uv 不可用时的 pip 回退无法安装 uv 的环境仍可用 pip但它不提供 CI 所依赖的 lockfile 工作流。完整的回退流程见 docs/development.md#pip-fallbackpython3 -m venv .venv .venv/bin/python -m pip install --upgrade pip .venv/bin/python -m pip install -e .[dev] .venv/bin/pre-commit installWindows 用户将.venv/bin/python替换为.venv\Scripts\python.exe。此外仓库还提供 Pixipixi install --locked锁定 Python 3.12与 Nix flakenix develop两套补充开发路径详见 docs/development.md。快速查看可用任务make help该目标解析Makefile中的target: ## 说明注释并排序打印所有脚本化任务涵盖 build、publish、release、docs、quality、sbom、grpc-proto、brand-check 等类别。代码风格门禁Ruff 是唯一事实来源OpenMed 明确规定Ruff 是 Python 代码 lint、导入排序与格式化的唯一事实来源禁止在仓库上运行 Black、isort、flake8 或编辑器自带格式化器。对应的配置集中在 pyproject.toml 的[tool.ruff]段target-version py310line-length 88lint 选择E9、F63、F7、F82语法级错误与I导入排序其中仅I可自动修复isort 将openmed声明为 first-party格式化为双引号、空格缩进、LF 行尾。提交 Pull Request 前必须依次运行uv sync --frozen --extra dev make format # ruff check --fix . ruff format . make lint # ruff check . make type-check # 作用域内的 mypy make format-check # ruff format --check .make lint对应ruff check .make format-check对应ruff format --check .两者与 CI 执行的门禁完全一致。make quality则一口气运行lint、type-check、format-check与完整测试套件。需要强调的是make type-check的 mypy 是有作用域的根据 pyproject.toml 的[tool.mypy]仅覆盖openmed/core/audit.py、openmed/core/pipeline.py、openmed/clinical/context.py、openmed/clinical/exporters/fhir/bundle.py等已具备精确注解与py.typed标记的公共面并非全项目严格门禁。mypy 版本被锁定为mypy2.3.0。Swift 代码OpenMedKitswift/OpenMedKit下的改动使用 Apple 官方swift-format配置随仓库提交.swift-format。格式化与检查通过两个脚本化目标完成make format-swift # scripts/format_swift.sh make lint-swift # scripts/lint_swift.sh对应脚本位于 scripts/format_swift.sh 与 scripts/lint_swift.sh。仓库还配套了 Swift 的测试工作流swift-test.yml。CI 的约束还包括PR 不应包含与本次功能/修复无关的格式化改动避免噪音混入评审范围。公共 API 文档字符串与导出清单100% 覆盖门禁OpenMed 对openmed.__all__中导出的每个函数与类都要求具备有意义的 docstring以保持运行时help()、IDE 提示与 mkdocstrings API 参考页的可用性同时不对私有/内部模块施加覆盖率要求。模块级数据导出dict、set、str 等无法携带符号级实例 docstring因此门禁将它们解析为显式清单inventory而不是按函数/类计分。本地验证两条路径uv run --frozen --extra dev python scripts/check_public_api_docstrings.py uv run --frozen --extra dev pytest tests/unit/test_public_api_docstrings.py -q静态检查器的实现原理scripts/check_public_api_docstrings.py 是一个纯标准库仅ast 路径运算不导入运行时包的 CLI解析openmed/__init__.py读取__all__以及支撑每个导出名的 eager import 或字面量_LAZY_IMPORTS绑定纯按文件系统布局将每个绑定解析到其定义源文件不执行任何 import用ast解析源文件通过ast.get_docstring检查class/def节点是否含非空 docstring最小长度为MIN_DOCSTRING_CHARS 10个字符防止占位空文档。解析器会沿 re-export 链最多追踪 12 跳_MAX_REEXPORT_HOPS 12防止循环最终定位到真正的def/class或数据赋值。只有 docstringable 的符号函数与类参与计分模块级数据值被单独解析进清单而不计入覆盖率__version__同样按 data 处理。DEFAULT_MIN_COVERAGE 100.0即函数与类的覆盖率必须保持 100%——新增公共函数或类时必须在同一个 PR 内补上 docstring。pytest 运行期一致性检查tests/unit/test_public_api_docstrings.py 在静态检查之上叠加了运行期校验它导入openmed要求实时__all__顺序与静态清单一致核验导出函数/类存在有意义的 docstring并对照显式白名单校验数据导出。其EXPECTED_DATA_EXPORTS精确列出每个数据导出的模块与类型例如ERROR_CODES→openmed.core.errors的dictPII_PATTERNS→openmed.core.pii_entity_merger的listSUPPORTED_LANGUAGES→openmed.core.language_pack_catalog的setDEFAULT_PII_MODELS、LANGUAGE_PII_PATTERNS→openmed.core.pii_i18n的dictCANONICAL_LABELS→openmed.core.labels的frozensetENCRYPTION_SCHEME→openmed.core.surrogate_vault的str这样设计的原因在于数据导出若依赖通用内置实例文档如 dict 的__doc__会毫无意义显式清单才能保证 API 参考页能给出准确的模块/类型定位。医疗数据日志红线No-Raw-PHI 策略OpenMed 处理的是病人文本与 PHI因此 docs/security/no-raw-phi-logging.md 定义了所有涉及 PII、脱敏、文本处理、服务与批处理改动的强制约束代码不得在任何日志级别写入原始 PHI、病人文本、源文档或明文抽取片段——日志只属于运维遥测。允许计数、耗时、阈值、模型标识、后端名、状态转换span 元数据标签、起始/结束偏移、置信度桶、有效性标志已存在的预计算 keyedtext_hash禁止在日志语句中临时造 hash异常类名与高层失败类别。禁止输入文档原文、清洗后文本、截断片段、prompt、句子实体原文、原始 PII 值、脱敏-原文映射可能包含用户输入/源路径/请求体的异常消息由病人、病历或就诊数据派生出的文件路径或条目标识。工程要求上新增日志优先使用结构化字段而非格式化散文用长度、计数、标签、偏移与安全标识代替文本并保持请求/响应体不进服务日志。任何涉及 PII/脱敏/文本处理/批处理路径的改动都必须运行日志守卫pytest tests/unit/test_no_raw_text_logging.py -q发布或 PR 评审前还需通过完整套件pytest tests/ -q。发布流程从版本号到 PyPI/npm版本号提升发布的第一步是 bump 版本。make bump-patch或bump-minor/bump-major调用 scripts/release/release.py其实现非常克制只更新 openmed/about.py 中的__version__字符串不构建、不发布。当前仓库版本为2.3.0。脚本支持 patch/minor/major 三种语义化 bump如1.9.1 - 1.9.2、1.9.2 - 1.10.0、1.10.0 - 2.0.0并通过正则精确替换__version__不会误伤其他内容。构建与发布make build # uv build产出 wheel 与 sdist然后更新 CHANGELOG.md 写入本次发布说明最后推送vX.Y.Z标签触发.github/workflows/publish.yml。注意Makefile中的publish/release目标基于hatch publish是本地遗留入口——根据 docs/release/trusted-publishing.md 的明确契约唯一的 PyPI 发布工作流是.github/workflows/publish.yml且该工作流只从v*标签的 push 事件自动运行不从pull_request或 fork PR 运行禁止新增第二个 PyPI 发布工作流也禁止把hatch publish或 Twine 上传命令加回发布 CI。publish.yml的关键契约包括用项目级PYPI_API_TOKENGitHubpypi环境的 secretnpm 路径使用npm环境短时NPM_ACCESS_TOKEN发布带 Sigstore provenancePyPI 与 npm 包版本必须与v*标签完全一致js/openmedkit-web/package.json、openmed/__about__.py、标签三处一致wheel 与 sdist 显式输出 Core Metadata 2.4见 pyproject.toml 中[tool.hatch.build.targets.sdist]/[tool.hatch.build.targets.wheel]的core-metadata-version 2.4可复用 provenance job.github/workflows/provenance.yml构建并校验发行物、生成 SLSA 证明、上传前验证 attestations恢复型手动 dispatchgh workflow run publish.yml --ref master -f tagvX.Y.Z只用于恢复已存在的不可变标签绝不删除/移动/重建标签。文档还记录了两次真实事故的经验v1.8.0因未配密码而回退到 Trusted Publishing、被 PyPI 以invalid-publisher拒绝v2.1.0因 Hatchling 1.32.0 默认输出 Core Metadata 2.5 而被发布 action 拒绝现恢复流程固定 Hatchling 1.31.0npm 恢复采用内容感知的幂等校验。对应的本地回归护栏是 tests/unit/test_publish_workflow_version.py 与 tests/unit/release/test_provenance_workflow.py。版本流与渠道策略根据 docs/release/semver-and-channels.mdOpenMed 分两条发布流Stream A模型工件本质是数据一个坏 checkpoint 只影响单个模型条目可通过回指 manifest 到最后绿色工件回滚由维护者在本地转换、评估、评审后触发Stream B库/SDKopenmedwheel 与 sdist 是代码坏版本会破坏所有下游安装因此遵循 SemVer 并放慢节奏PATCH 按日到周、MINOR 按月、MAJOR 按里程碑minor/major 需要维护者签字。渠道分为三档渠道选择器内容节奏受众Nightly / edgepip install openmed --pre最新绿色代码与受门禁的模型 pin每次绿色合并或每日早期采用者与内部评估Stablepip install openmed完整 golden 套件通过 canary 就绪 pinPATCH 日到周、MINOR 按月默认用户LTSpip install openmed1.8.*仅安全与召回兜底修复按需持续 12 个月受监管部署Nightly 使用 PEP 440 dev 版本如1.9.0.devNRC 版本如1.9.0rc1保留给稳定前切片。发布门禁critical-leakage、recall、量化 delta、设备分档、span 完整性、回归等而不是单一 F1 决定模型是否可发布。文档部署MkDocs 严格模式与 GitHub Pages文档站点由.github/workflows/pages.yml驱动每次 push 到master都会以严格模式构建 MkDocs把营销站点与文档捆绑后通过 GitHub Pages 部署。本地预览与验证uv sync --frozen --extra dev --extra docs uv run mkdocs serve -a 127.0.0.1:8008 # 热重载预览make docs-serve 同义 make docs-stage # 构建并校验 Pages 工件含品牌门禁 python3 -m http.server --directory site 9000 # 本地检查营销文档捆绑结果几点值得注意make docs-serve与make docs-build分别对应开发预览与 CI 对齐构建其中docs-build实际先执行docs-stage运行python scripts/docs/stage_pages.py并前置brand-check品牌系统校验再确保产物与 Pages 工件完全一致自动化中运行mkdocs build --strict因此本地必须检查构建日志确认同样的警告不会让 CI 失败需要 CI 之外手动发布时make docs-deploy复刻工作流构建到site/docs、把docs/website/复制进site/、用ghp-import site -f -p强推gh-pages分支make docs-browser-test会安装固定版本的 Chromium/Firefox/WebKitPlaywright运行跨浏览器品牌矩阵测试。Issue 提交流程与治理参考用户向文档统一放在docs/内新指南只需 Markdown 与可选 front matter提文档 bug 时引用精确的文件 小节便于快速复现倾向小 PR一次只聚焦一个指南或功能每个 PR 都会触发 CI 与 Pages安全问题例外脱敏绕过或 PHI/PII 泄漏必须走私下报告通道绝不能提公开 issue遵循 Security Disclosure policy涉及日志、文本处理、服务请求处理、PII 抽取或脱敏代码时运行pytest tests/unit/test_no_raw_text_logging.py -q。治理参考文档还包括Release Streams Channels定义模型工件与库的发布节奏上文已展开PyPI Publishing包发布、provenance 与令牌处理契约上文已展开Generative Model Policy定义被批准与被禁止的模型辅助工作流。最后一条硬性规范移植的规则集文件必须以上游归因头开头标明源项目、源 URL、许可证、移植日期与本地修改保证规则集的可追溯性与合规性。结语OpenMed 的贡献流程用一个词概括就是可复现 分层门禁uv lockfile 与 Makefile 保证本地与 CI 行为一致Ruff/Swift-format/mypy 保证代码风格收敛100% 的公共 API 文档门禁与显式导出清单保证 SDK 契约可文档化No-Raw-PHI 日志策略守住医疗数据红线标签驱动的双注册表发布与严格 Pages 构建则保证交付物可信。按本文顺序走完一遍你就能以维护者期望的方式为 OpenMed 提交代码、文档与发布。【免费下载链接】openmedLocal-first healthcare AI: clinical NER HIPAA PII de-identification that runs 100% on-device. 2,200 medical models, 21 languages, Apple MLX Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmed创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表