Wikipedia-API扩展开发:如何贡献代码并添加新功能
【免费下载链接】Wikipedia-APIPython wrapper for Wikipedia项目地址: https://gitcode.com/gh_mirrors/wi/Wikipedia-API
Wikipedia-API是一个强大的Python包装器,让开发者能够轻松与维基百科数据交互。本文将为你提供一份完整指南,帮助你贡献代码并添加新功能,成为这个开源项目的积极参与者。
为什么贡献代码?
参与开源项目不仅能提升你的编程技能,还能为全球开发者社区做出贡献。通过为Wikipedia-API添加新功能,你可以:
- 解决自己遇到的问题
- 学习最佳实践和设计模式
- 与志同道合的开发者建立联系
- 丰富你的作品集
准备工作
在开始贡献代码之前,请确保你已经完成以下步骤:
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/wi/Wikipedia-API - 阅读项目文档,特别是CONTRIBUTING.rst和DEVELOPMENT.rst
- 设置开发环境:按照文档中的说明安装依赖项
- 熟悉项目结构和代码风格
理解MediaWiki查询子模块
Wikipedia-API围绕MediaWiki的action=queryAPI构建,该API有两种主要类型的子模块:
prop=子模块:需要页面标题,结果在raw["query"]["pages"]中,如coordinates和imageslist=子模块:不需要页面标题,结果在raw["query"][list_key]中,如geosearch、random和search
选择正确的子模块类型是添加新功能的第一步,它将决定你的实现方式和公共方法的设计。
添加新功能的步骤
步骤1:定义类型化数据类
为子模块返回的结构化数据创建冻结的数据类,确保类型安全和代码清晰。例如,为coordinates子模块创建:
# wikipediaapi/_types.py @dataclass(frozen=True) class Coordinate: """A single geographic coordinate associated with a Wikipedia page.""" lat: float lon: float primary: bool globe: str = "earth" # 其他字段...步骤2:定义参数数据类
创建一个冻结的数据类,将Python参数映射到MediaWiki API参数。例如,为search子模块:
# wikipediaapi/_params.py @dataclass(frozen=True) class SearchParams(_BaseParams): """Parameters for list=search (prefix sr).""" query: str = "" namespace: int = 0 limit: int = 10 sort: str = "relevance" PREFIX: ClassVar[str] = "sr" FIELD_MAP: ClassVar[dict[str, str]] = { "query": "search", # → srsearch "namespace": "namespace", # → srnamespace # 其他映射... }步骤3:添加API参数构建器
在BaseWikipediaResource类中添加方法,构建原始API参数字典。例如:
# wikipediaapi/_resources/base_wikipedia_resource.py def _search_api_params(self, params: SearchParams) -> dict[str, Any]: """Build API params for list=search.""" api_params: dict[str, Any] = { "action": "query", "list": "search", # ← 独立列表,不需要页面标题 } api_params.update(params.to_api()) return api_params步骤4:添加响应解析器
实现解析原始JSON响应到类型化数据类的方法。例如,解析搜索结果:
# wikipediaapi/_resources/base_wikipedia_resource.py def _build_search_results(self, raw: dict[str, Any]) -> SearchResults: """Parse search list results into a SearchResults wrapper.""" pages = PagesDict(wiki=self) raw_query = raw.get("query", {}) for entry in raw_query.get("search", []): p = self._make_page( # ← 创建正确的页面类型 title=entry["title"], ns=int(entry.get("ns", 0)), language=self.language, variant=self.variant, ) # 设置页面属性... pages[entry["title"]] = p # 提取聚合信息... return SearchResults( pages=pages, totalhits=int(searchinfo.get("totalhits", 0)), suggestion=searchinfo.get("suggestion"), )步骤5和6:添加同步和异步公共方法
为同步和异步API添加公共方法。确保两者具有相同的签名,只在调度调用上有所不同(self._get(...)vsawait self._get(...))。
# wikipediaapi/_resources/wikipedia_resource.py (同步) def search( self, query: str, *, namespace: int = 0, limit: int = 10, sort: str = "relevance", ) -> SearchResults: """Search Wikipedia for pages matching a query.""" params = SearchParams(query=query, namespace=namespace, limit=limit, sort=sort) api_params = self._search_api_params(params) raw = self._get(self.language, self._construct_params_standalone(api_params)) return self._build_search_results(raw)# wikipediaapi/_resources/async_wikipedia_resource.py (异步) async def search( self, query: str, *, namespace: int = 0, limit: int = 10, sort: str = "relevance", ) -> SearchResults: """Async: Search Wikipedia for pages matching a query.""" params = SearchParams(query=query, namespace=namespace, limit=limit, sort=sort) api_params = self._search_api_params(params) raw = await self._get(self.language, self._construct_params_standalone(api_params)) return self._build_search_results(raw)步骤7:添加页面属性
为prop=子模块添加页面属性,使数据访问更加直观。同步和异步属性有不同的实现方式:
# wikipediaapi/_page/wikipedia_page.py (同步) @property def coordinates(self) -> list[Coordinate]: """Geographic coordinates for this page.""" default_params = CoordinatesParams() cached = self._get_cached("coordinates", default_params.cache_key()) if isinstance(cached, type(NOT_CACHED)): self.wiki.coordinates(self) # ← 触发获取 cached = self._get_cached("coordinates", default_params.cache_key()) if isinstance(cached, type(NOT_CACHED)): return [] return cached# wikipediaapi/_page/async_wikipedia_page.py (异步) @property def coordinates(self) -> Any: """Awaitable: geographic coordinates for this page.""" async def _get() -> list[Coordinate]: default_params = CoordinatesParams() cached = self._get_cached("coordinates", default_params.cache_key()) if isinstance(cached, type(NOT_CACHED)): await self.wiki.coordinates(self) # ← await cached = self._get_cached("coordinates", default_params.cache_key()) if isinstance(cached, type(NOT_CACHED)): return [] return cached return _get() # ← 返回协程,而不是结果步骤8-13:完善实现
完成剩下的步骤,包括更新页面初始化、导出类型、添加模拟数据、编写测试、更新文档和运行质量检查。详细指南请参考ADDING_SUBMODULES.md。
提交贡献
当你完成新功能的实现后,按照以下步骤提交贡献:
- 创建一个新的分支:
git checkout -b feature/your-feature-name - 提交你的更改:
git commit -m "Add feature: your feature description" - 推送到远程仓库:
git push origin feature/your-feature-name - 创建一个Pull Request (PR)
- 等待代码审查并根据反馈进行修改
结语
通过遵循这个指南,你可以为Wikipedia-API项目贡献有价值的功能,同时提升自己的开发技能。记住,开源贡献是一个协作过程,不要害怕寻求帮助或反馈。
无论你是添加新的MediaWiki子模块支持,还是改进现有功能,你的贡献都将帮助使Wikipedia-API变得更加强大和有用。开始你的贡献之旅吧!
【免费下载链接】Wikipedia-APIPython wrapper for Wikipedia项目地址: https://gitcode.com/gh_mirrors/wi/Wikipedia-API
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考