예제 #1
0
 def init_alchemy(self, alchemy_cfg: Dict[str, Any],
                  tables: Set[type]) -> None:
     """Create and initialize the :class:`Alchemy` with the required tables, and find the link between the master
     table and the identity table."""
     self.alchemy = ra.Alchemy(alchemy_cfg["database_url"], tables)
     self.master_table = self.alchemy.get(self._master_table)
     self.identity_table = self.alchemy.get(self._identity_table)
     # This is fine, as Pycharm doesn't know that identity_table is a class and not an object
     # noinspection PyArgumentList
     self.identity_column = self.identity_table.__getattribute__(
         self.identity_table, self._identity_column)
예제 #2
0
파일: serf.py 프로젝트: fakegit/royalnet
 def init_alchemy(self, alchemy_cfg: Dict[str, Any],
                  tables: Set[type]) -> None:
     """Create and initialize the :class:`Alchemy` with the required tables, and find the link between the master
     table and the identity table."""
     self.alchemy = ra.Alchemy(alchemy_cfg["database_url"], tables)
예제 #3
0
    def __init__(self, alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any],
                 packs_cfg: Dict[str, Any], constellation_cfg: Dict[str, Any],
                 logging_cfg: Dict[str, Any]):
        # Import packs
        pack_names = packs_cfg["active"]
        packs = {}
        for pack_name in pack_names:
            log.debug(f"Importing pack: {pack_name}")
            try:
                packs[pack_name] = {
                    "commands":
                    importlib.import_module(f"{pack_name}.commands"),
                    "events": importlib.import_module(f"{pack_name}.events"),
                    "stars": importlib.import_module(f"{pack_name}.stars"),
                    "tables": importlib.import_module(f"{pack_name}.tables"),
                }
            except ImportError as e:
                log.error(f"Error during the import of {pack_name}: {e}")
        log.info(f"Packs: {len(packs)} imported")

        self.alchemy = None
        """The :class:`~ra.Alchemy` of this Constellation."""

        # Alchemy
        if ra.Alchemy is None or alchemy_cfg is None:
            log.info("Alchemy: not installed")
        elif not alchemy_cfg["enabled"]:
            log.info("Alchemy: disabled")
        else:
            # Find all tables
            tables = set()
            for pack in packs.values():
                try:
                    # noinspection PyUnresolvedReferences
                    tables = tables.union(pack["tables"].available_tables)
                except AttributeError:
                    log.warning(
                        f"Pack `{pack}` does not have the `available_tables` attribute."
                    )
                    continue
            # Create the Alchemy
            self.alchemy = ra.Alchemy(alchemy_cfg["database_url"], tables)
            log.info(f"Alchemy: {self.alchemy}")

        # Logging
        self._logging_cfg: Dict[str, Any] = logging_cfg
        """The logging config for the :class:`Constellation` is stored to initialize the logger when the first page is
        requested, as disabling the :mod:`uvicorn` logging also disables all logging in the process in general."""

        # Herald
        self.herald: Optional[rh.Link] = None
        """The :class:`Link` object connecting the :class:`Constellation` to the rest of the herald network.
        As is the case with the logging module, it will be started on the first request received by the 
        :class:`Constellation`, as the event loop won't be available before that."""

        self._herald_cfg: Dict[str, Any] = herald_cfg
        """The herald config for the :class:`Constellation` is stored to initialize the :class:`rh.Herald` later."""

        self.herald_task: Optional[aio.Task] = None
        """A reference to the :class:`aio.Task` that runs the :class:`rh.Link`."""

        self.events: Dict[str, rc.HeraldEvent] = {}
        """A dictionary containing all :class:`~rc.Event` that can be handled by this :class:`Constellation`."""

        self.starlette = starlette.applications.Starlette(debug=__debug__)
        """The :class:`~starlette.Starlette` app."""

        self.stars: List[PageStar] = []
        """A list of all the :class:`PageStar` registered to this :class:`Constellation`."""

        # Register Events
        for pack_name in packs:
            pack = packs[pack_name]
            pack_cfg = packs_cfg.get(pack_name, {})
            try:
                # noinspection PyUnresolvedReferences
                events = pack["events"].available_events
            except AttributeError:
                log.warning(
                    f"Pack `{pack}` does not have the `available_events` attribute."
                )
            else:
                self.register_events(events, pack_cfg)
        log.info(f"Events: {len(self.events)} events")

        if rh.Link is None:
            log.info("Herald: not installed")
        elif not herald_cfg["enabled"]:
            log.info("Herald: disabled")
        else:
            log.info(f"Herald: will be enabled on first request")

        # Register PageStars and ExceptionStars
        for pack_name in packs:
            pack = packs[pack_name]
            pack_cfg = packs_cfg.get(pack_name, {})
            try:
                # noinspection PyUnresolvedReferences
                page_stars = pack["stars"].available_page_stars
            except AttributeError:
                log.warning(
                    f"Pack `{pack}` does not have the `available_page_stars` attribute."
                )
            else:
                self.register_page_stars(page_stars, pack_cfg)
        log.info(f"PageStars: {len(self.starlette.routes)} stars")

        self.running: bool = False
        """Is the :class:`Constellation` server currently running?"""

        self.address: str = constellation_cfg["address"]
        """The address that the :class:`Constellation` will bind to when run."""

        self.port: int = constellation_cfg["port"]
        """The port on which the :class:`Constellation` will listen for connection on."""

        self.loop: Optional[aio.AbstractEventLoop] = None
        """The event loop of the :class:`Constellation`. 
예제 #4
0
    def __init__(self,
                 alchemy_cfg: Dict[str, Any],
                 herald_cfg: Dict[str, Any],
                 packs_cfg: Dict[str, Any],
                 constellation_cfg: Dict[str, Any],
                 **_):
        if Starlette is None:
            raise ImportError("`constellation` extra is not installed")

        # Import packs
        pack_names = packs_cfg["active"]
        packs = {}
        for pack_name in pack_names:
            log.debug(f"Importing pack: {pack_name}")
            try:
                packs[pack_name] = importlib.import_module(pack_name)
            except ImportError as e:
                log.error(f"Error during the import of {pack_name}: {e}")
        log.info(f"Packs: {len(packs)} imported")

        self.alchemy = None
        """The :class:`~ra.Alchemy` of this Constellation."""

        # Alchemy
        if ra.Alchemy is None:
            log.info("Alchemy: not installed")
        elif not alchemy_cfg["enabled"]:
            log.info("Alchemy: disabled")
        else:
            # Find all tables
            tables = set()
            for pack in packs.values():
                try:
                    tables = tables.union(pack.available_tables)
                except AttributeError:
                    log.warning(f"Pack `{pack}` does not have the `available_tables` attribute.")
                    continue
            # Create the Alchemy
            self.alchemy = ra.Alchemy(alchemy_cfg["database_url"], tables)
            log.info(f"Alchemy: {self.alchemy}")

        # Herald
        self.herald: Optional[rh.Link] = None
        """The :class:`Link` object connecting the :class:`Constellation` to the rest of the herald network."""

        self.herald_task: Optional[aio.Task] = None
        """A reference to the :class:`aio.Task` that runs the :class:`rh.Link`."""

        self.Interface: Type[rc.CommandInterface] = self.interface_factory()
        """The :class:`~rc.CommandInterface` class of this :class:`Constellation`."""

        self.events: Dict[str, rc.Event] = {}
        """A dictionary containing all :class:`~rc.Event` that can be handled by this :class:`Constellation`."""

        self.starlette = Starlette(debug=__debug__)
        """The :class:`~starlette.Starlette` app."""

        # Register Events
        for pack_name in packs:
            pack = packs[pack_name]
            pack_cfg = packs_cfg.get(pack_name, {})
            try:
                events = pack.available_events
            except AttributeError:
                log.warning(f"Pack `{pack}` does not have the `available_events` attribute.")
            else:
                self.register_events(events, pack_cfg)
        log.info(f"Events: {len(self.events)} events")

        if rh.Link is None:
            log.info("Herald: not installed")
        elif not herald_cfg["enabled"]:
            log.info("Herald: disabled")
        else:
            self.init_herald(herald_cfg)
            log.info(f"Herald: enabled")

        # Register PageStars and ExceptionStars
        for pack_name in packs:
            pack = packs[pack_name]
            pack_cfg = packs_cfg.get(pack_name, {})
            try:
                page_stars = pack.available_page_stars
            except AttributeError:
                log.warning(f"Pack `{pack}` does not have the `available_page_stars` attribute.")
            else:
                self.register_page_stars(page_stars, pack_cfg)
            try:
                exc_stars = pack.available_exception_stars
            except AttributeError:
                log.warning(f"Pack `{pack}` does not have the `available_exception_stars` attribute.")
            else:
                self.register_exc_stars(exc_stars, pack_cfg)
        log.info(f"PageStars: {len(self.starlette.routes)} stars")
        log.info(f"ExceptionStars: {len(self.starlette.exception_handlers)} stars")

        self.running: bool = False
        """Is the :class:`Constellation` server currently running?"""

        self.address: str = constellation_cfg["address"]
        """The address that the :class:`Constellation` will bind to when run."""

        self.port: int = constellation_cfg["port"]
        """The port on which the :class:`Constellation` will listen for connection on."""