{"id":1124,"date":"2021-07-12T09:44:29","date_gmt":"2021-07-12T09:44:29","guid":{"rendered":"https:\/\/www.bearloga.space\/?page_id=1124"},"modified":"2021-07-12T09:44:30","modified_gmt":"2021-07-12T09:44:30","slug":"futbolnyj-telegram-bot-na-python-3-4-poluchenie-vneshnih-dannyh","status":"publish","type":"page","link":"https:\/\/www.bearloga.space\/uk\/futbolnyj-telegram-bot-na-python-3-4-poluchenie-vneshnih-dannyh\/","title":{"rendered":"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (3\/4): \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u0412 \u0442\u0440\u0435\u0442\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430 \u043d\u0430 python, \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c API. \u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u0430\u0442\u0447\u0435\u0439, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u043b\u043d\u044b\u0439&nbsp;<a href=\"https:\/\/gitlab.com\/PythonRu\/fonlinebot\/-\/tree\/master\/third_step\" target=\"_blank\" rel=\"noreferrer noopener\">\u043a\u043e\u0434 \u0431\u043e\u0442\u0430 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u043a\u0430 \u043d\u0430 gitlab<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-api\">\u0412\u044b\u0431\u043e\u0440 API \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043c\u0430\u0442\u0447\u0435\u0439<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u041e\u0431\u044b\u0447\u043d\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e&nbsp;<a href=\"https:\/\/rapidapi.com\/marketplace\" target=\"_blank\" rel=\"noreferrer noopener\">Rapid API<\/a>&nbsp;\u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041f\u043e\u0434 \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442&nbsp;<a href=\"https:\/\/rapidapi.com\/sportmonks-data\/api\/football-pro\/endpoints\" target=\"_blank\" rel=\"noreferrer noopener\">Football Pro<\/a>. \u041e\u043d\u0438 \u0434\u0430\u044e\u0442 100 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0434\u0435\u043d\u044c, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0437\u0430 \u0440\u0430\u0437.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c \u043d\u0430 Rapid Api, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043e\u0444\u043e\u0440\u043c\u0438\u0442\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 (\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439) \u043f\u043b\u0430\u043d. \u0421\u0435\u0440\u0432\u0438\u0441 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439, \u043d\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0440\u0442\u0430.<video controls=\"\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/cPyKSrGo8G.mp4\"><\/video><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u0437\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 100 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0443\u0442\u043a\u0438. \u041f\u0440\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u043b\u0438\u043c\u0438\u0442\u0430 \u0441 \u0432\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438. \u0425\u043e\u0442\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043b\u0438\u043c\u0438\u0442\u0430, \u044f \u043d\u0435 \u043d\u0435\u0441\u0443 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-api-1\">\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041a\u043b\u044e\u0447 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 \u00abEndpoints\u00bb \u0432\u043d\u0438\u0437\u0443 \u0432 \u043f\u043e\u043b\u0435 \u00abX-RapidAPI-Key\u00bb. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443 \u043c\u0435\u043d\u044f. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/config.py\n# ...\nSOCCER_API_URL = \"https:\/\/football-pro.p.rapidapi.com\/api\/v2.0\/livescores\"\nSOCCER_API_HEADERS = {\n    'x-rapidapi-key': \"\u0432\u0430\u0448 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447\",\n    'x-rapidapi-host': \"football-pro.p.rapidapi.com\"\n}\nSOCCER_API_PARAMS = {\n    \"tz\": \"Europe\/Moscow\",\n    \"include\": \"localTeam,visitorTeam\"\n}\n# ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u044d\u0442\u043e\u043c \u0436\u0435 \u0444\u0430\u0439\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0438\u0433. \u042f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 (Id\u00a0<a href=\"https:\/\/sportmonks.com\/products\/soccer\/coverage\" target=\"_blank\" rel=\"noreferrer noopener\">\u0437\u0434\u0435\u0441\u044c<\/a>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/config.py\n# ...\nBOT_LEAGUES = {\n    \"82\": \"\u041d\u0435\u043c\u0435\u0446\u043a\u0430\u044f \u0411\u0443\u043d\u0434\u0435\u0441\u043b\u0438\u0433\u0430\",\n    \"384\": \"\u0418\u0442\u0430\u043b\u044c\u044f\u043d\u0441\u043a\u0430\u044f \u0421\u0435\u0440\u0438\u044f \u0410\",\n    \"564\": \"\u0418\u0441\u043f\u0430\u043d\u0441\u043a\u0430\u044f \u041b\u0430 \u041b\u0438\u0433\u0430\",\n    \"462\": \"\u041f\u043e\u0440\u0442\u0443\u0433\u0430\u043b\u044c\u0441\u043a\u0430\u044f \u041f\u0440\u0438\u043c\u0435\u0439\u0440\u0430 \u041b\u0438\u0433\u0430\",\n    \"72\": \"\u0427\u0435\u043c\u043f\u0438\u043e\u043d\u0430\u0442 \u041d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u043e\u0432\",\n    \"2\": \"\u041b\u0438\u0433\u0430 \u0427\u0435\u043c\u043f\u0438\u043e\u043d\u043e\u0432\",\n    \"5\": \"\u041b\u0438\u0433\u0430 \u0415\u0432\u0440\u043e\u043f\u044b\",\n    \"8\": \"\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0430\u044f \u041f\u0440\u0435\u043c\u044c\u0435\u0440-\u043b\u0438\u0433\u0430\",\n    \"301\": \"\u0424\u0440\u0430\u043d\u0446\u0443\u0437\u0441\u043a\u0430\u044f \u041b\u0438\u0433\u0430 1\",\n    \"486\": \"\u0420\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u0430\u044f \u041f\u0440\u0435\u043c\u044c\u0435\u0440-\u043b\u0438\u0433\u0430\"\n}\n# \u0424\u043b\u0430\u0433\u0438 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, emoji-\u043a\u043e\u0434\nBOT_LEAGUE_FLAGS = {\n    \"82\": \":Germany:\",\n    \"384\": \":Italy:\",\n    \"564\": \":Spain:\",\n    \"462\": \":Portugal:\",\n    \"72\": \":Netherlands:\",\n    \"2\": \":European_Union:\",\n    \"5\": \":trophy:\",\n    \"8\": \":England:\",\n    \"301\": \":France:\",\n    \"486\": \":Russia:\"\n}\n# ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412\u043c\u0435\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 1,2,3 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 id \u043b\u0438\u0433. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u044d\u0442\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0438\u0433\u0438. \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/obnovlenie-nastroek-dlya-api-1.png\" alt=\"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (3\/4): \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\" class=\"wp-image-4704\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u041b\u0438\u0433\u043e\u0439 \u0427\u0435\u043c\u043f\u0438\u043e\u043d\u043e\u0432.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-api-2\">\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u044f \u0437\u0430\u043b\u043e\u0436\u0438\u043b \u0431\u0443\u0434\u0443\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e \u0442\u0440\u0435\u043c \u043b\u0438\u0433\u0430\u043c \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u043b\u044e\u0447\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u043e 10 \u043b\u0438\u0433 \u0438 \u043d\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u043e \u0442\u0440\u0435\u043c \u043b\u0438\u0433\u0430\u043c \u0438\u043b\u0438 \u0432\u0441\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u043b\u0443\u0447\u0448\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u042d\u0442\u043e \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u043a\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0412\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0435 \u00abEndpoints\u00bb \u0441\u043b\u0435\u0432\u0430 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u00abFixtures of Today\u00bb \u0438 \u043d\u0430\u0436\u043c\u0435\u043c \u00abTest Endpoint\u00bb. \u041e\u0442\u0432\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u0435.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/dannye-v-otvete-1024x318.png\" alt=\"\u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435\" class=\"wp-image-4710\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412\u043e\u0442 \u044d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0430\u0442\u0447\u0430:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  ...\n  \"league_id\":998\n  ...\n  \"scores\":{\n    ...\n    \"ht_score\":\"0-0\"\n    \"ft_score\":\"1-1\"\n    ...\n  }\n  \"time\":{\n    \"status\":\"FT\"\n    \"starting_at\":{\n      \"time\":\"08:00:00\"\n      ...\n    }\n    \"minute\":90\n    ...\n    \"added_time\":NULL\n    ...\n  }\n  ...\n  \"localTeam\":{\n    \"data\":{\n    ...\n    \"name\":\"Hadiya Hosaena\"\n    ...\n    }\n  }\n  \"visitorTeam\":{\n    \"data\":{\n    ...\n    \"name\":\"Kedus Giorgis\"\n    ...\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c&nbsp;<a href=\"https:\/\/pythonru.com\/biblioteki\/kratkoe-rukovodstvo-po-biblioteke-python-requests\" target=\"_blank\" rel=\"noopener\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 requests<\/a>:&nbsp;<code>pip install requests==2.25.1<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a API. \u0418\u043d\u043e\u0433\u0434\u0430 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c. \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u043b\u043e\u0433\u0438 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0438 \u0432\u0435\u0440\u043d\u0435\u043c \u0435\u0435.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TODO \u0434\u043b\u044f \u0432\u0430\u0441. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0430\u0434\u043c\u0438\u043d\u0443, \u0435\u0441\u043b\u0438\u00a0<code>fetch_results<\/code>\u00a0\u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0441 \u043a\u043b\u044e\u0447\u043e\u043c\u00a0<code>\"error\"<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\nimport requests\nimport logging\n\nfrom config import BOT_LEAGUES, BOT_LEAGUE_FLAGS, MINUTE, \\\n                   SOCCER_API_URL, SOCCER_API_HEADERS, SOCCER_API_PARAMS\n# ...\n\ndef limit_control(headers):\n    \"\"\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0433\u043e \u043b\u0438\u043c\u0438\u0442\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432\"\"\"\n    if headers.get(\"x-ratelimit-requests-remaining\") is None:\n        logging.error(f\"Invalid headers response {headers}\")\n\n    if int(headers&#91;'x-ratelimit-requests-remaining']) &lt;= 5:\n        cache.setex(\n            \"limit_control\",\n            int(headers&#91;'x-ratelimit-requests-reset']),\n            msg.limit_control\n        )\n\n\ndef fetch_results() -&gt; dict:\n    SOCCER_API_PARAMS&#91;'leagues'] = \",\".join(BOT_LEAGUES.keys())\n    try:\n        resp = requests.get(SOCCER_API_URL,\n                            headers=SOCCER_API_HEADERS,\n                            params=SOCCER_API_PARAMS)\n    except requests.ConnectionError:\n        logging.error(\"ConnectionError\")\n        return {\"error\": \"ConnectionError\"}\n\n    limit_control(resp.headers)\n    if resp.status_code == 200:\n        return resp.json()\n    else:\n        logging.warning(f\"Data retrieval error &#91;{resp.status_code}]. Headers: {resp.headers} \")\n        return {\"error\": resp.status_code}\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e&nbsp;<code>limit_control<\/code>. \u041a\u043e\u0433\u0434\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u044c\u0448\u0435 6\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u0435\u0448 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c. \u0422\u0435\u043f\u0435\u0440\u044c \u0431\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u044d\u0442\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043a\u0435\u0448\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u0432\u00a0<code>generate_results_answer<\/code>. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0435\u0441\u0442\u044c, \u043c\u044b \u0432\u0435\u0440\u043d\u0435\u043c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n#...\n\nasync def generate_results_answer(ids: list) -&gt; str:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434a\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043c\u0430\u0442\u0447\u0435\u0439\"\"\"\n    limit = cache.get(\"limit_control\")\n    if limit is not None:\n        return limit\n\n    results = await get_last_results(ids)\n    if results == &#91;&#91;]]*len(ids):\n        return msg.no_results\n    elif msg.fetch_error in results:\n        return msg.fetch_error\n    else:\n        text_results = results_to_text(results)\n        return msg.results.format(matches=text_results)\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u00abbot.py\u00bb \u0438 \u00abdialogs.py\u00bb.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n#...\n\n@dp.callback_query_handler(lambda c: c.data.startswith('update_results'))\nasync def update_results(callback_query: types.CallbackQuery):\n    \"\"\"\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\"\"\"\n    if cache.get(f\"last_update_{callback_query.from_user.id}\") is None:\n        user_leagues = callback_query.data.split(\"#\")&#91;1:]\n        answer = await s.generate_results_answer(user_leagues)\n        if answer == msg.limit_control:\n            return await callback_query.answer(answer, show_alert=True)\n        else:\n            cache.setex(f\"last_update_{callback_query.from_user.id}\", MINUTE, \"Updated\")\n            await bot.edit_message_text(\n                answer,\n                callback_query.from_user.id,\n                message_id=int(cache.get(f\"last_msg_{callback_query.from_user.id}\")),\n                reply_markup=s.results_kb(user_leagues)\n            )\n    # \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043c\u0438\u043d\u0443\u0442\u044b\n    await callback_query.answer(msg.cb_updated)\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u042f \u0434\u043e\u043f\u0438\u0441\u0430\u043b \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e 2 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438\u00a0<code>answer<\/code>. \u0415\u0441\u043b\u0438 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0441\u0442 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043b\u0438\u043c\u0438\u0442\u0430 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/dialogs.py\n#...\n\n    limit_control: str = \"\u041b\u0438\u043c\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043d. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044c \u0437\u0430\u0432\u0442\u0440\u0430.\"\n    fetch_error: str = \"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043f\u043e\u0437\u0436\u0435.\"\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u041c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u043c\u0438\u043d\u0443\u0442\u0443 \u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cache.setex(\"limit_control\", 60, msg.limit_control)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/limit-zaprosov-1.png\" alt=\"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (3\/4): \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\" class=\"wp-image-4707\"\/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0435 24 \u0447\u0430\u0441\u0430 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c \u0432 13:00, \u0437\u043d\u0430\u0447\u0438\u0442 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0442\u043a\u0430. \u0412 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u043e \u043a\u043b\u044e\u0447\u0443&nbsp;<code>x-ratelimit-requests-reset<\/code>&nbsp;\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445.<\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-api-3\">\u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 API \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442 \u043e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u0435\u0448.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TODO \u0434\u043b\u044f \u0432\u0430\u0441. \u041d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043c\u0430\u0442\u0447\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0432 8 \u0443\u0442\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0438 \u043f\u0435\u0440\u0432\u044b\u0439 \u043c\u0430\u0442\u0447 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0432 19.00. \u0414\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043c\u0430\u0442\u0447\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u0441\u044f, \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n#...\nasync def parse_matches() -&gt; dict:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e API\"\"\"\n    data = {}\n    matches = fetch_results()\n    if matches.get(\"error\", False):\n        return matches\n\n    for m in matches&#91;'data']:\n        if not data.get(str(m&#91;'league_id']), False):\n            data&#91;str(m&#91;'league_id'])] = &#91;m]\n        else:\n            data&#91;str(m&#91;'league_id'])].append(m)\n    return data\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u042d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u00a0<code>get_last_results<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u043a\u0435\u0448\u0435. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0443\u0434\u0430 \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n#...\nasync def save_results(matches: dict):\n    \"\"\"\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043c\u0430\u0442\u0447\u0435\u0439\"\"\"\n    for lg_id in BOT_LEAGUES.keys():\n        cache.jset(lg_id, matches.get(lg_id, &#91;]), MINUTE)\n\n\nasync def get_last_results(league_ids: list) -&gt; list:\n    last_results = &#91;cache.jget(lg_id) for lg_id in league_ids]\n    if None in last_results:\n        all_results = await parse_matches()\n        if all_results.get(\"error\", False):\n            return &#91;msg.fetch_error]\n        else:\n            await save_results(all_results)\n            last_results = &#91;all_results.get(lg_id, &#91;]) for lg_id in league_ids]\n    return last_results\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0415\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043b\u0438\u0433\u0435 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0438, \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a API \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 1 \u043c\u0438\u043d\u0443\u0442\u0443.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-\">\u0417\u0430\u043f\u0438\u0441\u044c \u043b\u043e\u0433\u043e\u0432 \u0432 \u0444\u0430\u0439\u043b<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0432\u0430\u0436\u043d\u044b\u0435 \u043b\u043e\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u0444\u043e\u0440\u043c\u0430\u0442 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0444\u0430\u0439\u043b.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/config.py\n#...\n\nformatter = '&#91;%(asctime)s] %(levelname)8s --- %(message)s (%(filename)s:%(lineno)s)'\nlogging.basicConfig(\n    # TODO \u0440\u0430\u0441\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435\n    # filename=f'bot-from-{datetime.datetime.now().date()}.log',\n    # filemode='w',\n    format=formatter,\n    datefmt='%Y-%m-%d %H:%M:%S',\n    # TODO logging.WARNING \n    level=logging.DEBUG\n)\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0440\u043e\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a. \u041f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u0440\u0435\u043c\u044f \u0438 \u043c\u0435\u0441\u0442\u043e \u043b\u043e\u0433\u0430:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;2021-02-05 11:38:29]     INFO --- Database connection established (database.py:38)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c. \u0423\u0440\u043e\u043a\u0438 \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u044b&nbsp;<a href=\"https:\/\/pythonru.com\/primery\/python-telegram-bot\" target=\"_blank\" rel=\"noopener\">\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0443<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--1\">\u041a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0425\u043e\u0440\u043e\u0448\u043e, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043b\u043e\u0432\u0430\u0440\u0435\u0439 \u0441 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0442\u0435\u043a\u0441\u0442 \u0444\u043e\u0440\u043c\u0430\u0442\u0430:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0430\u044f \u041f\u0440\u0435\u043c\u044c\u0435\u0440-\u043b\u0438\u0433\u0430\n\u041e\u043a\u043e\u043d\u0447\u0435\u043d \u0422\u043e\u0442\u0442\u0435\u043d\u0445\u044d\u043c 0:1 (0:1) \u0427\u0435\u043b\u0441\u0438<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0424\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u00a0<code>results_to_text<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n#...\ndef add_text_time(time: dict) -&gt; str:\n    \"\"\"\u041f\u043e\u0434\u0431\u043e\u0440 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043c\u0430\u0442\u0447\u0430\n    \u0412\u0441\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u044b \u0437\u0434\u0435\u0441\u044c:\n    https:&#47;&#47;sportmonks.com\/docs\/football\/2.0\/getting-started\/a\/response-codes\/85#definitions\n    \"\"\"\n    scheduled = &#91;\"NS\"]\n    ended = &#91;\"FT\", \"AET\", \"FT_PEN\"]\n    live = &#91;\"LIVE\", \"HT\", \"ET\", \"PEN_LIVE\"]\n\n    if time&#91;'status'] in scheduled and time&#91;'starting_at']&#91;'time'] is not None:\n        # \u043e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0441\u0435\u043a\u0443\u043d\u0434\u044b\n        return time&#91;'starting_at']&#91;'time']&#91;:-3]\n    elif time&#91;'status'] in ended:\n        return \"\u041e\u043a\u043e\u043d\u0447\u0435\u043d\"\n    elif time&#91;'status'] in live and time&#91;'minute'] is not None:\n        if time&#91;'extra_minute'] is not None:\n            return time&#91;'minute'] + time&#91;'extra_minute']\n        return time&#91;'minute']\n    else:\n        # \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443\n        return \"--:--\"\n\n\ndef results_to_text(matches: list) -&gt; str:\n    \"\"\"\n    \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043c\u0430\u0442\u0447\u0430\u043c\u0438\n    \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 list&#91;list&#91;dict]]]\n    \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442:\n    | \u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0430\u044f \u041f\u0440\u0435\u043c\u044c\u0435\u0440-\u043b\u0438\u0433\u0430           |\n    | \u041e\u043a\u043e\u043d\u0447\u0435\u043d \u0422\u043e\u0442\u0442\u0435\u043d\u0445\u044d\u043c 0:1 (0:1) \u0427\u0435\u043b\u0441\u0438 |\n    ...\n    \"\"\"\n\n    text = \"\"\n    for lg_matches in matches:\n        if not lg_matches:\n            continue\n\n        lg_flag = BOT_LEAGUE_FLAGS&#91;str(lg_matches&#91;0]&#91;'league_id'])]\n        lg_name = BOT_LEAGUES&#91;str(lg_matches&#91;0]&#91;'league_id'])]\n        text += f\"{emojize(lg_flag)} {lg_name}\\n\"\n        for m in lg_matches:\n            text += f\"{add_text_time(m&#91;'time']):&gt;7} \"\n            if m&#91;'localteam_id'] == m&#91;'winner_team_id']:\n                text += f\"*{m&#91;'localTeam']&#91;'data']&#91;'name']}* \"\n            else:\n                text += f\"{m&#91;'localTeam']&#91;'data']&#91;'name']} \"\n            if m&#91;'time']&#91;'minute'] is not None:\n                text += f\"{m&#91;'scores']&#91;'localteam_score']}-{m&#91;'scores']&#91;'visitorteam_score']} \"\n            else:\n                text += \"\u2014 \"\n            if m&#91;'scores']&#91;'ht_score'] is not None:\n                text += f\"({m&#91;'scores']&#91;'ht_score']}) \"\n            if m&#91;'visitorteam_id'] == m&#91;'winner_team_id']:\n                text += f\"*{m&#91;'visitorTeam']&#91;'data']&#91;'name']}*\\n\"\n            else:\n                text += f\"{m&#91;'visitorTeam']&#91;'data']&#91;'name']}\\n\"\n        text += \"\\n\"\n    return text\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0446\u0438\u043a\u043b\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043b\u0438\u0433\u0430\u043c \u0438 \u043c\u0430\u0442\u0447\u0430\u043c, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0432\u044b\u0432\u043e\u0434. \u041f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u00a0<code>parse_mode<\/code>\u00a0\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0436\u0438\u0440\u043d\u044b\u043c \u043a\u043e\u043c\u0430\u043d\u0434-\u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u0435\u0439.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n#...\nasync def get_results(message: types.Message):\n    #...\n        await message.answer(answer,\n                             reply_markup=s.results_kb(user_leagues),\n                             parse_mode=types.ParseMode.MARKDOWN)\n\n\n# ...\nasync def update_results(callback_query: types.CallbackQuery):\n    # ...\n            await bot.edit_message_text(\n                answer,\n                callback_query.from_user.id,\n                message_id=int(cache.get(f\"last_msg_{callback_query.from_user.id}\")),\n                parse_mode=types.ParseMode.MARKDOWN,\n                reply_markup=s.results_kb(user_leagues)\n            )\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u043e\u0442:<video controls=\"\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/dRnKBpVWLU.mp4\"><\/video><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TODO \u0434\u043b\u044f \u0432\u0430\u0441.<br>1. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u0434\u043b\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435&nbsp;<code>chat_action<\/code>. \u042d\u0442\u043e \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430.<br>2. \u041d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043e\u0448\u0438\u0431\u043a\u0435. \u041f\u0443\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0439.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u043f\u043e\u0439\u0434\u0435\u043c \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--2\">\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u043e\u0442\u0430<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0411\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c API \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043b\u0438\u043c\u0438\u0442\u0430.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/test.py\n#...\nimport requests\nimport config\n#...\nclass TestService(IsolatedAsyncioTestCase):\n    #...\n\n    def test_limit_control(self):\n        test_data = {'x-ratelimit-requests-reset': \"60\",\n                     'x-ratelimit-requests-remaining': \"0\"}\n        service.limit_control(test_data)\n        self.assertIsNotNone(cache.get(\"limit_control\"))\n\n\nclass TestAPI(unittest.TestCase):\n    def test_api_response(self):\n        result = service.fetch_results()\n        self.assertIsNotNone(result.get('data', None))\n\n    def test_api_headers(self):\n        config.SOCCER_API_PARAMS&#91;'leagues'] = \",\".join(config.BOT_LEAGUES.keys())\n        resp = requests.get(\n            config.SOCCER_API_URL,\n            headers=config.SOCCER_API_HEADERS,\n            params=config.SOCCER_API_PARAMS\n        )\n        self.assertIsNotNone(resp.headers.get('x-ratelimit-requests-reset', None))\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0411\u043e\u0442 \u0433\u043e\u0442\u043e\u0432! \u041a\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u043a\u0430 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412 \u0442\u0440\u0435\u0442\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430 \u043d\u0430 python, \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c API. \u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[79],"tags":[],"class_list":["post-1124","page","type-page","status-publish","hentry","category-futbolnyj-telegram-bot-na-python"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/pages\/1124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/comments?post=1124"}],"version-history":[{"count":0,"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/pages\/1124\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/media?parent=1124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/categories?post=1124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bearloga.space\/uk\/wp-json\/wp\/v2\/tags?post=1124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}