แƒคแƒแƒœแƒฃแƒ แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜ แƒคแƒแƒฃแƒกแƒขแƒ–แƒ”, แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜

แƒคแƒแƒœแƒฃแƒ แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜ แƒคแƒแƒฃแƒกแƒขแƒ–แƒ”, แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜

แƒกแƒแƒ แƒฉแƒ”แƒ•แƒ˜

  1. แƒœแƒแƒฌแƒ˜แƒšแƒ˜ I: แƒจแƒ”แƒกแƒแƒ•แƒแƒšแƒ˜

  2. แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜

แƒ แƒแƒก แƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ— แƒแƒฅ?

แƒ›แƒแƒจ แƒแƒกแƒ”, แƒ›แƒ”แƒแƒ แƒ” แƒœแƒแƒฌแƒ˜แƒšแƒ˜. แƒ แƒแƒ’แƒแƒ แƒช แƒแƒ“แƒ แƒ” แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ”, แƒ›แƒแƒกแƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ— แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒก:

  1. แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒžแƒแƒขแƒแƒ แƒ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜ alphavantage-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก aiohttp-แƒ–แƒ” แƒฉแƒ•แƒ”แƒœแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ แƒ‘แƒแƒšแƒ แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒ—.

  2. แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒฅแƒ›แƒœแƒแƒ— แƒแƒ’แƒ”แƒœแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒแƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒก แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ“แƒ แƒ›แƒแƒ—แƒ–แƒ” แƒ›แƒ”แƒข แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒแƒก.

แƒ›แƒแƒ’แƒ แƒแƒ›, แƒ”แƒก แƒแƒ แƒ˜แƒก แƒ˜แƒก, แƒ แƒแƒกแƒแƒช แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ— แƒ—แƒแƒ•แƒแƒ“ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ“แƒ แƒคแƒแƒฃแƒกแƒขแƒ˜แƒก แƒ™แƒ•แƒšแƒ”แƒ•แƒ˜แƒก แƒ—แƒ•แƒแƒšแƒกแƒแƒ–แƒ แƒ˜แƒกแƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒกแƒฌแƒแƒ•แƒšแƒ˜แƒ— แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒœ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒก แƒ™แƒแƒคแƒ™แƒแƒ“แƒแƒœ, แƒแƒกแƒ”แƒ•แƒ” แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜ (click wrapper), แƒฉแƒ•แƒ”แƒœแƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ - แƒฎแƒ”แƒšแƒ˜แƒ— แƒฌแƒแƒกแƒ•แƒšแƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ˜แƒ› แƒ—แƒ”แƒ›แƒแƒ–แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒแƒ™แƒแƒœแƒขแƒ แƒแƒšแƒ”แƒ‘แƒก.

แƒกแƒแƒกแƒฌแƒแƒ•แƒšแƒ

AlphaVantage แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜

แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜, แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒžแƒแƒขแƒแƒ แƒ aiohttp แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜ alphavantage-แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

alphavantage.py

แƒกแƒžแƒแƒ˜แƒšแƒ”แƒ แƒ˜

import urllib.parse as urlparse
from io import StringIO
from typing import Any, Dict, List, Union

import aiohttp
import pandas as pd
import stringcase
from loguru import logger

from horton.config import API_ENDPOINT


class AlphaVantageClient:
    def __init__(
        self,
        session: aiohttp.ClientSession,
        api_key: str,
        api_endpoint: str = API_ENDPOINT,
    ):
        self._query_params = {"datatype": "json", "apikey": api_key}
        self._api_endpoint = api_endpoint
        self._session = session

    @logger.catch
    def _format_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
        formatted_data = {}

        for field, item in data.items():
            formatted_data[stringcase.snakecase(field)] = item

        return formatted_data

    @logger.catch
    async def _construct_query(
        self, function: str, to_json: bool = True, **kwargs
    ) -> Union[Dict[str, Any], str]:
        path = "query/"

        async with self._session.get(
            urlparse.urljoin(self._api_endpoint, path),
            params={"function": function, **kwargs, **self._query_params},
        ) as response:
            data = (await response.json()) if to_json else (await response.text())

            if to_json:
                data = self._format_fields(data)

        return data

    @logger.catch
    async def get_securities(self, state: str = "active") -> List[Dict[str, str]]:
        data = await self._construct_query("LISTING_STATUS", state=state, to_json=False)

        data = pd.read_csv(StringIO(data))

        securities = data.to_dict("records")

        for index, security in enumerate(securities):
            security = self._format_fields(security)
            security["_type"] = "physical"

            securities[index] = security

        return securities

    @logger.catch
    async def get_security_overview(self, symbol: str) -> Dict[str, str]:
        return await self._construct_query("OVERVIEW", symbol=symbol)

    @logger.catch
    async def get_historical_data(self, symbol: str) -> Dict[str, Any]:
        return await self._construct_query(
            "TIME_SERIES_DAILY_ADJUSTED", symbol=symbol, outputsize="full"
        )

    @logger.catch
    async def get_last_price_data(self, symbol: str) -> Dict[str, Any]:
        return await self._construct_query("GLOBAL_QUOTE", symbol=symbol)

    @logger.catch
    async def get_indicator_data(
        self, symbol: str, indicator: str, **indicator_options
    ) -> Dict[str, Any]:
        return await self._construct_query(
            indicator, symbol=symbol, **indicator_options
        )

แƒกแƒ˜แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒ”แƒจแƒ˜, แƒ›แƒ˜แƒกแƒ’แƒแƒœ แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒœแƒแƒ—แƒ”แƒšแƒ˜แƒ:

  1. AlphaVantage API แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ“ แƒ“แƒ แƒšแƒแƒ›แƒแƒ–แƒแƒ“ แƒแƒ แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒšแƒ˜, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ” แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒแƒ› แƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒœแƒ›แƒ”แƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒœแƒ construct_query แƒกแƒแƒ“แƒแƒช แƒ—แƒแƒ•แƒ˜แƒก แƒ›แƒฎแƒ แƒ˜แƒ• แƒแƒ แƒ˜แƒก http แƒ–แƒแƒ แƒ˜.

  2. แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒ˜แƒœแƒ“แƒแƒ แƒก แƒ›แƒแƒ•แƒ˜แƒขแƒแƒœ snake_case แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒฃแƒšแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

  3. แƒ™แƒแƒ แƒ’แƒแƒ“, logger.catch แƒ’แƒแƒคแƒแƒ แƒ›แƒ”แƒ‘แƒ แƒšแƒแƒ›แƒแƒ–แƒ˜ แƒ“แƒ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ™แƒ•แƒแƒšแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

PS แƒแƒ  แƒ“แƒแƒ’แƒแƒ•แƒ˜แƒฌแƒงแƒ“แƒ”แƒ— alphavantage แƒŸแƒ”แƒขแƒแƒœแƒ˜แƒก แƒแƒ“แƒ’แƒ˜แƒšแƒแƒ‘แƒ แƒ˜แƒ•แƒแƒ“ แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ config.yml-แƒ–แƒ” แƒแƒœ แƒ’แƒแƒ แƒ”แƒ›แƒแƒก แƒชแƒ•แƒšแƒแƒ“แƒ˜แƒก แƒ”แƒฅแƒกแƒžแƒแƒ แƒขแƒ˜ HORTON_SERVICE_APIKEY. แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒŸแƒ”แƒขแƒแƒœแƒก แƒแƒฅ.

CRUD แƒ™แƒšแƒแƒกแƒ˜

แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒ”แƒฅแƒœแƒ”แƒ‘แƒ แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒšแƒ”แƒฅแƒชแƒ˜แƒ แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ›แƒ”แƒขแƒ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒแƒœแƒแƒฎแƒแƒ“.

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ/security.py

แƒฉแƒ”แƒ›แƒ˜ แƒแƒ–แƒ แƒ˜แƒ—, แƒแƒฅ แƒแƒ แƒแƒคแƒ แƒ˜แƒก แƒแƒฎแƒกแƒœแƒ แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ แƒ“แƒ แƒ—แƒแƒ•แƒแƒ“ แƒกแƒแƒ‘แƒแƒ–แƒ แƒ™แƒšแƒแƒกแƒ˜ แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒ.

get_app ()

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒ›แƒแƒขแƒแƒ— แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒจแƒ”แƒกแƒแƒฅแƒ›แƒœแƒ”แƒšแƒแƒ“ app.py

แƒกแƒžแƒแƒ˜แƒšแƒ”แƒ แƒ˜

import faust

from horton.config import KAFKA_BROKERS


def get_app():
    return faust.App("horton", broker=KAFKA_BROKERS)

แƒฏแƒ”แƒ แƒฏแƒ”แƒ แƒแƒ‘แƒ˜แƒ— แƒ’แƒ•แƒ”แƒฅแƒœแƒ”แƒ‘แƒ แƒฃแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒกแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ, แƒชแƒแƒขแƒ แƒ›แƒแƒ’แƒ•แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒ— แƒ’แƒแƒ•แƒแƒคแƒแƒ แƒ—แƒแƒ•แƒ”แƒ‘แƒ—, แƒ—แƒฃแƒ›แƒชแƒ แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒแƒ  แƒ“แƒแƒ’แƒ”แƒšแƒแƒ“แƒแƒ—, แƒแƒฅ แƒชแƒœแƒแƒ‘แƒ”แƒ‘แƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ™แƒšแƒแƒกแƒจแƒ˜. แƒ›แƒ” แƒแƒกแƒ”แƒ•แƒ” แƒ’แƒ˜แƒ แƒฉแƒ”แƒ•แƒ—, แƒ’แƒแƒ“แƒแƒฎแƒ”แƒ“แƒแƒ— แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒก แƒ™แƒšแƒแƒกแƒก, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒก แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒก แƒฃแƒ›แƒ”แƒขแƒ”แƒกแƒแƒ‘แƒแƒ–แƒ”.

แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒœแƒแƒฌแƒ˜แƒšแƒ˜

แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ˜แƒก แƒจแƒ”แƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒแƒ’แƒ”แƒœแƒขแƒ˜

app = get_app()

collect_securities_topic = app.topic("collect_securities", internal=True)

@app.agent(collect_securities_topic)
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
	pass

แƒแƒกแƒ” แƒ แƒแƒ›, แƒฏแƒ”แƒ  แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒคแƒแƒฃแƒกแƒขแƒ˜แƒก แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒก - แƒ”แƒก แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒ. แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  แƒ•แƒแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒ— แƒ—แƒ”แƒ›แƒแƒก แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก... แƒแƒฅ แƒฃแƒœแƒ“แƒ แƒแƒฆแƒ˜แƒœแƒ˜แƒจแƒœแƒแƒก, แƒ แƒ แƒแƒ แƒ˜แƒก แƒ”แƒก, แƒ แƒ แƒแƒ แƒ˜แƒก แƒจแƒ˜แƒ“แƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜ แƒ“แƒ แƒ แƒแƒ’แƒแƒ  แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ”แƒก แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒแƒ“ แƒ˜แƒงแƒแƒก แƒ›แƒแƒฌแƒงแƒแƒ‘แƒ˜แƒšแƒ˜.

  1. แƒ—แƒ”แƒ›แƒ”แƒ‘แƒ˜ แƒ™แƒแƒคแƒ™แƒแƒจแƒ˜, แƒ—แƒฃ แƒ’แƒ•แƒ˜แƒœแƒ“แƒ แƒ•แƒ˜แƒชแƒแƒ“แƒ”แƒ— แƒ–แƒฃแƒกแƒขแƒ˜ แƒ’แƒแƒœแƒ›แƒแƒ แƒขแƒ”แƒ‘แƒ, แƒฏแƒแƒ‘แƒ˜แƒ แƒฌแƒแƒ•แƒ˜แƒ™แƒ˜แƒ—แƒฎแƒแƒ— แƒ’แƒแƒ›แƒแƒ แƒ—แƒฃแƒšแƒ˜แƒ. แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒ˜, แƒแƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒแƒ— แƒ™แƒแƒ›แƒžแƒ”แƒœแƒ“แƒ˜แƒฃแƒ›แƒ˜ แƒฐแƒแƒ‘แƒ แƒ”แƒ–แƒ” แƒ แƒฃแƒกแƒฃแƒšแƒแƒ“, แƒกแƒแƒ“แƒแƒช แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒแƒกแƒ”แƒ•แƒ” แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ–แƒฃแƒกแƒขแƒแƒ“ แƒแƒ แƒ˜แƒก แƒแƒกแƒแƒฎแƒฃแƒšแƒ˜ :)

  2. แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜ แƒจแƒ˜แƒ“แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ™แƒแƒ แƒ’แƒแƒ“ แƒแƒ แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ faust doc-แƒจแƒ˜, แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒ•แƒแƒซแƒšแƒ”แƒ•แƒก แƒ“แƒแƒ•แƒแƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒแƒ— แƒ—แƒ”แƒ›แƒ แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  แƒ™แƒแƒ“แƒจแƒ˜, แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ, แƒ”แƒก แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก แƒคแƒแƒฃแƒกแƒขแƒ˜แƒก แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒฃแƒš แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒก, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“: แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ, แƒจแƒ”แƒ™แƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒšแƒ˜แƒขแƒ˜แƒ™แƒ (แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒแƒ“ แƒฌแƒแƒจแƒšแƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒแƒงแƒ”แƒœแƒแƒ— แƒ™แƒแƒ›แƒžแƒแƒฅแƒขแƒฃแƒ แƒ˜), แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ แƒ—แƒ”แƒ›แƒแƒ–แƒ” (แƒฅแƒฃแƒšแƒแƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒแƒ—, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒ˜ แƒ’แƒšแƒแƒ‘แƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒ˜ faust).

  3. แƒ–แƒแƒ’แƒแƒ“แƒแƒ“, แƒแƒ’แƒ”แƒœแƒขแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒจแƒ”แƒฅแƒ›แƒœแƒแƒก แƒ›แƒแƒ แƒ—แƒฃแƒšแƒ˜ แƒ—แƒ”แƒ›แƒ แƒ’แƒšแƒแƒ‘แƒแƒšแƒฃแƒ แƒ˜ แƒฆแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒ—, แƒ—แƒฃแƒ›แƒชแƒ, แƒ›แƒ” แƒ›แƒ˜แƒงแƒ•แƒแƒ แƒก แƒงแƒ•แƒ”แƒšแƒแƒคแƒ แƒ˜แƒก แƒชแƒแƒšแƒกแƒแƒฎแƒแƒ“ แƒ“แƒ”แƒ™แƒšแƒแƒ แƒ˜แƒ แƒ”แƒ‘แƒ. แƒ’แƒแƒ แƒ“แƒ แƒแƒ›แƒ˜แƒกแƒ, แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒก แƒ แƒ”แƒ™แƒšแƒแƒ›แƒแƒจแƒ˜ แƒ—แƒ”แƒ›แƒ˜แƒก แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ—แƒ˜ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒก (แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ แƒแƒœ แƒจแƒ”แƒ™แƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒšแƒ˜แƒขแƒ˜แƒ™แƒ) แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ.

    แƒแƒ˜, แƒ แƒแƒ’แƒแƒ แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒแƒ“แƒ”แƒก แƒ—แƒ”แƒ›แƒ˜แƒก แƒฎแƒ”แƒšแƒ˜แƒ— แƒ’แƒแƒœแƒกแƒแƒ–แƒฆแƒ•แƒ แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”:

app = get_app()

@app.agent()
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
	pass

แƒแƒฎแƒšแƒ แƒ›แƒแƒ“แƒ˜แƒ— แƒแƒฆแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒ แƒแƒก แƒ’แƒแƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒก แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ˜ :)

app = get_app()

collect_securities_topic = app.topic("collect_securities", internal=True)

@app.agent(collect_securities_topic)
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
    async with aiohttp.ClientSession() as session:
        async for _ in stream:
            logger.info("Start collect securities")

            client = AlphaVantageClient(session, API_KEY)

            securities = await client.get_securities()

            for security in securities:
                await SecurityCRUD.update_one(
                    {"symbol": security["symbol"], "exchange": security["exchange"]}, security, upsert=True
                )

            yield True

แƒแƒกแƒ” แƒ แƒแƒ›, แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒก แƒ“แƒแƒกแƒแƒฌแƒงแƒ˜แƒกแƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ•แƒฎแƒกแƒœแƒ˜แƒ— aiohttp แƒกแƒ”แƒกแƒ˜แƒแƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—. แƒแƒ›แƒ แƒ˜แƒ’แƒแƒ“, แƒ›แƒฃแƒจแƒแƒ™แƒ˜แƒก แƒ“แƒแƒฌแƒงแƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ, แƒ›แƒแƒจแƒ˜แƒœแƒ•แƒ” แƒ’แƒแƒ˜แƒฎแƒกแƒœแƒ”แƒ‘แƒ แƒกแƒ”แƒกแƒ˜แƒ - แƒ”แƒ แƒ—แƒ˜, แƒ›แƒฃแƒจแƒแƒ™แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ“แƒ แƒแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ (แƒแƒœ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ”, แƒ—แƒฃ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ˜แƒ— แƒ™แƒแƒœแƒ™แƒฃแƒ แƒ”แƒœแƒชแƒ˜แƒ แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒ˜ แƒ”แƒ แƒ—แƒ”แƒฃแƒšแƒ˜แƒก แƒ›แƒฅแƒแƒœแƒ” แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒกแƒ’แƒแƒœ).

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ›แƒ˜แƒ•แƒงแƒ•แƒ”แƒ‘แƒ˜แƒ— แƒœแƒแƒ™แƒแƒ“แƒก (แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ— แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒแƒก _, แƒ•แƒ˜แƒœแƒแƒ˜แƒ“แƒแƒœ แƒฉแƒ•แƒ”แƒœ, แƒแƒ› แƒแƒ’แƒ”แƒœแƒขแƒจแƒ˜, แƒแƒ  แƒ’แƒ•แƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ”แƒ‘แƒก แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ—แƒ”แƒ›แƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜, แƒ—แƒฃ แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ”แƒœ แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒแƒคแƒกแƒ”แƒขแƒจแƒ˜, แƒฌแƒ˜แƒœแƒแƒแƒฆแƒ›แƒ“แƒ”แƒ’ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒชแƒ˜แƒ™แƒšแƒ˜ แƒ“แƒแƒ”แƒšแƒแƒ“แƒ”แƒ‘แƒ แƒ›แƒแƒ— แƒฉแƒแƒ›แƒแƒกแƒ•แƒšแƒแƒก. แƒ˜แƒกแƒ”, แƒฉแƒ•แƒ”แƒœแƒ˜ แƒชแƒ˜แƒ™แƒšแƒ˜แƒก แƒจแƒ˜แƒ’แƒœแƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ•แƒฌแƒ”แƒ แƒ— แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒแƒก, แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒแƒฅแƒขแƒ˜แƒฃแƒ แƒ˜ (get_securities แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒแƒ“ แƒแƒฅแƒขแƒ˜แƒฃแƒ แƒก, แƒ˜แƒฎแƒ˜แƒšแƒ”แƒ— แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ™แƒแƒ“แƒ˜) แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒแƒก แƒ“แƒ แƒ•แƒ˜แƒœแƒแƒฎแƒแƒ•แƒ— แƒ›แƒแƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜, แƒ•แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ— แƒแƒ แƒ˜แƒก แƒ—แƒฃ แƒแƒ แƒ แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ˜ แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒขแƒ˜แƒ™แƒ”แƒ แƒ˜แƒ— แƒ“แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒ’แƒแƒชแƒ•แƒšแƒ, แƒ—แƒฃ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก, แƒ›แƒแƒจแƒ˜แƒœ แƒ˜แƒก (แƒฅแƒแƒฆแƒแƒšแƒ“แƒ˜) แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒ’แƒแƒœแƒแƒฎแƒšแƒ“แƒ”แƒ‘แƒ.

แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒแƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ แƒจแƒ”แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ!

> docker-compose up -d
... ะ—ะฐะฟัƒัะบ ะบะพะฝั‚ะตะนะฝะตั€ะพะฒ ...
> faust -A horton.agents worker --without-web -l info

PS แƒ›แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜ แƒ•แƒ”แƒ‘ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒ”แƒ‘แƒจแƒ˜ แƒคแƒแƒฃแƒกแƒขแƒก แƒแƒ  แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ•, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒ˜ แƒ“แƒ แƒแƒจแƒ แƒ“แƒแƒ•แƒแƒงแƒ”แƒœแƒ”แƒ—.

แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒแƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ•แƒฃแƒ—แƒฎแƒแƒ แƒ˜แƒ— แƒคแƒแƒฃแƒกแƒขแƒก, แƒกแƒแƒ“ แƒฃแƒœแƒ“แƒ แƒ”แƒซแƒ˜แƒแƒก แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜ แƒ“แƒ แƒ แƒ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒแƒ™แƒ”แƒ—แƒแƒก แƒ›แƒแƒกแƒ—แƒแƒœ (แƒ’แƒแƒฃแƒจแƒ•แƒ แƒ›แƒฃแƒจแƒแƒ™แƒ˜) แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก แƒŸแƒฃแƒ แƒœแƒแƒšแƒ˜แƒก แƒ’แƒแƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ“แƒแƒœแƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ–แƒ”. แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ’แƒแƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒก:

แƒกแƒžแƒแƒ˜แƒšแƒ”แƒ แƒ˜

โ”Œฦ’aยตSโ€  v1.10.4โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ id          โ”‚ horton                                            โ”‚
โ”‚ transport   โ”‚ [URL('kafka://localhost:9092')]                   โ”‚
โ”‚ store       โ”‚ memory:                                           โ”‚
โ”‚ log         โ”‚ -stderr- (info)                                   โ”‚
โ”‚ pid         โ”‚ 1271262                                           โ”‚
โ”‚ hostname    โ”‚ host-name                                         โ”‚
โ”‚ platform    โ”‚ CPython 3.8.2 (Linux x86_64)                      โ”‚
โ”‚ drivers     โ”‚                                                   โ”‚
โ”‚   transport โ”‚ aiokafka=1.1.6                                    โ”‚
โ”‚   web       โ”‚ aiohttp=3.6.2                                     โ”‚
โ”‚ datadir     โ”‚ /path/to/project/horton-data                      โ”‚
โ”‚ appdir      โ”‚ /path/to/project/horton-data/v1                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
... ะปะพะณะธ, ะปะพะณะธ, ะปะพะณะธ ...

โ”ŒTopic Partition Setโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ topic                      โ”‚ partitions โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ collect_securities         โ”‚ {0-7}      โ”‚
โ”‚ horton-__assignor-__leader โ”‚ {0}        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

แฒชแƒแƒชแƒฎแƒแƒšแƒ˜แƒ!!!

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒฎแƒ”แƒ“แƒแƒ— แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒ›แƒžแƒšแƒ”แƒฅแƒขแƒก. แƒ แƒแƒ’แƒแƒ แƒช แƒ•แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒจแƒ”แƒ˜แƒฅแƒ›แƒœแƒ แƒ—แƒ”แƒ›แƒ แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒกแƒแƒฎแƒ”แƒšแƒ”แƒ— แƒ™แƒแƒ“แƒจแƒ˜, แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ (8, แƒแƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ—แƒ”แƒ›แƒ_แƒขแƒ˜แƒฎแƒ แƒ”แƒ‘แƒ˜ - แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜), แƒ แƒแƒ“แƒ’แƒแƒœ แƒฉแƒ•แƒ”แƒœ แƒแƒ  แƒ“แƒแƒ•แƒแƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒ”แƒ— แƒ˜แƒœแƒ“แƒ˜แƒ•แƒ˜แƒ“แƒฃแƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ—แƒ”แƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก (แƒขแƒ˜แƒฎแƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—). แƒ›แƒฃแƒจแƒแƒ™แƒจแƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒš แƒแƒ’แƒ”แƒœแƒขแƒก แƒ”แƒœแƒ˜แƒญแƒ”แƒ‘แƒ 8-แƒ•แƒ” แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ˜, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒก แƒ”แƒ แƒ—แƒแƒ“แƒ”แƒ แƒ—แƒ˜แƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ”แƒก แƒฃแƒคแƒ แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒฎแƒ˜แƒšแƒฃแƒšแƒ˜ แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜.

แƒแƒฎแƒšแƒ แƒฉแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ”แƒ— แƒกแƒฎแƒ•แƒ แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒ˜แƒก แƒคแƒแƒœแƒฏแƒแƒ แƒแƒจแƒ˜ แƒ“แƒ แƒ’แƒแƒ•แƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ— แƒชแƒแƒ แƒ˜แƒ”แƒšแƒ˜ แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ แƒฉแƒ•แƒ”แƒœแƒก แƒ—แƒ”แƒ›แƒแƒจแƒ˜:

> faust -A horton.agents send @collect_securities
{"topic": "collect_securities", "partition": 6, "topic_partition": ["collect_securities", 6], "offset": 0, "timestamp": ..., "timestamp_type": 0}

PS แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— @ แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ—, แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒ— แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒแƒก แƒ—แƒ”แƒ›แƒแƒ–แƒ” แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒ— "collect_securities".

แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ แƒ›แƒ”-6 แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒจแƒ˜ - แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— kafdrop-แƒ–แƒ” แƒ’แƒแƒ“แƒแƒกแƒ•แƒšแƒ˜แƒ— localhost:9000

แƒฉแƒ•แƒ”แƒœแƒก แƒ—แƒแƒœแƒแƒ›แƒจแƒ แƒแƒ›แƒ”แƒšแƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒ˜แƒก แƒคแƒแƒœแƒฏแƒแƒ แƒแƒจแƒ˜ แƒ’แƒแƒ“แƒแƒกแƒ•แƒšแƒ˜แƒกแƒแƒก แƒ“แƒแƒ•แƒ˜แƒœแƒแƒฎแƒแƒ•แƒ— แƒ‘แƒ”แƒ“แƒœแƒ˜แƒ”แƒ  แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒšแƒ˜แƒ loguru-แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—:

2020-09-23 00:26:37.304 | INFO     | horton.agents:collect_securities:40 - Start collect securities

แƒฉแƒ•แƒ”แƒœ แƒแƒกแƒ”แƒ•แƒ” แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒจแƒ”แƒ•แƒฎแƒ”แƒ“แƒแƒ— แƒ›แƒแƒœแƒ’แƒแƒก (Robo3T แƒแƒœ Studio3T-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—) แƒ“แƒ แƒ“แƒแƒ•แƒ˜แƒœแƒแƒฎแƒแƒ—, แƒ แƒแƒ› แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜ แƒแƒ แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜:

แƒ›แƒ” แƒแƒ  แƒ•แƒแƒ  แƒ›แƒ˜แƒšแƒ˜แƒแƒ แƒ“แƒ”แƒ แƒ˜ แƒ“แƒ แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ•แƒ™แƒ›แƒแƒงแƒแƒคแƒ˜แƒšแƒ“แƒ”แƒ‘แƒ˜แƒ— แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜แƒ—.

แƒคแƒแƒœแƒฃแƒ แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜ แƒคแƒแƒฃแƒกแƒขแƒ–แƒ”, แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜แƒคแƒแƒœแƒฃแƒ แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜ แƒคแƒแƒฃแƒกแƒขแƒ–แƒ”, แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜

แƒ‘แƒ”แƒ“แƒœแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ แƒ“แƒ แƒกแƒ˜แƒฎแƒแƒ แƒฃแƒšแƒ˜ - แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ›แƒ–แƒแƒ“แƒแƒ :)

แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ›แƒ–แƒแƒ“แƒแƒ, แƒ’แƒแƒฃแƒ›แƒแƒ แƒฏแƒแƒก แƒแƒฎแƒแƒš แƒแƒ’แƒ”แƒœแƒขแƒก!

แƒ“แƒ˜แƒแƒฎ, แƒ‘แƒแƒขแƒแƒœแƒ”แƒ‘แƒ, แƒฉแƒ•แƒ”แƒœ แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒ— แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒ–แƒ˜แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ 1/3 แƒ’แƒแƒ•แƒ˜แƒแƒ แƒ”แƒ—, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒ  แƒ˜แƒœแƒ”แƒ แƒ•แƒ˜แƒฃแƒšแƒแƒ—, แƒ แƒแƒ“แƒ’แƒแƒœ แƒแƒฎแƒšแƒ แƒฃแƒคแƒ แƒ แƒแƒ“แƒ•แƒ˜แƒšแƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ.

แƒแƒฎแƒšแƒ แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒแƒ’แƒ”แƒœแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒก แƒ›แƒ”แƒขแƒ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒแƒก แƒ“แƒ แƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒก แƒ›แƒแƒก แƒ™แƒแƒšแƒ”แƒฅแƒชแƒ˜แƒฃแƒ  แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒจแƒ˜:

collect_security_overview_topic = app.topic("collect_security_overview", internal=True)


@app.agent(collect_security_overview_topic)
async def collect_security_overview(
    stream: StreamT[?],
) -> AsyncIterable[bool]:
    async with aiohttp.ClientSession() as session:
        async for event in stream:
            ...

แƒ•แƒ˜แƒœแƒแƒ˜แƒ“แƒแƒœ แƒ”แƒก แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ“แƒแƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒก แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒแƒก แƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒฃแƒšแƒ˜ แƒฃแƒกแƒแƒคแƒ แƒ—แƒฎแƒแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘, แƒฉแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ›แƒ˜แƒ•แƒฃแƒ—แƒ˜แƒ—แƒแƒ— แƒแƒ› แƒฃแƒกแƒแƒคแƒ แƒ—แƒฎแƒแƒ”แƒ‘แƒ˜แƒก แƒขแƒ˜แƒ™แƒ”แƒ แƒ˜ (แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒ) แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒแƒจแƒ˜. แƒแƒ› แƒ›แƒ˜แƒ–แƒœแƒ˜แƒ— แƒคแƒแƒฃแƒกแƒขแƒจแƒ˜ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ”แƒ‘แƒ˜ โ€” แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒ”แƒœ แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒกแƒฅแƒ”แƒ›แƒแƒก แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒก แƒ—แƒ”แƒ›แƒแƒจแƒ˜.

แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ›แƒแƒ“แƒ˜แƒ— แƒฌแƒแƒ•แƒ˜แƒ“แƒ”แƒ— แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ”แƒ‘แƒ˜.py แƒ“แƒ แƒแƒฆแƒฌแƒ”แƒ แƒ”แƒ— แƒ แƒแƒ’แƒแƒ แƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ›แƒ”แƒกแƒ˜แƒฏแƒ˜ แƒแƒ› แƒ—แƒ”แƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก:

import faust


class CollectSecurityOverview(faust.Record):
    symbol: str
    exchange: str

แƒ แƒแƒ’แƒแƒ แƒช แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒšแƒ‘แƒแƒ— แƒ›แƒ˜แƒฎแƒ•แƒ“แƒ˜แƒ—, แƒคแƒแƒฃแƒกแƒขแƒ˜ แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก แƒžแƒ˜แƒ—แƒแƒœแƒ˜แƒก แƒขแƒ˜แƒžแƒ˜แƒก แƒแƒœแƒแƒขแƒแƒชแƒ˜แƒแƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒฅแƒ”แƒ›แƒ˜แƒก แƒแƒฆแƒกแƒแƒฌแƒ”แƒ แƒแƒ“, แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒช แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ›แƒ˜แƒœแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒแƒ แƒ˜แƒก 3.6.

แƒ“แƒแƒ•แƒฃแƒ‘แƒ แƒฃแƒœแƒ“แƒ”แƒ— แƒแƒ’แƒ”แƒœแƒขแƒก, แƒ“แƒแƒ•แƒแƒงแƒ”แƒœแƒแƒ— แƒขแƒ˜แƒžแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ“แƒแƒ•แƒแƒ›แƒแƒขแƒแƒ—:

collect_security_overview_topic = app.topic(
    "collect_security_overview", internal=True, value_type=CollectSecurityOverview
)


@app.agent(collect_security_overview_topic)
async def collect_security_overview(
    stream: StreamT[CollectSecurityOverview],
) -> AsyncIterable[bool]:
    async with aiohttp.ClientSession() as session:
        async for event in stream:
            logger.info(
                "Start collect security [{symbol}] overview", symbol=event.symbol
            )

            client = AlphaVantageClient(session, API_KEY)

            security_overview = await client.get_security_overview(event.symbol)

            await SecurityCRUD.update_one({"symbol": event.symbol, "exchange": event.exchange}, security_overview)

            yield True

แƒ แƒแƒ’แƒแƒ แƒช แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒ—แƒ”แƒ›แƒ˜แƒก แƒ˜แƒœแƒ˜แƒชแƒ˜แƒแƒšแƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒ”แƒ—แƒแƒ“แƒก แƒ’แƒแƒ“แƒแƒ•แƒชแƒ”แƒ›แƒ— แƒแƒฎแƒแƒš แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒก แƒกแƒฅแƒ”แƒ›แƒ˜แƒ— - value_type. แƒ’แƒแƒ แƒ“แƒ แƒแƒ›แƒ˜แƒกแƒ, แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ”แƒ แƒ—แƒ˜ แƒ“แƒ แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒกแƒฅแƒ”แƒ›แƒ˜แƒ— แƒ›แƒ˜แƒฐแƒงแƒ•แƒ”แƒ‘แƒ, แƒแƒกแƒ” แƒ แƒแƒ›, แƒ›แƒ” แƒ•แƒ”แƒ  แƒ•แƒฎแƒ”แƒ“แƒแƒ• แƒแƒ–แƒ แƒก แƒกแƒฎแƒ•แƒ แƒ แƒแƒ›แƒ”แƒ–แƒ” แƒคแƒ˜แƒฅแƒ แƒจแƒ˜.

แƒ˜แƒกแƒ”, แƒกแƒแƒ‘แƒแƒšแƒแƒ แƒจแƒ”แƒฎแƒ”แƒ‘แƒ แƒแƒ แƒ˜แƒก แƒ–แƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ แƒ›แƒ”แƒขแƒ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒแƒ’แƒ”แƒœแƒขแƒ—แƒแƒœ collect_securites-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก:

....
for security in securities:
    await SecurityCRUD.update_one({
            "symbol": security["symbol"],
            "exchange": security["exchange"]
        },
        security,
        upsert = True,
    )

    await collect_security_overview.cast(
        CollectSecurityOverview(symbol = security["symbol"], exchange = security["exchange"])
    )
....

แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ— แƒแƒ“แƒ แƒ” แƒ’แƒแƒ›แƒแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒฃแƒš แƒกแƒฅแƒ”แƒ›แƒแƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒ›แƒ” แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ” .cast แƒ›แƒ”แƒ—แƒแƒ“แƒ˜, แƒ แƒแƒ“แƒ’แƒแƒœ แƒแƒ  แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒแƒ’แƒ”แƒœแƒขแƒ˜แƒกแƒ’แƒแƒœ แƒจแƒ”แƒ“แƒ”แƒ’แƒก แƒ•แƒ”แƒšแƒแƒ“แƒแƒ—, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒฆแƒกแƒแƒœแƒ˜แƒจแƒœแƒแƒ•แƒ˜แƒ, แƒ แƒแƒ› แƒ’แƒ–แƒ”แƒ‘แƒ˜ แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ”แƒ— แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ แƒ—แƒ”แƒ›แƒแƒ–แƒ”:

  1. แƒ›แƒกแƒแƒฎแƒ˜แƒแƒ‘แƒ˜ - แƒแƒ  แƒ‘แƒšแƒแƒ™แƒแƒ•แƒก, แƒ แƒแƒ“แƒ’แƒแƒœ แƒจแƒ”แƒ“แƒ”แƒ’แƒก แƒแƒ  แƒ”แƒšแƒ˜แƒก. แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒ  แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜แƒก แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ แƒกแƒฎแƒ•แƒ แƒ—แƒ”แƒ›แƒแƒจแƒ˜ แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ—.

  2. แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ - แƒแƒ  แƒ‘แƒšแƒแƒ™แƒแƒ•แƒก, แƒ แƒแƒ“แƒ’แƒแƒœ แƒจแƒ”แƒ“แƒ”แƒ’แƒก แƒแƒ  แƒ”แƒšแƒ˜แƒก. แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒแƒ— แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ—แƒ”แƒ›แƒแƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒ“แƒแƒช แƒฌแƒแƒ•แƒ แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜.

  3. แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ - แƒ”แƒšแƒแƒ“แƒ”แƒ‘แƒ แƒจแƒ”แƒ“แƒ”แƒ’แƒก. แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒแƒ— แƒแƒ’แƒ”แƒœแƒขแƒ˜ แƒ—แƒ”แƒ›แƒแƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒ“แƒแƒช แƒฌแƒแƒ•แƒ แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜.

แƒแƒกแƒ” แƒ แƒแƒ›, แƒ”แƒก แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ“แƒฆแƒ”แƒ•แƒแƒœแƒ“แƒ”แƒšแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒ—!

แฒกแƒแƒแƒชแƒœแƒ”แƒ‘แƒ แƒ’แƒฃแƒœแƒ“แƒ˜

แƒ‘แƒแƒšแƒ, แƒ แƒ˜แƒกแƒ˜ แƒ“แƒแƒฌแƒ”แƒ แƒแƒกแƒแƒช แƒ“แƒแƒ•แƒžแƒ˜แƒ แƒ“แƒ˜ แƒแƒ› แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜, แƒแƒ แƒ˜แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜. แƒ แƒแƒ’แƒแƒ แƒช แƒฃแƒ™แƒ•แƒ” แƒแƒฆแƒ•แƒœแƒ˜แƒจแƒœแƒ”แƒ—, แƒคแƒแƒฃแƒกแƒขแƒ˜แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒแƒ แƒ˜แƒก แƒ“แƒแƒฌแƒ™แƒแƒžแƒฃแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒจแƒ”แƒ›แƒ. แƒกแƒ˜แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒ”แƒจแƒ˜, แƒคแƒแƒฃแƒกแƒขแƒ˜ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒแƒœแƒ˜แƒญแƒ”แƒ‘แƒก แƒฉแƒ•แƒ”แƒœแƒก แƒ›แƒแƒ แƒ’แƒ”แƒ‘แƒฃแƒš แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒแƒก แƒ—แƒแƒ•แƒ˜แƒก แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒก, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒ”แƒ‘แƒก -A แƒ™แƒšแƒแƒ•แƒ˜แƒจแƒก

แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช แƒ’แƒแƒ›แƒแƒชแƒฎแƒแƒ“แƒ“แƒ แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜.py แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ“แƒ”แƒ™แƒแƒ แƒแƒขแƒแƒ แƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ app.commandแƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒก แƒ“แƒแƒ แƒ”แƒ™แƒ•แƒ แƒ›แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒแƒ‘แƒ ัƒ แƒจแƒ”แƒแƒ’แƒ แƒแƒ•แƒแƒก_ แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜:

@app.command()
async def start_collect_securities():
    """Collect securities and overview."""

    await collect_securities.cast()

แƒแƒ›แƒ แƒ˜แƒ’แƒแƒ“, แƒ—แƒฃ แƒฉแƒ•แƒ”แƒœ แƒ›แƒแƒ•แƒฃแƒฌแƒแƒ“แƒ”แƒ‘แƒ— แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒ›แƒแƒœแƒแƒ—แƒ•แƒแƒšแƒก, แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒฎแƒแƒšแƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ›แƒแƒกแƒจแƒ˜:

> faust -A horton.agents --help

....
Commands:
  agents                    List agents.
  clean-versions            Delete old version directories.
  completion                Output shell completion to be evaluated by the...
  livecheck                 Manage LiveCheck instances.
  model                     Show model detail.
  models                    List all available models as a tabulated list.
  reset                     Delete local table state.
  send                      Send message to agent/topic.
  start-collect-securities  Collect securities and overview.
  tables                    List available tables.
  worker                    Start worker instance for given app.

แƒฉแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ˜แƒก, แƒ แƒแƒ’แƒแƒ แƒช แƒกแƒฎแƒ•แƒ”แƒ‘แƒ˜, แƒแƒกแƒ” แƒ แƒแƒ›, แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ— Faust Worker แƒ“แƒ แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒแƒ— แƒคแƒแƒกแƒ˜แƒแƒœแƒ˜ แƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ‘แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒ™แƒแƒšแƒ”แƒฅแƒชแƒ˜แƒ:

> faust -A horton.agents start-collect-securities

แƒ แƒ แƒ›แƒแƒฎแƒ“แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’?

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜, แƒ“แƒแƒ แƒฉแƒ”แƒœแƒ˜แƒšแƒ˜ แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒ— แƒกแƒแƒซแƒ˜แƒ แƒ™แƒ•แƒšแƒ˜แƒก แƒ›แƒ”แƒฅแƒแƒœแƒ˜แƒ–แƒ›แƒก แƒ•แƒแƒญแƒ แƒแƒ‘แƒ˜แƒก แƒ“แƒแƒฎแƒฃแƒ แƒ•แƒ˜แƒก แƒคแƒแƒกแƒ”แƒ‘แƒจแƒ˜ แƒ”แƒฅแƒกแƒขแƒ แƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒกแƒแƒซแƒ”แƒ‘แƒœแƒแƒ“ แƒฌแƒšแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ แƒ“แƒ แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ.

แƒ“แƒฆแƒ”แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒฃแƒš แƒ”แƒกแƒแƒ! แฒ›แƒแƒ“แƒšแƒแƒ‘แƒ แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก :)

แƒ™แƒแƒ“แƒ˜ แƒแƒ› แƒœแƒแƒฌแƒ˜แƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

แƒคแƒแƒœแƒฃแƒ แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜ แƒคแƒแƒฃแƒกแƒขแƒ–แƒ”, แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II: แƒแƒ’แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ’แƒฃแƒœแƒ“แƒ”แƒ‘แƒ˜

PS แƒ‘แƒแƒšแƒ แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜ แƒ›แƒ™แƒ˜แƒ—แƒฎแƒ”แƒก แƒคแƒแƒฃแƒกแƒขแƒ˜แƒกแƒ แƒ“แƒ แƒจแƒ”แƒ แƒฌแƒงแƒ›แƒ˜แƒก แƒ™แƒแƒคแƒ™แƒแƒ–แƒ” (แƒ แƒ แƒ—แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒแƒฅแƒ•แƒก แƒ™แƒแƒœแƒคแƒšแƒ”แƒœแƒขแƒก?). แƒ แƒแƒ’แƒแƒ แƒช แƒฉแƒแƒœแƒก, แƒ™แƒแƒœแƒคแƒšแƒฃแƒ”แƒœแƒขแƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒ—แƒ•แƒแƒšแƒกแƒแƒ–แƒ แƒ˜แƒกแƒ˜แƒ— แƒฃแƒคแƒ แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒแƒšแƒฃแƒ แƒ˜แƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒคแƒแƒฅแƒขแƒ˜แƒ, แƒ แƒแƒ› แƒคแƒแƒฃแƒกแƒขแƒก แƒแƒ  แƒแƒฅแƒ•แƒก แƒกแƒ แƒฃแƒšแƒ˜ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ แƒ™แƒแƒœแƒคแƒฃแƒ”แƒœแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก - แƒ”แƒก แƒ’แƒแƒ›แƒแƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ”แƒแƒ‘แƒก แƒ˜แƒฅแƒ˜แƒ“แƒแƒœ. แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒจแƒ”แƒ–แƒฆแƒฃแƒ“แƒ•แƒ”แƒ‘แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒจแƒ˜.

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ