Beispiel #1
0
 def import_relative_to_app(self, attr: str) -> Any:
     """Import string like "module.Model", or "Model" to model class."""
     try:
         return symbol_by_name(attr)
     except ImportError as original_exc:
         if not self.app.conf.origin:
             raise
         root, _, _ = self.app.conf.origin.partition(':')
         try:
             return symbol_by_name(f'{root}.models.{attr}')
         except ImportError:
             try:
                 return symbol_by_name(f'{root}.{attr}')
             except ImportError:
                 raise original_exc from original_exc
Beispiel #2
0
 def apply(self, web: "Web") -> None:
     """Apply all blueprints."""
     if not self.applied:
         self.applied = True
         for prefix, blueprint in self._enabled:
             bp: BlueprintT = symbol_by_name(blueprint)
             self._apply_blueprint(web, prefix, bp)
Beispiel #3
0
 def tables(self) -> TableManagerT:
     """Map of available tables, and the table manager service."""
     TableManager = (self.conf.TableManager if self.finalized else
                     symbol_by_name('faust.tables:TableManager'))
     return TableManager(
         app=self,
         loop=self.loop,
         beacon=self.beacon,
     )
Beispiel #4
0
def find_app(
    app: str,
    *,
    symbol_by_name: Callable = symbol_by_name,
    imp: Callable = import_from_cwd,
    attr_name: str = "app",
) -> AppT:
    """Find app by string like ``examples.simple``.

    Notes:
        This function uses ``import_from_cwd`` to temporarily
        add the current working directory to :envvar:`PYTHONPATH`,
        such that when importing the app it will search the current
        working directory last.

        You can think of it as temporarily
        running with the :envvar:`PYTHONPATH` set like this:

        .. sourcecode: console

            $ PYTHONPATH="${PYTHONPATH}:."

        You can disable this with the ``imp`` keyword argument,
        for example passing ``imp=importlib.import_module``.

    Examples:
        >>> # If providing the name of a module, it will attempt
        >>> # to find an attribute name (.app) in that module.
        >>> # Example below is the same as importing::
        >>> #    from examples.simple import app
        >>> find_app('examples.simple')

        >>> # If you want an attribute other than .app you can
        >>> # use : to separate module and attribute.
        >>> # Examples below is the same as importing::
        >>> #     from examples.simple import my_app
        >>> find_app('examples.simple:my_app')

        >>> # You can also use period for the module/attribute separator
        >>> find_app('examples.simple.my_app')
    """
    try:
        # Try to import name' as is.
        val = symbol_by_name(app, imp=imp)
    except AttributeError:
        # last part (of "pkg.x") was not an attribute,
        # but a module instead: use imp to import_module.
        val = imp(app)
    if isinstance(val, ModuleType) and ":" not in app:
        # if we found a module, try to get .app attribute
        found = getattr(val, attr_name)
        if isinstance(found, ModuleType):
            # proj.app:x where x is a module
            raise AttributeError(f"Looks like module, not app: -A {app}")
        val = found
    return prepare_app(val, app)
Beispiel #5
0
 def test_constructor(self, app):
     w = Worker(app)
     assert w.app is app
     assert w.sensors == set()
     assert w.workdir == Path.cwd()
     assert w.Website == symbol_by_name(WEBSITE_CLS)
     assert w.web_port is None
     assert w.web_bind is None
     assert w.web_host == socket.gethostname()
     assert isinstance(w.spinner, terminal.Spinner)
Beispiel #6
0
 def _inner(fun: AgentFun) -> AgentT:
     Agent = (self.conf.Agent
              if self.finalized else symbol_by_name('faust:Agent'))
     agent = Agent(fun,
                   name=name,
                   app=self,
                   channel=channel,
                   concurrency=concurrency,
                   supervisor_strategy=supervisor_strategy,
                   sink=sink,
                   isolated_partitions=isolated_partitions,
                   on_error=self._on_agent_error,
                   help=fun.__doc__,
                   **kwargs)
     self.agents[agent.name] = agent
     venusian.attach(agent, category=SCAN_AGENT)
     return agent
Beispiel #7
0
    def topic(self,
              *topics: str,
              pattern: Union[str, Pattern] = None,
              key_type: ModelArg = None,
              value_type: ModelArg = None,
              key_serializer: CodecArg = None,
              value_serializer: CodecArg = None,
              partitions: int = None,
              retention: Seconds = None,
              compacting: bool = None,
              deleting: bool = None,
              replicas: int = None,
              acks: bool = True,
              internal: bool = False,
              config: Mapping[str, Any] = None,
              maxsize: int = None,
              loop: asyncio.AbstractEventLoop = None) -> TopicT:
        """Create topic description.

        Topics are named channels (for example a Kafka topic),
        that exist on a server.  To make an ephemeral local communication
        channel use: :meth:`channel`.

        See Also:
            :class:`faust.topics.Topic`
        """
        Topic = (self.conf.Topic
                 if self.finalized else symbol_by_name('faust:Topic'))
        return Topic(
            self,
            topics=topics,
            pattern=pattern,
            key_type=key_type,
            value_type=value_type,
            key_serializer=key_serializer,
            value_serializer=value_serializer,
            partitions=partitions,
            retention=retention,
            compacting=compacting,
            deleting=deleting,
            replicas=replicas,
            acks=acks,
            internal=internal,
            config=config,
            loop=loop,
        )
Beispiel #8
0
 def __init__(self,
              app: AppT,
              *services: ServiceT,
              sensors: Iterable[SensorT] = None,
              debug: bool = DEBUG,
              quiet: bool = False,
              loglevel: Union[str, int] = None,
              logfile: Union[str, IO] = None,
              stdout: IO = sys.stdout,
              stderr: IO = sys.stderr,
              blocking_timeout: float = BLOCKING_TIMEOUT,
              workdir: Union[Path, str] = None,
              Website: SymbolArg[Type[_Website]] = WEBSITE_CLS,
              web_port: int = None,
              web_bind: str = None,
              web_host: str = None,
              console_port: int = 50101,
              loop: asyncio.AbstractEventLoop = None,
              **kwargs: Any) -> None:
     self.app = app
     self.sensors = set(sensors or [])
     self.workdir = Path(workdir or Path.cwd())
     self.Website = symbol_by_name(Website)
     self.web_port = web_port
     self.web_bind = web_bind
     self.web_host = web_host or socket.gethostname()
     super().__init__(
         *services,
         debug=debug,
         quiet=quiet,
         loglevel=loglevel,
         logfile=logfile,
         loghandlers=app.conf.loghandlers,
         stdout=stdout,
         stderr=stderr,
         blocking_timeout=blocking_timeout,
         console_port=console_port,
         redirect_stdouts=app.conf.worker_redirect_stdouts,
         redirect_stdouts_level=app.conf.worker_redirect_stdouts_level,
         loop=loop,
         **kwargs)
     self.spinner = terminal.Spinner(file=self.stdout)
Beispiel #9
0
    def Table(self,
              name: str,
              *,
              default: Callable[[], Any] = None,
              window: WindowT = None,
              partitions: int = None,
              help: str = None,
              **kwargs: Any) -> TableT:
        """Define new table.

        Arguments:
            name: Name used for table, note that two tables living in
                the same application cannot have the same name.

            default: A callable, or type that will return a default value
               for keys missing in this table.
            window: A windowing strategy to wrap this window in.

        Examples:
            >>> table = app.Table('user_to_amount', default=int)
            >>> table['George']
            0
            >>> table['Elaine'] += 1
            >>> table['Elaine'] += 1
            >>> table['Elaine']
            2
        """
        Table = (self.conf.Table
                 if self.finalized else symbol_by_name('faust:Table'))
        table = self.tables.add(
            Table(
                self,
                name=name,
                default=default,
                beacon=self.beacon,
                partitions=partitions,
                help=help,
                **kwargs))
        return table.using_window(window) if window else table
Beispiel #10
0
 def Stream(self, Stream: SymbolArg[Type[StreamT]]) -> None:
     self._Stream = symbol_by_name(Stream)
Beispiel #11
0
 def ConsumerScheduler(self,
                       value: SymbolArg[Type[SchedulingStrategyT]]) -> None:
     self._ConsumerScheduler = symbol_by_name(value)
Beispiel #12
0
 def Agent(self, Agent: SymbolArg[Type[AgentT]]) -> None:
     self._Agent = symbol_by_name(Agent)
Beispiel #13
0
 def agent_supervisor(self,
                      sup: SymbolArg[Type[SupervisorStrategyT]]) -> None:
     self._agent_supervisor = symbol_by_name(sup)
Beispiel #14
0
 def Topic(self, Topic: SymbolArg[Type[TopicT]]) -> None:
     self._Topic = symbol_by_name(Topic)
Beispiel #15
0
 def LeaderAssignor(self,
                    Assignor: SymbolArg[Type[LeaderAssignorT]]) -> None:
     self._LeaderAssignor = symbol_by_name(Assignor)
Beispiel #16
0
 def Worker(self, Worker: SymbolArg[Type[_WorkerT]]) -> None:
     self._Worker = symbol_by_name(Worker)
Beispiel #17
0
 def TableManager(self, Manager: SymbolArg[Type[TableManagerT]]) -> None:
     self._TableManager = symbol_by_name(Manager)
Beispiel #18
0
 def Table(self, Table: SymbolArg[Type[TableT]]) -> None:
     self._Table = symbol_by_name(Table)
Beispiel #19
0
 def settings(self) -> Settings:
     return symbol_by_name('django.conf:settings')
Beispiel #20
0
 def apps(self) -> Apps:
     return symbol_by_name('django.apps:apps')
Beispiel #21
0
 def SetTable(self, SetTable: SymbolArg[Type[TableT]]) -> None:
     self._SetTable = symbol_by_name(SetTable)
Beispiel #22
0
 def apply(self, web: 'Web') -> None:
     if not self.applied:
         self.applied = True
         for prefix, blueprint in self._enabled:
             self._apply_blueprint(web, prefix, symbol_by_name(blueprint))
Beispiel #23
0
 def Serializers(self, Serializers: SymbolArg[Type[RegistryT]]) -> None:
     self._Serializers = symbol_by_name(Serializers)
Beispiel #24
0
 def to_python(self, conf: _Settings, value: IT) -> OT:
     return cast(OT, symbol_by_name(value))
Beispiel #25
0
 def PartitionAssignor(
         self, Assignor: SymbolArg[Type[PartitionAssignorT]]) -> None:
     self._PartitionAssignor = symbol_by_name(Assignor)
Beispiel #26
0
W_ALREADY_CONFIGURED_KEY = '''\
Setting new value for configuration key {key!r} that was already used.

Reconfiguring late may mean parts of your program are still
using the old value of {old_value!r}.

Code such as:

app.conf.{key} = {value!r}

Should appear before calling app.topic/@app.agent/etc.
'''

# XXX mypy borks if we do `from faust import __version__`
faust_version: str = symbol_by_name('faust:__version__')

TIMEZONE = timezone.utc

#: Broker URL, used as default for :setting:`broker`.
BROKER_URL = 'kafka://localhost:9092'

#: Default transport used when no scheme specified.
DEFAULT_BROKER_SCHEME = 'kafka'

#: Table storage URL, used as default for :setting:`store`.
STORE_URL = 'memory://'

#: Cache storage URL, used as default for setting:`cache`.
CACHE_URL = 'memory://'
Beispiel #27
0
 def Router(self, Router: SymbolArg[Type[RouterT]]) -> None:
     self._Router = symbol_by_name(Router)
Beispiel #28
0
 def Monitor(self, Monitor: SymbolArg[Type[SensorT]]) -> None:
     self._Monitor = symbol_by_name(Monitor)
Beispiel #29
0
 def HttpClient(self, HttpClient: SymbolArg[Type[HttpClientT]]) -> None:
     self._HttpClient = symbol_by_name(HttpClient)
Beispiel #30
0
 def producer_partitioner(
         self, handler: Optional[SymbolArg[PartitionerT]]) -> None:
     self._producer_partitioner = symbol_by_name(handler)