Coverage for src/lexigram/web/contributors/discovery.py: 44%
18 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 04:37 +0800
1"""Web contributor discovery via entry-points.
3Discovers and loads web contributors from installed packages via the
4``lexigram.web.contributors`` entry-point group. Failed contributors
5are logged but do not halt the discovery process.
6"""
8from __future__ import annotations
10from importlib.metadata import entry_points
12from lexigram.contracts.web import WebContributorProtocol
13from lexigram.logging import get_logger
15logger = get_logger(__name__)
17ENTRY_POINT_GROUP = "lexigram.web.contributors"
20def load_web_contributors() -> list[WebContributorProtocol]:
21 """Load web contributors from entry-points.
23 Scans the ``lexigram.web.contributors`` entry-point group and loads
24 each registered contributor class. Failed loads (import errors,
25 instantiation failures) are logged and skipped without halting
26 the discovery process.
28 Returns:
29 List of successfully loaded and instantiated contributor instances.
31 Example:
32 A package registers a contributor via pyproject.toml::
34 [project.entry-points."lexigram.web.contributors"]
35 graphql = "lexigram.graphql.web.contributor:GraphQLWebContributor"
37 The web provider loads all contributors at startup::
39 contributors = load_web_contributors()
40 for contributor in contributors:
41 logger.info(f"Loaded contributor: {contributor.contributor_id}")
42 """
43 contributors: list[WebContributorProtocol] = []
45 for contributor_entry_point in entry_points(group=ENTRY_POINT_GROUP):
46 try:
47 contributor_class = contributor_entry_point.load()
48 contributor = contributor_class()
49 except Exception as exc: # noqa: BLE001
50 logger.warning(
51 "web.contributor_load_failed",
52 name=getattr(contributor_entry_point, "name", "<unknown>"),
53 error=str(exc),
54 )
55 continue
57 contributors.append(contributor)
59 return contributors
62__all__ = ["ENTRY_POINT_GROUP", "load_web_contributors"]