better-notion 1.0.1__py3-none-any.whl → 1.1.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.
- better_notion/_sdk/client.py +106 -3
- better_notion/_sdk/plugins.py +180 -0
- better_notion/plugins/base.py +99 -1
- better_notion/plugins/loader.py +51 -1
- better_notion/plugins/official/__init__.py +1 -3
- better_notion/plugins/official/agents.py +211 -74
- better_notion/plugins/official/agents_cli.py +1767 -0
- better_notion/plugins/official/agents_sdk/__init__.py +30 -0
- better_notion/plugins/official/agents_sdk/managers.py +973 -0
- better_notion/plugins/official/agents_sdk/models.py +2256 -0
- better_notion/plugins/official/agents_sdk/plugin.py +146 -0
- {better_notion-1.0.1.dist-info → better_notion-1.1.0.dist-info}/METADATA +2 -2
- {better_notion-1.0.1.dist-info → better_notion-1.1.0.dist-info}/RECORD +16 -10
- {better_notion-1.0.1.dist-info → better_notion-1.1.0.dist-info}/WHEEL +0 -0
- {better_notion-1.0.1.dist-info → better_notion-1.1.0.dist-info}/entry_points.txt +0 -0
- {better_notion-1.0.1.dist-info → better_notion-1.1.0.dist-info}/licenses/LICENSE +0 -0
better_notion/_sdk/client.py
CHANGED
|
@@ -99,6 +99,11 @@ class NotionClient:
|
|
|
99
99
|
self._comment_cache: Cache[object] = Cache()
|
|
100
100
|
# No cache for Block (too many)
|
|
101
101
|
|
|
102
|
+
# Plugin-managed resources (for SDK plugin system)
|
|
103
|
+
self._plugin_caches: dict[str, Cache[object]] = {}
|
|
104
|
+
self._plugin_managers: dict[str, object] = {}
|
|
105
|
+
self._plugin_models: dict[str, type] = {}
|
|
106
|
+
|
|
102
107
|
# Search cache
|
|
103
108
|
self._search_cache: dict[str, list[object]] = {}
|
|
104
109
|
|
|
@@ -259,10 +264,92 @@ class NotionClient:
|
|
|
259
264
|
|
|
260
265
|
return results
|
|
261
266
|
|
|
267
|
+
# ===== SDK PLUGIN SYSTEM =====
|
|
268
|
+
|
|
269
|
+
def register_sdk_plugin(
|
|
270
|
+
self,
|
|
271
|
+
models: dict[str, type] | None = None,
|
|
272
|
+
caches: dict[str, "Cache"] | None = None,
|
|
273
|
+
managers: dict[str, object] | None = None,
|
|
274
|
+
) -> None:
|
|
275
|
+
"""Register an SDK plugin's resources with the client.
|
|
276
|
+
|
|
277
|
+
This method allows plugins to register custom models, caches, and
|
|
278
|
+
managers without modifying the core SDK.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
models: Dict mapping model names to model classes
|
|
282
|
+
caches: Dict mapping cache names to Cache instances
|
|
283
|
+
managers: Dict mapping manager names to manager instances
|
|
284
|
+
|
|
285
|
+
Example:
|
|
286
|
+
>>> client.register_sdk_plugin(
|
|
287
|
+
... models={"Organization": Organization},
|
|
288
|
+
... caches={"organizations": Cache()},
|
|
289
|
+
... managers={"organizations": OrganizationManager(client)},
|
|
290
|
+
... )
|
|
291
|
+
"""
|
|
292
|
+
if models:
|
|
293
|
+
self._plugin_models.update(models)
|
|
294
|
+
|
|
295
|
+
if caches:
|
|
296
|
+
self._plugin_caches.update(caches)
|
|
297
|
+
|
|
298
|
+
if managers:
|
|
299
|
+
self._plugin_managers.update(managers)
|
|
300
|
+
|
|
301
|
+
def plugin_cache(self, name: str) -> "Cache | None":
|
|
302
|
+
"""Access a plugin-registered cache.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
name: Cache name (e.g., "organizations")
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
Cache instance if found, None otherwise
|
|
309
|
+
|
|
310
|
+
Example:
|
|
311
|
+
>>> cache = client.plugin_cache("organizations")
|
|
312
|
+
>>> if cache and org_id in cache:
|
|
313
|
+
... org = cache[org_id]
|
|
314
|
+
"""
|
|
315
|
+
return self._plugin_caches.get(name)
|
|
316
|
+
|
|
317
|
+
def plugin_manager(self, name: str) -> object | None:
|
|
318
|
+
"""Access a plugin-registered manager.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
name: Manager name (e.g., "organizations")
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
Manager instance if found, None otherwise
|
|
325
|
+
|
|
326
|
+
Example:
|
|
327
|
+
>>> orgs_mgr = client.plugin_manager("organizations")
|
|
328
|
+
>>> if orgs_mgr:
|
|
329
|
+
... orgs = await orgs_mgr.list()
|
|
330
|
+
"""
|
|
331
|
+
return self._plugin_managers.get(name)
|
|
332
|
+
|
|
333
|
+
def plugin_model(self, name: str) -> type | None:
|
|
334
|
+
"""Access a plugin-registered model class.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
name: Model name (e.g., "Organization")
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
Model class if found, None otherwise
|
|
341
|
+
|
|
342
|
+
Example:
|
|
343
|
+
>>> OrgClass = client.plugin_model("Organization")
|
|
344
|
+
>>> if OrgClass:
|
|
345
|
+
... org = await OrgClass.get(org_id, client=client)
|
|
346
|
+
"""
|
|
347
|
+
return self._plugin_models.get(name)
|
|
348
|
+
|
|
262
349
|
# ===== CACHE MANAGEMENT =====
|
|
263
350
|
|
|
264
351
|
def clear_all_caches(self) -> None:
|
|
265
|
-
"""Clear all caches.
|
|
352
|
+
"""Clear all caches including plugin caches.
|
|
266
353
|
|
|
267
354
|
Example:
|
|
268
355
|
>>> client.clear_all_caches()
|
|
@@ -272,8 +359,12 @@ class NotionClient:
|
|
|
272
359
|
self._page_cache.clear()
|
|
273
360
|
self._search_cache.clear()
|
|
274
361
|
|
|
362
|
+
# Clear plugin caches
|
|
363
|
+
for cache in self._plugin_caches.values():
|
|
364
|
+
cache.clear()
|
|
365
|
+
|
|
275
366
|
def get_cache_stats(self) -> dict[str, dict[str, Any]]:
|
|
276
|
-
"""Get statistics for all caches.
|
|
367
|
+
"""Get statistics for all caches including plugin caches.
|
|
277
368
|
|
|
278
369
|
Returns:
|
|
279
370
|
Dict with stats for each cache
|
|
@@ -283,10 +374,11 @@ class NotionClient:
|
|
|
283
374
|
>>> print(stats)
|
|
284
375
|
{
|
|
285
376
|
'user_cache': {'hits': 100, 'misses': 5, 'size': 50, 'hit_rate': 0.95},
|
|
377
|
+
'plugin:organizations': {'hits': 50, 'misses': 2, 'size': 10, 'hit_rate': 0.96},
|
|
286
378
|
...
|
|
287
379
|
}
|
|
288
380
|
"""
|
|
289
|
-
|
|
381
|
+
stats = {
|
|
290
382
|
"user_cache": {
|
|
291
383
|
"hits": self._user_cache.stats.hits,
|
|
292
384
|
"misses": self._user_cache.stats.misses,
|
|
@@ -310,6 +402,17 @@ class NotionClient:
|
|
|
310
402
|
}
|
|
311
403
|
}
|
|
312
404
|
|
|
405
|
+
# Add plugin cache stats
|
|
406
|
+
for cache_name, cache in self._plugin_caches.items():
|
|
407
|
+
stats[f"plugin:{cache_name}"] = {
|
|
408
|
+
"hits": cache.stats.hits,
|
|
409
|
+
"misses": cache.stats.misses,
|
|
410
|
+
"size": cache.stats.size,
|
|
411
|
+
"hit_rate": cache.stats.hit_rate
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return stats
|
|
415
|
+
|
|
313
416
|
# ===== CONTEXT MANAGER =====
|
|
314
417
|
|
|
315
418
|
async def __aenter__(self):
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""SDK Plugin System for extending NotionClient functionality.
|
|
2
|
+
|
|
3
|
+
This module provides the protocol interface for SDK-level plugins that need to:
|
|
4
|
+
- Register custom model classes
|
|
5
|
+
- Add dedicated caches to NotionClient
|
|
6
|
+
- Create custom managers
|
|
7
|
+
- Initialize plugin-specific resources
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from better_notion._sdk.cache import Cache
|
|
16
|
+
from better_notion._sdk.client import NotionClient
|
|
17
|
+
from better_notion._sdk.base.entity import BaseEntity
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SDKPluginInterface(Protocol):
|
|
21
|
+
"""
|
|
22
|
+
Protocol for SDK-level plugins that extend NotionClient functionality.
|
|
23
|
+
|
|
24
|
+
SDK plugins can register custom models, caches, and managers with the
|
|
25
|
+
NotionClient, enabling domain-specific extensions without modifying
|
|
26
|
+
the core SDK.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> class AgentsSDKPlugin:
|
|
30
|
+
... def register_models(self) -> dict[str, type[BaseEntity]]:
|
|
31
|
+
... return {"Organization": Organization}
|
|
32
|
+
...
|
|
33
|
+
... def register_caches(self, client: NotionClient) -> dict[str, Cache]:
|
|
34
|
+
... return {"organizations": Cache()}
|
|
35
|
+
...
|
|
36
|
+
... def register_managers(self, client: NotionClient) -> dict[str, Any]:
|
|
37
|
+
... return {"organizations": OrganizationManager(client)}
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def register_models(self) -> dict[str, type[BaseEntity]]:
|
|
41
|
+
"""Register custom model classes.
|
|
42
|
+
|
|
43
|
+
Model classes should inherit from BaseEntity and follow the
|
|
44
|
+
autonomous entity pattern (get, create, update methods).
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Dictionary mapping model names to model classes
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
>>> def register_models(self) -> dict[str, type[BaseEntity]]:
|
|
51
|
+
... return {
|
|
52
|
+
... "Organization": Organization,
|
|
53
|
+
... "Project": Project,
|
|
54
|
+
... "Task": Task,
|
|
55
|
+
... }
|
|
56
|
+
"""
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
def register_caches(self, client: "NotionClient") -> dict[str, "Cache"]:
|
|
60
|
+
"""Register custom caches with the client.
|
|
61
|
+
|
|
62
|
+
Caches are stored in the client and accessible via
|
|
63
|
+
client.plugin_cache(name). Each cache should have a unique name
|
|
64
|
+
to avoid collisions with other plugins.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
client: NotionClient instance to register caches with
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Dictionary mapping cache names to Cache instances
|
|
71
|
+
|
|
72
|
+
Example:
|
|
73
|
+
>>> def register_caches(self, client) -> dict[str, Cache]:
|
|
74
|
+
... return {
|
|
75
|
+
... "organizations": Cache(),
|
|
76
|
+
... "projects": Cache(),
|
|
77
|
+
... "tasks": Cache(),
|
|
78
|
+
... }
|
|
79
|
+
"""
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
def register_managers(self, client: "NotionClient") -> dict[str, Any]:
|
|
83
|
+
"""Register custom managers with the client.
|
|
84
|
+
|
|
85
|
+
Managers are accessible via client.plugin_manager(name).
|
|
86
|
+
They typically provide convenience methods for working with
|
|
87
|
+
the plugin's models.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
client: NotionClient instance
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Dictionary mapping manager names to manager instances
|
|
94
|
+
|
|
95
|
+
Example:
|
|
96
|
+
>>> def register_managers(self, client) -> dict[str, Any]:
|
|
97
|
+
... return {
|
|
98
|
+
... "organizations": OrganizationManager(client),
|
|
99
|
+
... "projects": ProjectManager(client),
|
|
100
|
+
... }
|
|
101
|
+
"""
|
|
102
|
+
...
|
|
103
|
+
|
|
104
|
+
def initialize(self, client: "NotionClient") -> None:
|
|
105
|
+
"""Initialize plugin-specific resources.
|
|
106
|
+
|
|
107
|
+
Called after all registrations (models, caches, managers) are
|
|
108
|
+
complete. Use this for setup tasks like loading configuration,
|
|
109
|
+
validating resources, or establishing connections.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
client: NotionClient instance
|
|
113
|
+
|
|
114
|
+
Example:
|
|
115
|
+
>>> def initialize(self, client) -> None:
|
|
116
|
+
... # Load database IDs from config
|
|
117
|
+
... db_ids = load_workspace_config()
|
|
118
|
+
... client._workspace_config = db_ids
|
|
119
|
+
"""
|
|
120
|
+
...
|
|
121
|
+
|
|
122
|
+
def get_info(self) -> dict[str, Any]:
|
|
123
|
+
"""Return plugin metadata.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Dictionary with plugin information
|
|
127
|
+
|
|
128
|
+
Example:
|
|
129
|
+
>>> def get_info(self) -> dict[str, Any]:
|
|
130
|
+
... return {
|
|
131
|
+
... "name": "agents-sdk",
|
|
132
|
+
... "version": "1.0.0",
|
|
133
|
+
... "description": "SDK extensions for agents workflow",
|
|
134
|
+
... }
|
|
135
|
+
"""
|
|
136
|
+
...
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class CombinedPluginInterface(Protocol):
|
|
140
|
+
"""
|
|
141
|
+
Protocol for plugins that extend both CLI and SDK.
|
|
142
|
+
|
|
143
|
+
This allows a single plugin class to provide:
|
|
144
|
+
- CLI commands (via register_commands)
|
|
145
|
+
- SDK extensions (via register_models, register_caches, etc.)
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
>>> class AgentsPlugin(CombinedPluginInterface):
|
|
149
|
+
... def register_commands(self, app: typer.Typer) -> None:
|
|
150
|
+
... # Register CLI commands
|
|
151
|
+
... pass
|
|
152
|
+
...
|
|
153
|
+
... def register_models(self) -> dict[str, type[BaseEntity]]:
|
|
154
|
+
... # Register SDK models
|
|
155
|
+
... return {"Organization": Organization}
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
def register_commands(self, app: Any) -> None:
|
|
159
|
+
"""Register CLI commands with Typer app."""
|
|
160
|
+
...
|
|
161
|
+
|
|
162
|
+
def register_models(self) -> dict[str, type[BaseEntity]]:
|
|
163
|
+
"""Register custom model classes."""
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
def register_caches(self, client: "NotionClient") -> dict[str, "Cache"]:
|
|
167
|
+
"""Register custom caches."""
|
|
168
|
+
...
|
|
169
|
+
|
|
170
|
+
def register_managers(self, client: "NotionClient") -> dict[str, Any]:
|
|
171
|
+
"""Register custom managers."""
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
def initialize(self, client: "NotionClient") -> None:
|
|
175
|
+
"""Initialize plugin resources."""
|
|
176
|
+
...
|
|
177
|
+
|
|
178
|
+
def get_info(self) -> dict[str, Any]:
|
|
179
|
+
"""Return plugin metadata."""
|
|
180
|
+
...
|
better_notion/plugins/base.py
CHANGED
|
@@ -5,14 +5,20 @@ Plugins can extend the CLI by:
|
|
|
5
5
|
1. Adding new commands (CommandPlugin)
|
|
6
6
|
2. Providing data filters/formatters (DataPlugin)
|
|
7
7
|
3. Combining both capabilities
|
|
8
|
+
4. Extending the SDK with models, caches, and managers (SDKPlugin)
|
|
8
9
|
"""
|
|
9
10
|
from __future__ import annotations
|
|
10
11
|
|
|
11
12
|
from abc import ABC, abstractmethod
|
|
12
|
-
from typing import Any, Protocol
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
|
13
14
|
|
|
14
15
|
import typer
|
|
15
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from better_notion._sdk.cache import Cache
|
|
19
|
+
from better_notion._sdk.client import NotionClient
|
|
20
|
+
from better_notion._sdk.base.entity import BaseEntity
|
|
21
|
+
|
|
16
22
|
|
|
17
23
|
class CommandPlugin(Protocol):
|
|
18
24
|
"""
|
|
@@ -148,6 +154,98 @@ class PluginInterface(ABC):
|
|
|
148
154
|
"""
|
|
149
155
|
return {}
|
|
150
156
|
|
|
157
|
+
# ===== SDK EXTENSION METHODS (OPTIONAL) =====
|
|
158
|
+
|
|
159
|
+
def register_sdk_models(self) -> dict[str, type[BaseEntity]]:
|
|
160
|
+
"""
|
|
161
|
+
Register custom SDK model classes.
|
|
162
|
+
|
|
163
|
+
Plugins can register domain-specific models that extend BaseEntity.
|
|
164
|
+
These models are accessible via client.plugin_model(name).
|
|
165
|
+
|
|
166
|
+
Default implementation returns empty dict.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
Dictionary mapping model names to model classes
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
>>> def register_sdk_models(self) -> dict[str, type[BaseEntity]]:
|
|
173
|
+
... return {
|
|
174
|
+
... "Organization": Organization,
|
|
175
|
+
... "Project": Project,
|
|
176
|
+
... }
|
|
177
|
+
"""
|
|
178
|
+
return {}
|
|
179
|
+
|
|
180
|
+
def register_sdk_caches(self, client: "NotionClient") -> dict[str, "Cache"]:
|
|
181
|
+
"""
|
|
182
|
+
Register custom SDK caches.
|
|
183
|
+
|
|
184
|
+
Plugins can register dedicated caches for their models.
|
|
185
|
+
These caches are accessible via client.plugin_cache(name).
|
|
186
|
+
|
|
187
|
+
Default implementation returns empty dict.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
client: NotionClient instance
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Dictionary mapping cache names to Cache instances
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
>>> def register_sdk_caches(self, client) -> dict[str, Cache]:
|
|
197
|
+
... return {
|
|
198
|
+
... "organizations": Cache(),
|
|
199
|
+
... "projects": Cache(),
|
|
200
|
+
... }
|
|
201
|
+
"""
|
|
202
|
+
return {}
|
|
203
|
+
|
|
204
|
+
def register_sdk_managers(self, client: "NotionClient") -> dict[str, Any]:
|
|
205
|
+
"""
|
|
206
|
+
Register custom SDK managers.
|
|
207
|
+
|
|
208
|
+
Plugins can register managers that provide convenience methods
|
|
209
|
+
for working with their models. Managers are accessible via
|
|
210
|
+
client.plugin_manager(name).
|
|
211
|
+
|
|
212
|
+
Default implementation returns empty dict.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
client: NotionClient instance
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Dictionary mapping manager names to manager instances
|
|
219
|
+
|
|
220
|
+
Example:
|
|
221
|
+
>>> def register_sdk_managers(self, client) -> dict[str, Any]:
|
|
222
|
+
... return {
|
|
223
|
+
... "organizations": OrganizationManager(client),
|
|
224
|
+
... }
|
|
225
|
+
"""
|
|
226
|
+
return {}
|
|
227
|
+
|
|
228
|
+
def sdk_initialize(self, client: "NotionClient") -> None:
|
|
229
|
+
"""
|
|
230
|
+
Initialize SDK plugin resources.
|
|
231
|
+
|
|
232
|
+
Called after all registrations are complete. Use this for
|
|
233
|
+
setup tasks like loading configuration, validating resources,
|
|
234
|
+
or establishing connections.
|
|
235
|
+
|
|
236
|
+
Default implementation does nothing.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
client: NotionClient instance
|
|
240
|
+
|
|
241
|
+
Example:
|
|
242
|
+
>>> def sdk_initialize(self, client) -> None:
|
|
243
|
+
... # Load workspace configuration
|
|
244
|
+
... config = load_workspace_config()
|
|
245
|
+
... client._workspace_config = config
|
|
246
|
+
"""
|
|
247
|
+
pass
|
|
248
|
+
|
|
151
249
|
def validate(self) -> tuple[bool, list[str]]:
|
|
152
250
|
"""
|
|
153
251
|
Validate the plugin structure and configuration.
|
better_notion/plugins/loader.py
CHANGED
|
@@ -13,10 +13,13 @@ import importlib.util
|
|
|
13
13
|
import json
|
|
14
14
|
import sys
|
|
15
15
|
from pathlib import Path
|
|
16
|
-
from typing import Any
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
17
|
|
|
18
18
|
from better_notion.plugins.base import CommandPlugin
|
|
19
19
|
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from better_notion._sdk.client import NotionClient
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
class PluginLoader:
|
|
22
25
|
"""
|
|
@@ -242,3 +245,50 @@ class PluginLoader:
|
|
|
242
245
|
return True
|
|
243
246
|
|
|
244
247
|
return False
|
|
248
|
+
|
|
249
|
+
def register_sdk_extensions(self, client: "NotionClient") -> None:
|
|
250
|
+
"""
|
|
251
|
+
Register SDK extensions from all loaded plugins with a NotionClient.
|
|
252
|
+
|
|
253
|
+
This method iterates through all loaded plugins and registers their
|
|
254
|
+
SDK models, caches, and managers with the provided NotionClient instance.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
client: NotionClient instance to register extensions with
|
|
258
|
+
|
|
259
|
+
Example:
|
|
260
|
+
>>> loader = PluginLoader()
|
|
261
|
+
>>> loader.discover() # Load plugins first
|
|
262
|
+
>>> client = NotionClient(auth="...")
|
|
263
|
+
>>> loader.register_sdk_extensions(client)
|
|
264
|
+
"""
|
|
265
|
+
# Get all loaded plugins
|
|
266
|
+
plugins = list(self.loaded_plugins.values())
|
|
267
|
+
|
|
268
|
+
# Also discover plugins if not already loaded
|
|
269
|
+
if not plugins:
|
|
270
|
+
plugins = self.discover()
|
|
271
|
+
|
|
272
|
+
# Register SDK extensions from each plugin
|
|
273
|
+
for plugin in plugins:
|
|
274
|
+
try:
|
|
275
|
+
# Register models
|
|
276
|
+
models = plugin.register_sdk_models()
|
|
277
|
+
if models:
|
|
278
|
+
client._plugin_models.update(models)
|
|
279
|
+
|
|
280
|
+
# Register caches
|
|
281
|
+
caches = plugin.register_sdk_caches(client)
|
|
282
|
+
if caches:
|
|
283
|
+
client._plugin_caches.update(caches)
|
|
284
|
+
|
|
285
|
+
# Register managers
|
|
286
|
+
managers = plugin.register_sdk_managers(client)
|
|
287
|
+
if managers:
|
|
288
|
+
client._plugin_managers.update(managers)
|
|
289
|
+
|
|
290
|
+
# Initialize plugin
|
|
291
|
+
plugin.sdk_initialize(client)
|
|
292
|
+
except Exception:
|
|
293
|
+
# Continue with other plugins if one fails
|
|
294
|
+
continue
|
|
@@ -4,12 +4,10 @@ Official plugins for Better Notion CLI.
|
|
|
4
4
|
This package contains officially maintained plugins that extend
|
|
5
5
|
the CLI with commonly-needed functionality.
|
|
6
6
|
"""
|
|
7
|
-
from better_notion.plugins.official.agents import AgentsPlugin
|
|
8
7
|
from better_notion.plugins.official.productivity import ProductivityPlugin
|
|
9
8
|
|
|
10
|
-
__all__ = ["
|
|
9
|
+
__all__ = ["ProductivityPlugin"]
|
|
11
10
|
|
|
12
11
|
OFFICIAL_PLUGINS = [
|
|
13
|
-
AgentsPlugin,
|
|
14
12
|
ProductivityPlugin,
|
|
15
13
|
]
|