Skip to content

Commit a67c25d

Browse files
authored
💥 [Breaking] Deprecate get_interface method (#3)
* 🎨 Friendly to type checking * 🩺 Require a higher version of Python * 💥 [Breaking] Deprecate `get_interface` method * 🐛 Fix the issue of Black going on strike
1 parent 9acd832 commit a67c25d

File tree

11 files changed

+890
-453
lines changed

11 files changed

+890
-453
lines changed

README.md

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# GraiaX Playwright
44

5-
*适用于 Graia Project 的 Playwright 管理器*
5+
_适用于 Graia Project 的 Playwright 管理器_
66

77
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
88
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
@@ -53,20 +53,15 @@ launart.launch_blocking()
5353
from creart import create
5454
from launart import Launart
5555
from graia.ariadne.util.saya import listen
56-
from graiax.playwright import PlaywrightBrowser
57-
58-
# 此处代码为没有使用 Persistent Context 的示例
59-
# 若使用 Persistent Context 请使用 `context = launart.get_interface(PlaywrightContext)`
60-
# 该方法获得的对象与 playwright.async_api.BrowserContext 兼容
56+
from graiax.playwright import PlaywrightService
6157

6258

6359
@listen(...)
6460
async def function(app: Ariadne):
6561
launart = create(Launart)
66-
browser = launart.get_interface(PlaywrightBrowser)
67-
# 此处的 browser 之用法与 playwright.async_api.Browser 无异,但要注意的是下方代码的返回值为 False。
68-
# `isinstance(browser, playwright.async_api.Browser)`
69-
async with browser.page( # 此 API 启用了自动上下文管理
62+
pw_service = launart.get_component(PlaywrightService)
63+
64+
async with pw_service.page( # 此 API 启用了自动上下文管理
7065
viewport={"width": 800, "height": 10},
7166
device_scale_factor=1.5,
7267
) as page:
@@ -77,20 +72,26 @@ async def function(app: Ariadne):
7772

7873
### 高级用法之一
7974

80-
上面配合 Saya 使用的例子展示了创建一个页面的例子,但假如我们需要一个与其他页面**隔离**的新页面(例如 cookie
81-
等),那么我们可以使用 `browser.page(context=True)` 在创建页面时使用一个新的上下文,如下所示:
75+
上面配合 Saya 使用的例子展示了创建一个页面的例子,但该页面默认与其他页面互相**隔离**(例如 cookie
76+
等),假如我们需要一个与其他页面**隔离**的新页面,那么我们可以使用
77+
`page(use_global_context=False)` 在创建页面时使用一个新的上下文,如下所示:
8278

8379
> [!NOTE]
84-
> 该种用法不支持持久性上下文(Persistent Context)
80+
> 该种用法中的新上下文,仍受到 Playwright 启动参数的影响
81+
>
82+
> 如果你传入了例如 `viewport` 之类的只有新创建上下文或者新页面才支持的参数时,则会忽略
83+
> `use_global_context` 参数。此时若 `without_new_context`
84+
> `True`(默认行为),则将会直接使用浏览器实例创建新页面。
85+
> 反之则会先创建新上下文再用新的上下文创建新页面,但是结束时新的页面和上下文都会被关闭。
8586
>
8687
> 更多信息详见:<https://playwright.dev/python/docs/browser-contexts>
8788
8889
```python
8990
@listen(...)
9091
async def function(app: Ariadne):
9192
launart = create(Launart)
92-
browser = launart.get_interface(PlaywrightBrowser)
93-
async with browser.page(new_context=True) as page: # 此 API 启用了自动上下文管理
93+
pw_service = launart.get_component(PlaywrightService)
94+
async with pw_service.page(use_global_context=False) as page: # 此 API 启用了自动上下文管理
9495
await page.set_content("Hello World!")
9596
img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale="device")
9697
...
@@ -102,9 +103,6 @@ async def function(app: Ariadne):
102103
版本起,可以在创建 PlaywrightService 时为全局的 Browser Context 指定 viewport,然后在截图时使用全局
103104
Browser Context 截图,如下所示:
104105

105-
> [!NOTE]
106-
> 该种用法不支持持久性上下文(Persistent Context)
107-
108106
**机器人入口文件:**
109107

110108
```python
@@ -114,19 +112,68 @@ launart.add_service(PlaywrightService("chromium"))
114112
**Saya 模块中:**
115113

116114
```python
117-
from graiax.playwright import PlaywrightContext
115+
from graiax.playwright import PlaywrightService
118116

119117

120118
@listen(...)
121119
async def function(app: Ariadne):
122120
launart = create(Launart)
123-
context = launart.get_interface(PlaywrightContext)
124-
async with context.page() as page: # 此 API 启用了自动上下文管理
125-
await page.set_content("Hello World!")
126-
img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale="device")
121+
pw_service = manager.get_component(PlaywrightService)
122+
async with pw_service.context(...) as context: # 此 API 启用了自动上下文管理
123+
page = context.new_page()
124+
try:
125+
await page.set_content("Hello World!")
126+
img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale='device')
127+
finally:
128+
page.stop()
127129
...
128130
```
129131

132+
### 高级用法之三
133+
134+
通过依赖注入来获取 `PlaywrightService`,前面的代码中获取 `PlaywrightService` 都需要通过 Launart
135+
`get_component()` 方法,你也可以通过自定义一个 BCC 的 `Dispatcher` 来实现依赖注入。
136+
137+
编写一个 `Dispatcher`
138+
139+
```python
140+
from graia.broadcast.entities.dispatcher import BaseDispatcher
141+
from graia.broadcast.interfaces.dispatcher import DispatcherInterface
142+
143+
class CustomDispatcher(BaseDispatcher):
144+
@classmethod
145+
async def catch(cls, interface: DispatcherInterface):
146+
with contextlib.suppress(TypeError):
147+
if generic_isinstance(interface.event, Service):
148+
manager = Launart.current()
149+
return manager.get_component(interface.annotation)
150+
```
151+
152+
在启动 Launart 之前获取一个 BCC 实例并对其应用这个 `Dispatcher`
153+
154+
```python
155+
from creart import it
156+
from graia.broadcast import Broadcast
157+
158+
bcc = it(Broadcast)
159+
bcc.finale_dispatchers.append(RedbotDispatcher)
160+
161+
...
162+
163+
launart.launch_blocking() # 或者是 avilla.launch()
164+
```
165+
166+
之后用起来就很简单了,你可以对比一下有什么不同:
167+
168+
```python
169+
from graiax.playwright import PlaywrightService
170+
171+
@listen(...)
172+
async def function(app: Ariadne, pw_service: PlaywrightService):
173+
async with pw_service.page(...) as page:
174+
...
175+
```
176+
130177
## 许可证
131178

132179
本项目使用 [`MIT`](./LICENSE) 许可证进行许可。

0 commit comments

Comments
 (0)