nonebot-plugin-htmlrender 0.6.7__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. nonebot_plugin_htmlrender/__init__.py +146 -21
  2. nonebot_plugin_htmlrender/_bootstrap.py +81 -0
  3. nonebot_plugin_htmlrender/_compat.py +286 -0
  4. nonebot_plugin_htmlrender/backend/__init__.py +42 -0
  5. nonebot_plugin_htmlrender/backend/base.py +217 -0
  6. nonebot_plugin_htmlrender/backend/factory.py +194 -0
  7. nonebot_plugin_htmlrender/backend/playwright/__init__.py +98 -0
  8. nonebot_plugin_htmlrender/backend/playwright/_page.py +258 -0
  9. nonebot_plugin_htmlrender/backend/playwright/config.py +244 -0
  10. nonebot_plugin_htmlrender/backend/playwright/data_source.py +90 -0
  11. nonebot_plugin_htmlrender/backend/playwright/install.py +161 -0
  12. nonebot_plugin_htmlrender/backend/playwright/models.py +432 -0
  13. nonebot_plugin_htmlrender/backend/playwright/operations.py +671 -0
  14. nonebot_plugin_htmlrender/backend/playwright/render.py +764 -0
  15. nonebot_plugin_htmlrender/backend/playwright/runtime.py +441 -0
  16. nonebot_plugin_htmlrender/backend/playwright/telemetry.py +240 -0
  17. nonebot_plugin_htmlrender/backend/playwright/types.py +280 -0
  18. nonebot_plugin_htmlrender/browser.py +33 -206
  19. nonebot_plugin_htmlrender/config.py +41 -61
  20. nonebot_plugin_htmlrender/consts.py +109 -23
  21. nonebot_plugin_htmlrender/data_source.py +36 -312
  22. nonebot_plugin_htmlrender/py.typed +0 -0
  23. nonebot_plugin_htmlrender/render.py +712 -0
  24. nonebot_plugin_htmlrender/resources/__init__.py +34 -0
  25. nonebot_plugin_htmlrender/resources/config.py +66 -0
  26. nonebot_plugin_htmlrender/resources/filehost/__init__.py +162 -0
  27. nonebot_plugin_htmlrender/resources/filehost/cache.py +258 -0
  28. nonebot_plugin_htmlrender/resources/filehost/guard.py +159 -0
  29. nonebot_plugin_htmlrender/resources/filehost/warmup.py +251 -0
  30. nonebot_plugin_htmlrender/resources/resolve.py +338 -0
  31. nonebot_plugin_htmlrender/resources/template.py +313 -0
  32. nonebot_plugin_htmlrender/utils/__init__.py +48 -0
  33. nonebot_plugin_htmlrender/utils/install.py +172 -0
  34. nonebot_plugin_htmlrender/utils/process.py +292 -0
  35. nonebot_plugin_htmlrender/utils/signal.py +165 -0
  36. nonebot_plugin_htmlrender/utils/telemetry/__init__.py +91 -0
  37. nonebot_plugin_htmlrender/utils/telemetry/common.py +160 -0
  38. nonebot_plugin_htmlrender/utils/telemetry/prometheus.py +199 -0
  39. nonebot_plugin_htmlrender/utils/telemetry/sentry.py +228 -0
  40. nonebot_plugin_htmlrender-0.7.0.dist-info/METADATA +205 -0
  41. nonebot_plugin_htmlrender-0.7.0.dist-info/RECORD +52 -0
  42. {nonebot_plugin_htmlrender-0.6.7.dist-info → nonebot_plugin_htmlrender-0.7.0.dist-info}/WHEEL +1 -1
  43. nonebot_plugin_htmlrender/install.py +0 -239
  44. nonebot_plugin_htmlrender/process.py +0 -165
  45. nonebot_plugin_htmlrender/signal.py +0 -138
  46. nonebot_plugin_htmlrender/utils.py +0 -161
  47. nonebot_plugin_htmlrender-0.6.7.dist-info/METADATA +0 -220
  48. nonebot_plugin_htmlrender-0.6.7.dist-info/RECORD +0 -22
  49. /nonebot_plugin_htmlrender/templates/{github-markdown-light.css → markdown/github-markdown-light.css} +0 -0
  50. /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/katex.min.b64_fonts.css +0 -0
  51. /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/katex.min.js +0 -0
  52. /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/mathtex-script-type.min.js +0 -0
  53. /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/mhchem.min.js +0 -0
  54. /nonebot_plugin_htmlrender/templates/{markdown.html → markdown/markdown.html} +0 -0
  55. /nonebot_plugin_htmlrender/templates/{pygments-default.css → markdown/pygments-default.css} +0 -0
  56. /nonebot_plugin_htmlrender/templates/{text.css → text/text.css} +0 -0
  57. /nonebot_plugin_htmlrender/templates/{text.html → text/text.html} +0 -0
  58. {nonebot_plugin_htmlrender-0.6.7.dist-info → nonebot_plugin_htmlrender-0.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,55 +1,180 @@
1
+ from typing_extensions import Unpack
2
+
1
3
  import nonebot
4
+ from nonebot import require
2
5
  from nonebot.log import logger
3
6
  from nonebot.plugin import PluginMetadata
4
7
 
5
- from nonebot_plugin_htmlrender.browser import get_browser as get_browser
6
- from nonebot_plugin_htmlrender.browser import get_new_page as get_new_page
7
- from nonebot_plugin_htmlrender.browser import init_browser as init_browser
8
- from nonebot_plugin_htmlrender.browser import shutdown_browser as shutdown_browser
9
- from nonebot_plugin_htmlrender.browser import start_browser as start_browser
10
- from nonebot_plugin_htmlrender.config import Config
11
- from nonebot_plugin_htmlrender.data_source import capture_element as capture_element
12
- from nonebot_plugin_htmlrender.data_source import html_to_pic as html_to_pic
13
- from nonebot_plugin_htmlrender.data_source import md_to_pic as md_to_pic
14
- from nonebot_plugin_htmlrender.data_source import template_to_html as template_to_html
15
- from nonebot_plugin_htmlrender.data_source import template_to_pic as template_to_pic
16
- from nonebot_plugin_htmlrender.data_source import text_to_pic as text_to_pic
8
+ require("nonebot_plugin_localstore")
9
+
10
+ from nonebot_plugin_htmlrender._bootstrap import (
11
+ _bootstrap_filehost_guard_on_import,
12
+ _bootstrap_optional_plugins_on_import,
13
+ )
14
+ from nonebot_plugin_htmlrender._bootstrap import (
15
+ _patch_filehost_request_headers_validator as _patch_filehost_request_headers_validator,
16
+ )
17
+
18
+ _bootstrap_optional_plugins_on_import()
19
+
20
+ from nonebot_plugin_htmlrender._compat import (
21
+ capture_element as capture_element,
22
+ )
23
+ from nonebot_plugin_htmlrender._compat import (
24
+ get_new_page as get_new_page,
25
+ )
26
+ from nonebot_plugin_htmlrender._compat import (
27
+ html_to_pic as html_to_pic,
28
+ )
29
+ from nonebot_plugin_htmlrender._compat import (
30
+ md_to_pic as md_to_pic,
31
+ )
32
+ from nonebot_plugin_htmlrender._compat import (
33
+ shutdown_htmlrender as shutdown_htmlrender,
34
+ )
35
+ from nonebot_plugin_htmlrender._compat import (
36
+ startup_htmlrender as startup_htmlrender,
37
+ )
38
+ from nonebot_plugin_htmlrender._compat import (
39
+ template_to_html as template_to_html,
40
+ )
41
+ from nonebot_plugin_htmlrender._compat import (
42
+ template_to_pic as template_to_pic,
43
+ )
44
+ from nonebot_plugin_htmlrender._compat import (
45
+ text_to_pic as text_to_pic,
46
+ )
47
+
48
+ # Wire the render context provider so that backend operations can obtain
49
+ # pages without importing the render module directly (avoids circular coupling).
50
+ from nonebot_plugin_htmlrender.backend.playwright._page import (
51
+ register_render_context_provider as _register_ctx_provider,
52
+ )
53
+ from nonebot_plugin_htmlrender.backend.playwright.runtime import (
54
+ clear_playwright_env_vars,
55
+ )
56
+ from nonebot_plugin_htmlrender.backend.playwright.types import BrowserSessionKwargs
57
+ from nonebot_plugin_htmlrender.config import Config, plugin_config
58
+ from nonebot_plugin_htmlrender.consts import RenderBackend, RenderStartupMode
59
+ from nonebot_plugin_htmlrender.render import (
60
+ available_render_backends,
61
+ capture_html_element,
62
+ get_default_render,
63
+ get_render,
64
+ get_render_backend_status,
65
+ get_render_context,
66
+ is_render_backend_available,
67
+ is_render_backend_registered,
68
+ list_render_backend_statuses,
69
+ probe_render,
70
+ registered_render_backends,
71
+ render_html,
72
+ render_markdown,
73
+ render_template,
74
+ render_template_html,
75
+ render_text,
76
+ shutdown_render,
77
+ startup_render,
78
+ unavailable_render_backends,
79
+ )
80
+ from nonebot_plugin_htmlrender.resources import (
81
+ ResourceResolveError,
82
+ resolve_template_vars,
83
+ to_resource_url,
84
+ )
85
+ from nonebot_plugin_htmlrender.resources.filehost import ensure_filehost_runtime_ready
86
+
87
+ _register_ctx_provider(get_render_context)
88
+ del _register_ctx_provider
17
89
 
18
90
  __plugin_meta__ = PluginMetadata(
19
91
  name="nonebot-plugin-htmlrender",
20
92
  description="通过浏览器渲染图片",
21
- usage="",
93
+ usage=(
94
+ "提供 HTML/Markdown/模板渲染为图片的能力,作为库插件供其他插件调用。\n"
95
+ "主要接口:render_html, render_text, render_markdown, render_template 等。"
96
+ ),
22
97
  type="library",
23
98
  config=Config,
24
99
  homepage="https://github.com/kexue-z/nonebot-plugin-htmlrender",
25
- extra={},
100
+ supported_adapters=None,
26
101
  )
27
102
 
28
103
  driver = nonebot.get_driver()
29
104
 
30
105
 
106
+ _bootstrap_filehost_guard_on_import()
107
+
108
+
31
109
  @driver.on_startup
32
- async def init(**kwargs):
110
+ async def init(**kwargs: Unpack[BrowserSessionKwargs]) -> None:
111
+ """插件启动时初始化渲染后端。"""
33
112
  logger.info("HTMLRender Starting...")
34
- await init_browser(**kwargs)
35
- logger.info("HTMLRender Started.")
113
+ if plugin_config.render_backend is None:
114
+ logger.info("No render backend selected; startup skipped.")
115
+ return
116
+
117
+ if plugin_config.render_backend == RenderBackend.PLAYWRIGHT:
118
+ await ensure_filehost_runtime_ready(reason="plugin_startup")
119
+
120
+ try:
121
+ startup_mode = plugin_config.render_startup_mode
122
+ if startup_mode == RenderStartupMode.OFF:
123
+ logger.info("Render startup skipped by configuration.")
124
+ return
125
+ if startup_mode == RenderStartupMode.WARMUP:
126
+ await startup_render(**kwargs)
127
+ else:
128
+ await startup_render(**kwargs)
129
+ await probe_render()
130
+ except Exception as e:
131
+ logger.exception("Failed to start render runtime.")
132
+ raise RuntimeError("Render runtime startup failed.") from e
133
+
134
+ logger.opt(colors=True).info(
135
+ f"HTMLRender Started with backend <cyan>{plugin_config.render_backend}</cyan>."
136
+ )
36
137
 
37
138
 
38
139
  @driver.on_shutdown
39
- async def shutdown():
140
+ async def shutdown() -> None:
141
+ """插件关闭时清理渲染资源。"""
40
142
  logger.info("HTMLRender Shutting down...")
41
- await shutdown_browser()
143
+ await shutdown_render()
144
+ clear_playwright_env_vars()
42
145
  logger.info("HTMLRender Shut down.")
43
146
 
44
147
 
45
148
  __all__ = [
149
+ "ResourceResolveError",
150
+ "available_render_backends",
46
151
  "capture_element",
152
+ "capture_html_element",
153
+ "get_default_render",
47
154
  "get_new_page",
155
+ "get_render",
156
+ "get_render_backend_status",
157
+ "get_render_context",
48
158
  "html_to_pic",
159
+ "is_render_backend_available",
160
+ "is_render_backend_registered",
161
+ "list_render_backend_statuses",
49
162
  "md_to_pic",
50
- "shutdown_browser",
51
- "start_browser",
163
+ "probe_render",
164
+ "registered_render_backends",
165
+ "render_html",
166
+ "render_markdown",
167
+ "render_template",
168
+ "render_template_html",
169
+ "render_text",
170
+ "resolve_template_vars",
171
+ "shutdown_htmlrender",
172
+ "shutdown_render",
173
+ "startup_htmlrender",
174
+ "startup_render",
52
175
  "template_to_html",
53
176
  "template_to_pic",
54
177
  "text_to_pic",
178
+ "to_resource_url",
179
+ "unavailable_render_backends",
55
180
  ]
@@ -0,0 +1,81 @@
1
+ """Bootstrap helpers executed at plugin import time."""
2
+
3
+ from importlib import import_module
4
+ from importlib.util import find_spec
5
+
6
+ from nonebot import require
7
+ from nonebot.log import logger
8
+
9
+ from nonebot_plugin_htmlrender.config import plugin_config
10
+ from nonebot_plugin_htmlrender.consts import RenderBackend
11
+ from nonebot_plugin_htmlrender.resources.filehost import (
12
+ ensure_filehost_request_guard_installed,
13
+ )
14
+
15
+ _OPTIONAL_PLUGIN_IDS = (
16
+ "nonebot_plugin_filehost",
17
+ "nonebot_plugin_sentry",
18
+ "nonebot_plugin_prometheus",
19
+ )
20
+
21
+
22
+ def _patch_filehost_request_headers_validator() -> None:
23
+ """修补 filehost 请求头验证器以兼容 pydantic。"""
24
+ try:
25
+ filehost_models = import_module("nonebot_plugin_filehost.models")
26
+ request_headers = getattr(filehost_models, "RequestHeaders", None)
27
+ request_scope_info = getattr(filehost_models, "RequestScopeInfo", None)
28
+ if request_headers is None or request_scope_info is None:
29
+ return
30
+ if bool(getattr(request_headers, "__htmlrender_validator_patched__", False)):
31
+ return
32
+
33
+ raw_validate = request_headers.__dict__.get("validate")
34
+ if not isinstance(raw_validate, classmethod):
35
+ return
36
+
37
+ validate_func = raw_validate.__func__
38
+
39
+ def _compat_validate(cls, value, *args, **kwargs): # type: ignore[no-untyped-def]
40
+ """兼容性验证包装器。"""
41
+ del args, kwargs
42
+ return validate_func(cls, value)
43
+
44
+ request_headers.validate = classmethod(_compat_validate)
45
+ request_headers.__htmlrender_validator_patched__ = True
46
+ model_rebuild = getattr(request_scope_info, "model_rebuild", None)
47
+ if callable(model_rebuild):
48
+ model_rebuild(force=True)
49
+ logger.opt(colors=True).info(
50
+ "Patched <c>nonebot_plugin_filehost</c> websocket scope validator for pydantic compatibility."
51
+ )
52
+ except Exception as e:
53
+ logger.opt(colors=True).warning(
54
+ "Failed to patch <c>nonebot_plugin_filehost</c> validator compatibility: <r>{e}</r>",
55
+ e=e,
56
+ )
57
+
58
+
59
+ def _bootstrap_optional_plugins_on_import() -> None:
60
+ """在导入时引导可选插件。"""
61
+ for plugin_name in _OPTIONAL_PLUGIN_IDS:
62
+ if find_spec(plugin_name) is None:
63
+ logger.opt(colors=True).info(
64
+ "Optional plugin <d>{plugin_name}</d> not installed, skip bootstrap.",
65
+ plugin_name=plugin_name,
66
+ )
67
+ continue
68
+ require(plugin_name)
69
+ if plugin_name == "nonebot_plugin_filehost":
70
+ _patch_filehost_request_headers_validator()
71
+ logger.opt(colors=True).info(
72
+ "Optional plugin <c>{plugin_name}</c> bootstrapped on import.",
73
+ plugin_name=plugin_name,
74
+ )
75
+
76
+
77
+ def _bootstrap_filehost_guard_on_import() -> None:
78
+ """在导入时安装 filehost 请求守卫。"""
79
+ if plugin_config.render_backend != RenderBackend.PLAYWRIGHT:
80
+ return
81
+ ensure_filehost_request_guard_installed(reason="plugin_import")
@@ -0,0 +1,286 @@
1
+ # ruff: noqa: A002, FBT001, FBT002, PTH109
2
+ """Backward-compatible deprecated API surface.
3
+
4
+ All deprecated top-level functions are defined here. Other modules
5
+ (``data_source``, ``browser``, ``__init__``) re-export from this
6
+ module so that old import paths keep working.
7
+ """
8
+
9
+ from collections.abc import AsyncIterator
10
+ from contextlib import asynccontextmanager
11
+ from os import getcwd
12
+ from typing import Any, Literal
13
+ from typing_extensions import Unpack, deprecated
14
+
15
+ from playwright.async_api import Browser
16
+
17
+ from nonebot_plugin_htmlrender.backend.playwright.operations import (
18
+ read_file as read_file,
19
+ )
20
+ from nonebot_plugin_htmlrender.backend.playwright.operations import (
21
+ read_tpl as read_tpl,
22
+ )
23
+ from nonebot_plugin_htmlrender.backend.playwright.runtime import (
24
+ clean_playwright_cache as _clean_playwright_cache,
25
+ )
26
+ from nonebot_plugin_htmlrender.backend.playwright.runtime import (
27
+ reconcile_legacy_playwright_cache as _reconcile_legacy_playwright_cache,
28
+ )
29
+ from nonebot_plugin_htmlrender.backend.playwright.types import (
30
+ BrowserSessionKwargs,
31
+ GotoKwargs,
32
+ HtmlPageKwargs,
33
+ LocatorScreenshotKwargs,
34
+ PageContextKwargs,
35
+ TemplatePageKwargs,
36
+ )
37
+ from nonebot_plugin_htmlrender.render import (
38
+ capture_html_element,
39
+ get_render,
40
+ get_render_context,
41
+ render_html,
42
+ render_markdown,
43
+ render_template,
44
+ render_template_html,
45
+ render_text,
46
+ shutdown_render,
47
+ startup_render,
48
+ )
49
+
50
+
51
+ def _require_browser(session: object) -> Browser:
52
+ """从渲染会话中提取 Browser 实例。
53
+
54
+ Args:
55
+ session: 渲染会话对象,需包含 ``handle`` 属性。
56
+
57
+ Returns:
58
+ 会话中的 :class:`Browser` 实例。
59
+
60
+ Raises:
61
+ RuntimeError: 当前渲染目标不是 Browser 实例时抛出。
62
+ """
63
+ browser = getattr(session, "handle", None)
64
+ if isinstance(browser, Browser):
65
+ return browser
66
+ raise RuntimeError("Current render target is not a Browser instance.")
67
+
68
+
69
+ @deprecated("`text_to_pic` is deprecated. Use `render_text` instead.")
70
+ async def text_to_pic(
71
+ text: str,
72
+ css_path: str = "",
73
+ width: int = 500,
74
+ type: Literal["jpeg", "png"] = "png",
75
+ quality: int | None = None,
76
+ device_scale_factor: float = 2,
77
+ screenshot_timeout: float | None = 30_000,
78
+ ) -> bytes:
79
+ """已弃用:将文本渲染为图片,请使用 ``render_text``。"""
80
+ return await render_text(
81
+ text,
82
+ css_path=css_path,
83
+ width=width,
84
+ image_type=type,
85
+ quality=quality,
86
+ device_scale_factor=device_scale_factor,
87
+ screenshot_timeout=screenshot_timeout,
88
+ )
89
+
90
+
91
+ @deprecated("`md_to_pic` is deprecated. Use `render_markdown` instead.")
92
+ async def md_to_pic(
93
+ md: str = "",
94
+ md_path: str = "",
95
+ css_path: str = "",
96
+ width: int = 500,
97
+ type: Literal["jpeg", "png"] = "png",
98
+ quality: int | None = None,
99
+ device_scale_factor: float = 2,
100
+ screenshot_timeout: float | None = 30_000,
101
+ ) -> bytes:
102
+ """已弃用:将 Markdown 渲染为图片,请使用 ``render_markdown``。"""
103
+ return await render_markdown(
104
+ md,
105
+ md_path=md_path,
106
+ css_path=css_path,
107
+ width=width,
108
+ image_type=type,
109
+ quality=quality,
110
+ device_scale_factor=device_scale_factor,
111
+ screenshot_timeout=screenshot_timeout,
112
+ )
113
+
114
+
115
+ @deprecated("`template_to_html` is deprecated. Use `render_template_html` instead.")
116
+ async def template_to_html(
117
+ template_path: str,
118
+ template_name: str,
119
+ filters: dict[str, Any] | None = None,
120
+ **kwargs: Any,
121
+ ) -> str:
122
+ """已弃用:将模板渲染为 HTML,请使用 ``render_template_html``。"""
123
+ return await render_template_html(
124
+ template_path,
125
+ template_name=template_name,
126
+ filters=filters,
127
+ **kwargs,
128
+ )
129
+
130
+
131
+ @deprecated("`html_to_pic` is deprecated. Use `render_html` instead.")
132
+ async def html_to_pic(
133
+ html: str,
134
+ wait: int = 0,
135
+ template_path: str | None = None,
136
+ type: Literal["jpeg", "png"] = "png",
137
+ quality: int | None = None,
138
+ device_scale_factor: float = 2,
139
+ screenshot_timeout: float | None = 30_000,
140
+ full_page: bool = True,
141
+ **kwargs: Unpack[HtmlPageKwargs],
142
+ ) -> bytes:
143
+ """已弃用:将 HTML 渲染为图片,请使用 ``render_html``。"""
144
+ return await render_html(
145
+ html,
146
+ wait=wait,
147
+ template_path=template_path,
148
+ image_type=type,
149
+ quality=quality,
150
+ device_scale_factor=device_scale_factor,
151
+ screenshot_timeout=screenshot_timeout,
152
+ full_page=full_page,
153
+ **kwargs,
154
+ )
155
+
156
+
157
+ @deprecated("`template_to_pic` is deprecated. Use `render_template` instead.")
158
+ async def template_to_pic(
159
+ template_path: str,
160
+ template_name: str,
161
+ templates: dict[str, Any],
162
+ filters: dict[str, Any] | None = None,
163
+ pages: TemplatePageKwargs | None = None,
164
+ wait: int = 0,
165
+ type: Literal["jpeg", "png"] = "png",
166
+ quality: int | None = None,
167
+ device_scale_factor: float = 2,
168
+ screenshot_timeout: float | None = 30_000,
169
+ ) -> bytes:
170
+ """已弃用:将模板渲染为图片,请使用 ``render_template``。"""
171
+ default_pages: TemplatePageKwargs = {
172
+ "viewport": {"width": 500, "height": 10},
173
+ "base_url": f"file://{getcwd()}",
174
+ }
175
+ return await render_template(
176
+ template_path,
177
+ template_name=template_name,
178
+ templates=templates,
179
+ filters=filters,
180
+ pages=pages or default_pages,
181
+ wait=wait,
182
+ image_type=type,
183
+ quality=quality,
184
+ device_scale_factor=device_scale_factor,
185
+ screenshot_timeout=screenshot_timeout,
186
+ )
187
+
188
+
189
+ @deprecated("`capture_element` is deprecated. Use `capture_html_element` instead.")
190
+ async def capture_element(
191
+ url: str,
192
+ element: str,
193
+ page_kwargs: PageContextKwargs | None = None,
194
+ goto_kwargs: GotoKwargs | None = None,
195
+ screenshot_kwargs: LocatorScreenshotKwargs | None = None,
196
+ ) -> bytes:
197
+ """已弃用:捕获页面元素截图,请使用 ``capture_html_element``。"""
198
+ return await capture_html_element(
199
+ url,
200
+ element,
201
+ page_kwargs=page_kwargs,
202
+ goto_kwargs=goto_kwargs,
203
+ screenshot_kwargs=screenshot_kwargs,
204
+ )
205
+
206
+
207
+ @deprecated("`get_new_page` is deprecated. Use `get_render_context` instead.")
208
+ @asynccontextmanager
209
+ async def get_new_page(
210
+ device_scale_factor: float = 2,
211
+ **kwargs: Unpack[HtmlPageKwargs],
212
+ ) -> AsyncIterator[object]:
213
+ """已弃用:获取新的浏览器页面,请使用 ``get_render_context``。"""
214
+ async with get_render_context(
215
+ device_scale_factor=device_scale_factor,
216
+ **kwargs,
217
+ ) as page:
218
+ yield page
219
+
220
+
221
+ @deprecated("`get_browser` is deprecated. Use `get_render` instead.")
222
+ async def get_browser(**kwargs: Unpack[BrowserSessionKwargs]) -> Browser:
223
+ """已弃用:获取浏览器实例,请使用 ``get_render``。"""
224
+ session = await get_render(**kwargs)
225
+ return _require_browser(session)
226
+
227
+
228
+ @deprecated("`startup_htmlrender` is deprecated. Use `startup_render` instead.")
229
+ async def startup_htmlrender(**kwargs: Unpack[BrowserSessionKwargs]) -> Browser:
230
+ """已弃用:启动 HTML 渲染引擎,请使用 ``startup_render``。"""
231
+ session = await startup_render(**kwargs)
232
+ return _require_browser(session)
233
+
234
+
235
+ @deprecated("`shutdown_htmlrender` is deprecated. Use `shutdown_render` instead.")
236
+ async def shutdown_htmlrender() -> None:
237
+ """已弃用:关闭 HTML 渲染引擎,请使用 ``shutdown_render``。"""
238
+ await shutdown_render()
239
+
240
+
241
+ @deprecated("`_launch` is deprecated. Use `startup_render` instead.")
242
+ async def _launch(
243
+ browser_type: str,
244
+ **kwargs: Unpack[BrowserSessionKwargs],
245
+ ) -> Browser:
246
+ """已弃用:启动浏览器,请使用 ``startup_render``。"""
247
+ _ = browser_type
248
+ return await startup_htmlrender(**kwargs)
249
+
250
+
251
+ @deprecated(
252
+ "`clean_playwright_cache` from `nonebot_plugin_htmlrender.browser` is deprecated. "
253
+ "Use `nonebot_plugin_htmlrender.backend.playwright.runtime.reconcile_legacy_playwright_cache` instead."
254
+ )
255
+ def clean_playwright_cache(*, cleanup: bool) -> None:
256
+ """已弃用:清理 Playwright 缓存。"""
257
+ _clean_playwright_cache(cleanup=cleanup)
258
+
259
+
260
+ @deprecated(
261
+ "`reconcile_legacy_playwright_cache` from `nonebot_plugin_htmlrender.browser` "
262
+ "is deprecated. Use "
263
+ "`nonebot_plugin_htmlrender.backend.playwright.runtime.reconcile_legacy_playwright_cache` instead."
264
+ )
265
+ def reconcile_legacy_playwright_cache(*, cleanup: bool) -> None:
266
+ """已弃用:协调旧版 Playwright 缓存目录。"""
267
+ _reconcile_legacy_playwright_cache(cleanup=cleanup)
268
+
269
+
270
+ __all__ = [
271
+ "_launch",
272
+ "capture_element",
273
+ "clean_playwright_cache",
274
+ "get_browser",
275
+ "get_new_page",
276
+ "html_to_pic",
277
+ "md_to_pic",
278
+ "read_file",
279
+ "read_tpl",
280
+ "reconcile_legacy_playwright_cache",
281
+ "shutdown_htmlrender",
282
+ "startup_htmlrender",
283
+ "template_to_html",
284
+ "template_to_pic",
285
+ "text_to_pic",
286
+ ]
@@ -0,0 +1,42 @@
1
+ from .base import (
2
+ Backend,
3
+ BackendCapability,
4
+ RenderRuntime,
5
+ RenderSession,
6
+ SupportsHtmlRenderBackend,
7
+ )
8
+ from .factory import (
9
+ BackendAvailability,
10
+ BackendStatus,
11
+ available_backends,
12
+ backend_statuses,
13
+ build_backend,
14
+ get_backend_status,
15
+ is_backend_available,
16
+ is_backend_registered,
17
+ register_backend,
18
+ registered_backends,
19
+ unavailable_backends,
20
+ )
21
+ from .playwright import PlaywrightBackend, PlaywrightMode
22
+
23
+ __all__ = [
24
+ "Backend",
25
+ "BackendAvailability",
26
+ "BackendCapability",
27
+ "BackendStatus",
28
+ "PlaywrightBackend",
29
+ "PlaywrightMode",
30
+ "RenderRuntime",
31
+ "RenderSession",
32
+ "SupportsHtmlRenderBackend",
33
+ "available_backends",
34
+ "backend_statuses",
35
+ "build_backend",
36
+ "get_backend_status",
37
+ "is_backend_available",
38
+ "is_backend_registered",
39
+ "register_backend",
40
+ "registered_backends",
41
+ "unavailable_backends",
42
+ ]