预处理器,用于将 API 方法的引用替换为其描述的链接。
项目描述
用于 Foliant 的 APILinks 预处理器
APILinks 预处理器现已弃用。它不会更新,将来可能会被删除。请改用 APIReferences。
预处理器,用于将 Markdown 文件中的 API引用替换为 API 文档网页上实际方法描述的链接。
安装
$ pip install foliantcontrib.apilinks
快速开始
假设您有一个 API 文档托管在 url http://example.com/api-docs
它可能是一个Swagger UI网站或只是一些静态的单页网站(如Slate)。
因此,如果您有一个包含 API 文档的站点,您可能会在其他文档中不时引用它们:
To authenticate user use API method `GET /user/authenticate`.
我们想,如果这个片段:`GET /user/authenticate`自动转换为您的 API 文档网站上的此方法描述的链接,那该有多酷。这就是 APILinks 的用途。
如果您的 API 文档是类似 Slate 的静态网站,请将其添加到您的预处理器列表中:
preprocessors:
- apilinks:
API:
My-API:
url: http://example.com/api-docs
如果您的 API 文档是 Swagger UI 网站,或者像这样:
preprocessors:
- apilinks:
API:
My-API:
url: http://example.com/api-docs
规格:http ://example.com/api-docs/swagger.json
这里:
API是必填部分;My-API是您的 API 的本地名称。现在它不是很重要,但在下一个例子中会派上用场;url是一个包含 API 文档网页的完整 URL 的字符串。它将用于验证引用并构造方法的链接;spec是一个包含 OpenAPI 规范文件的完整 URL 的字符串,它将用于为该方法构造正确的锚点。如果您不想每次都下载它,它也可能是本地规范文件的路径。
foliant 应用预处理器后,您的文档将转换为:
To authenticate user use API method [GET user/authenticate](http://example.com/api-docs/#get-user-authenticate).
请注意,预处理器自己找出了正确的锚点#get-user-authenticate。现在,您获得了指向方法描述的链接,而不是方法的简单名称!
好的,如果我有两个不同的 API:客户端 API 和管理 API,该怎么办?
没问题,将它们都放入您的配置中:
preprocessors:
- apilinks:
API:
Client-API:
url: http://example.com/client/api-docs
Admin-API:
url: http://example.com/admin/api-docs
spec: http://example.com/admin/api-docs/swagger.yml
现在这个来源:
To authenticate user use API method `GET user/authenticate`.
To ban user from the website use admin API method `POST admin/ban_user/{user_id}`
将由 apilinks 转换为:
To authenticate user use API method [GET user/authenticate](http://example.com/client/api-docs/#get-user-authenticate).
To ban user from the website use admin API method [POST admin/ban_user/{user_id}](http://example.com/admin/api-docs/#/user/banUser)
请注意,apilinks 确定第一个引用来自 Client API,第二个引用来自 Admin API。这怎么可能?预处理器从配置中解析每个 API url,并在查找引用之前存储它们的方法。当需要处理引用时,它已经有一个所有方法的列表来验证您的引用并确定应该插入哪个 API 链接。
但是,如果我们在两个 API 中都有同名的方法怎么办?在这种情况下,您将看到一条警告:
WARNING: GET /service/healthcheck is present in several APIs (Client-API, Admin-API). Please, use prefix. Skipping
它建议我们使用前缀,这意味着在 config.xml 中使用 API 的本地名称为引用添加前缀。像那样:
Check status of the server through Client API: `Client-API: GET /service/healthcheck`
Do the same through Admin API: `Admin-API: GET /service/healthcheck`
这里Client-API: 和Admin-API: 是前缀。它们应该与配置中的 API 名称相同。
现在每个引用都将替换为相应 API 网页的链接。
apilinks 是一个高度可定制的预处理器。你可以调:
- 参考文献的格式;
- 将替换引用的输出字符串;
- API 网页中标题的格式;
- 和更多!
有关详细信息,请查看以下部分。
词汇表:
- reference — 对源文件中的 API 方法的引用。要替换为链接的那个,例如
GET user/config - 动词— HTTP 方法,例如
GET,POST等。 - command — 用于表示 API 文档网页上的方法的资源,例如
/service/healthcheck. - 端点前缀——从服务器根到命令的前缀。如果命令是
/user/status且完整资源是/api/v0/user/satus,则应说明端点前缀/api/v0。在引用中,您可以使用完整资源 ({endpoint_prefix}/{command}) 或仅使用命令。apilinks 会为你整理出来。 - output — 字符串,它将替换引用。
- header — 方法描述的 API 文档网页上的 HTML 标头,例如
<h2 id="get-user-config">GET user/config</h2> - anchor — 指向API 文档网页上特定标头的web-anchor ,例如
#get-user-config
它是如何工作的?
预处理器可以在在线和离线模式下工作。
在离线模式下,它只是将API 方法的引用替换为指向其描述的链接。引用由正则表达式捕获。链接 url 取自配置,链接锚点自动从参考生成。
您可以在配置中声明几个不同的 API。您可以使用前缀来指出正在引用哪个 API d。可以在配置中自定义前缀格式,但默认情况下您会这样做:Client-API: GET user/name. 这里' Client-API '是一个前缀。
如果您在参考预处理器中不使用前缀,则会假设您的意思是默认 API,它由 config.xml 中的default选项标记。如果它们都没有被标记 - 去列表中的第一个。
请注意,Swagger UI API 网站根本无法在离线模式下工作,因为我们需要下载规范文件 (swagger.json) 以找出方法描述的正确锚点。
在在线模式下,事情变得越来越有趣。预处理器实际上会访问每个 API 网页,并收集所有方法标头。然后它会检查您的文档的来源:当它遇到一个引用时,它会查看所有收集的方法并将引用替换为指向它的正确链接。如果未找到方法 - 预处理器将显示警告并保持引用不变。如果在不同的 API 中有多个具有此名称的方法,也会发生同样的情况。
前面解释过的前缀也受支持。
配置
要启用预处理器,请添加apilinks到preprocessors项目配置中的部分:
preprocessors:
- apilinks
预处理器有很多选择。为方便起见,所需选项已标记(必需);并且那些在定制中使用的选项被标记为(可选)。您很可能只需要后者中的一两个。
preprocessors:
- apilinks:
targets:
- site
offline: False
trim_if_targets:
- pdf
prefix_to_ignore: Ignore
reference:
- regex: *ref_pattern
only_with_prefixes: false
only_defined_prefixes: true
output_template: '[{verb} {command}]({url})'
trim_template: '`{verb} {command}`'
API:
Client-API:
url: http://example.com/api/client
default: true
header_template: '{verb} {command}'
site_backend: slate
login: mylogin
password: mypass
Admin-API:
url: http://example.com/api/client
header_template: '{command}'
endpoint_prefix: /api/v0
site_backend: aglio
Internal-API:
url: http://example.com/swagger-ui
spec: http://example.com/swagger-ui/swagger.json
site_backend: swagger
prefix_to_ignore
: (可选)忽略引用的默认前缀。如果 apilinks 遇到带有此前缀的引用,它将保持不变。默认:Ignore
targets
:( 可选)foliant make命令支持的目标列表。如果目标未在此处列出 - 将不会应用预处理器。如果列表为空 - 预处理器将应用于任何目标。默认:[]
offline
:( 可选)确定预处理器是在线还是离线模式工作的选项。它是如何工作的?和在线和离线模式比较部分。默认:False
trim_if_targets
:( 可选)将删除文本中所有引用foliant make的前缀的命令目标列表。默认:[]
只有那些前缀在本
API节中定义的引用(如下所述)受此选项影响。所有带有未列出前缀的引用都不会被修剪。
reference
:( 可选)列出您将在文本中捕获的所有引用类型及其属性的小节。下面列出了此部分的选项。
引用选项
regex
:( 可选)用于捕获源中引用的正则表达式。在捕获参考部分中查找详细信息。默认:
(?P<source>`((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>\S+)`)
only_with_prefixes
: (可选)如果是true,则只会转换带有前缀的引用。普通链接之类的GET user/info会被忽略。默认:false
only_defined_prefixes
:( 可选)如果这是true所有前缀未在API部分(如下所述)中列出的引用,则将被忽略,保持不变。没有前缀的引用不受此选项的影响。默认值:false。
output_template
: (可选)描述将替换引用的输出的模板字符串。自定义输出部分中的更多信息。默认:'[{verb} {command}]({url})'
trim_template
:( 可选)trim_if_targets仅适用于选项中列出的目标。如果您想自定义 apilinks 如何删除前缀,请调整此模板。引用将替换为基于此模板的文本。默认:'`{verb} {command}`'
API
:( 必需)列出所有 API 及其属性的小节。在本节下,每个 API 都应该有一个单独的小节。部分名称代表 API 名称,同时代表引用中使用的前缀。您需要添加至少一个 API 小节才能使预处理器工作。
API 属性
url
:( 必需) API 文档网页 URL。它将用于构建该方法的完整链接。在在线模式下,它也将被预处理器解析以进行验证。
spec
:( 站点后端需要)URLswagger或redocOpenAPI 规范文件的本地路径。
default
:( 可选)仅适用于离线模式。用于定义默认 API 的标记。如果几个 API 被标记为默认,预处理器将选择其中的第一个。如果没有标记为默认 - 将选择列表中的第一个 API。这个项目的价值应该是true。
header_template
:( 可选)描述 API 文档网页中标题格式的模板字符串。需要从网页中解析方法标题。解析 API 网页部分的详细信息。默认:'{verb} {command}'
endpoint_prefix
:( 可选)从服务器根到 API 方法的端点前缀。如果有说明——apilinks 可以将参考中的命令进行划分,更准确地搜索。您也可以在模板中使用它。更多信息即将推出。默认:''
site_backend
:( 可选)静态站点生成器的名称,它构建了您的 API 文档网站。这会影响标头如何转换为锚点。默认值:slate。可用选项:aglio, mkdocs, redoc, slate, swagger.
login
:( 可选)登录以进行基本身份验证(如果您的 API 站点上存在)。
password
:( 可选)基本身份验证的密码(如果存在于您的 API 站点上)。
如果您的 API 文档网站是由另一个静态站点生成器构建的,那么您仍然有机会使其与 APILinks 一起使用,因为它们中的许多使用类似的模式来生成锚点。只需尝试
aglio,mkdocs,之一slate(但不是redocandswagger,这些是特殊的)。如果它不起作用,请给我们发送消息,我们将为您的工具添加支持。
在线和离线模式比较
请注意,Swagger 和 Redoc 站点无法在离线模式下工作
让我们研究一个例子,看看预处理器的行为在在线和离线模式下会如何变化。
我们在配置中描述了三个 API:
preprocessors:
- apilinks:
API:
Admin-API:
url: http://example.com/api/client
Client-API:
url: http://example.com/api/client
default: true
header_template: '{verb} {command}'
Remote-API:
url: https://remote.net/api-ref/
header_template: '{command}'
现在让我们看看 Markdown 源代码中使用的文本的不同示例,以及它将如何在离线和在线模式下进行转换
示例 1 来源:
Unprefixed link which only exists in Remote API: `GET system/info`.
在离线模式下,预处理器不会进行任何检查,只需将引用替换为配置中指向默认 API 的链接:
Unprefixed link which only exists in Remote API: [GET system/info](http://example.com/api/client/#get-system-info).
这当然是一个错误的决定,但这是我们的错,我们应该在引用中添加前缀。
但是让我们看看在线模式会发生什么:
Unprefixed link which only exists in Remote API: [GET system/info](https://remote.net/api-ref/#system-info).
在没有任何前缀的情况下,预处理器决定它应该选择远程 API 来替换这个引用,因为这个方法只存在于它的页面上。在此模式下,该default选项将被忽略。
顺便说一下,请注意两个示例中的锚点有何不同。对于远程 API 预处理器使用其标头模板来重建锚点,从中删除动词。
示例 2 来源:
Unprefixed link with misprint: `GET user/sttus`.
The link is incorrect, there's no such method in any of the APIs.
在离线模式下,预处理器不会再做任何检查。没有魔法,引用将替换为配置中默认 API 的链接:
Unprefixed link with misprint: [GET user/sttus](http://example.com/api/client/#get-user-sttus).
The link is incorrect, there's no such method in any of the APIs.
在在线模式下,预处理器将无法在验证期间找到方法,并且根本不会替换引用:
Unprefixed link with misprint: `GET user/sttus`.
The link is incorrect, there's no such method in any of the APIs.
在 Foliant 项目组装期间,您将看到一条警告消息:
WARNING: Cannot find method GET user/sttus. Skipping
示例 3 来源:
Prefixed link to the Admin API: `Admin-API: POST user/ban_forever`.
在离线模式下,预处理器会注意到前缀并且能够用适当的链接替换引用:
Prefixed link to the Admin API: [POST user/ban_forever](http://example.com/api/client/#post-user-ban_forever).
请注意,前缀从文本中消失了。如果您希望它留在那里 - 将output_template选项编辑为以下内容:'{prefix}: {verb} {command}'.
在在线模式下,结果将完全相同。预处理器将检查 Admin-API 方法,在那里找到引用的方法并在文本中替换它:
Prefixed link to the Admin API: [POST user/ban_forever](http://example.com/api/client/#post-user-ban_forever).
示例 4
Prefixed link to the Remote API with a misprint: `Remote-API: GET billling/info`.
Oh no, the method is incorrect again.
在离线模式下,预处理器将不执行任何检查,只需将引用替换为远程 API 的链接:
Prefixed link to the Remote API with a misprint: [GET billling/info](https://remote.net/api-ref/#get-billling-info).
Oh no, the method is incorrect again.
另一方面,在线模式将做功课。它将检查远程 API 是否真的有方法GET billing/info。发现它没有它将保持参考不变:
Prefixed link to the Remote API with a misprint: `Remote-API: GET billling/info`.
Oh no, the method is incorrect again.
...并用以下信息警告我们:
WARNING: Cannot find method GET billling/info in Remote-API. Skipping
示例 5
Now let's reference a method which is present in both Client and Admin APIs: `GET service/healthcheck`.
在离线模式下,预处理器只会将引用替换为默认 API 的链接:
Now let's reference a method which is present in both Client and Admin APIs: [GET service/healthcheck](http://example.com/api/client/#get-service-healthcheck).
但在在线模式下,预处理器将遍历所有 API 方法列表。它会发现多次提到这种确切的方法,并且很困惑,根本不会取代参考:
Now let's reference a method which is present in both Client and Admin APIs: `GET service/healthcheck`.
您还将看到一个警告:
WARNING: GET /service/healthcheck is present in several APIs (Admin-API, Client-API). Please, use prefix. Skipping
捕获引用
APILinks 使用正则表达式来捕获对Markdown 文件中 API 方法的引用。
默认的正则表达式如下:
(?P<source>`((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>\S+)`)
此表达式接受如下引用:
Client-API: GET user/infoUPDATE user/details
请注意,默认表达式使用命名捕获组。如果要重新定义表达式,您可能也想使用所有这些。尽管并非所有这些都是必需的,但请参见下表。
| 团体 | 必需的 | 描述 |
|---|---|---|
| 资源 | 是的 | 完整的原始参考字符串 |
| 字首 | 不 | 指向 config 中 API 名称的前缀 |
| 动词 | 不 | HTTP 动词 as GET, POST, 等 |
| 命令 | 是的 | API 标头中声明的完整方法资源(可能包括端点前缀) |
要重新定义正则表达式reg-regex,请在预处理器配置中添加一个选项。
例如,如果您只想捕获带有前缀的引用,您可以使用以下命令:
preprocessors:
- apilinks:
reference:
- regex: '(?P<source>`((?P<prefix>[\w-]+):\s*)(?P<verb>POST|GET|PUT|UPDATE|DELETE)\s+(?P<command>\S+)`)'
此示例仅用于说明目的。您只需打开该
only_with_prefixes选项即可实现相同的目标。
现在,没有前缀 ( UPDATE user/details) 的引用将被忽略。
自定义输出
您可以自定义将替换参考字符串的输出字符串。为此,将模板添加到您的配置文件中。
模板是一个可能包含属性的字符串,用花括号括起来。这些属性将被替换为值,其余的将保持不变。
例如,查看默认模板:
preprocessors:
- apilinks:
reference:
- output_template: '[{verb} {command}]({url})',
不要忘记模板周围的单引号。通过这种方式,我们对 yaml 引擎说这是一个字符串,因为它不会与花括号混淆。
使用默认模板,引用字符串将被替换为:
[GET user/info](http://example.com/api/#get-user-info)
如果您不想将引用转换为链接,请使用您自己的模板。您可以在模板中使用的属性:
| 财产 | 描述 | 例子 |
|---|---|---|
| 网址 | 方法描述的完整网址 | http://example.com/api/#get-user-info |
| 资源 | 完整的原始参考字符串 | ` Client-API: GET user/info` |
| 字首 | 参考中使用的前缀 | Client-API |
| 动词 | 参考中使用的 HTTP 动词 | GET |
| 命令 | 删除端点前缀引用的 API 命令 | user/info |
| 端点前缀 | API 的端点前缀(如果endpoint_prefix填写了选项) |
/api/v0 |
解析 API 网页
aglio, mkdocs,slate网站后端
在在线模式下,APILinks 会遍历 API 网页内容并收集那里描述的所有方法。
为此,预处理器扫描每个 HTML h1、h2、h3、h4标签并存储其id属性(这是要构造的链接的锚点)和标签的内容(标题本身)。
例如在这个链接中:
<h2 id="get-user-info">GET user/info</h2>
锚点是get-user-info,标题是GET user/info。
要构建指向方法描述的链接,我们必须为其创建正确的锚点。要创建锚点,我们需要先重建标题。但是标题格式可能是任意的,这就是我们需要header_template配置选项的原因。
Theheader_template是一个可能包含属性的字符串,用花括号括起来。当预处理器尝试重建航向时,这些属性将被替换为值。其余的将保持不变。
例如,如果您的 API 标题如下所示:
<h2 id="method-user-info-get">Method user/info (GET)</h2>
您应该使用以下选项:
...
API:
Client-API:
header_template: 'Method {command} ({verb})'
...
不要忘记模板周围的单引号。这样我们就对 yaml 引擎说这是一个字符串。
如果您的标题根本没有动词:
<h2 id="user-info">user/info</h2>
您应该使用以下选项:
...
API:
Client-API:
header_template: '{command}'
...
您可以在模板中使用的属性:
| 财产 | 描述 | 例子 |
|---|---|---|
| 动词 | 参考中使用的 HTTP 动词 | GET |
| 命令 | 引用的 API 命令 | user/info |
| 端点前缀 | API 的端点前缀(如果endpoint_prefix填写了选项) |
/api/v0 |
swagger和redoc网站后端
对于 Swagger 和 Redoc,它有点不同。为了找出方法描述的正确锚点,我们需要知道operation_id方法。为此,我们需要swagger.json用于生成网站的规范文件 ( )。
这就是为什么 Swagger 和 Redoc 站点 APILinks 解析的不是网站本身,而是规范文件。现在你不能自定义锚格式,对于 Swagger 来说是这样的:
#\{tag}\{operationId}
就像 Redoc 一样:
operation\{operationId}