Browse Source

Рефактор. Версия после тестирования.

master
Дмитрий 3 years ago
parent
commit
455e1f4155
  1. 6
      app_config.py
  2. 6
      config_object.py
  3. 71
      request_builder.py
  4. 20
      solution.py

6
app_config.py

@ -5,7 +5,6 @@ from os import path
class AppConfig: class AppConfig:
"""Класс для хранения настроек сервиса. """Класс для хранения настроек сервиса.
TODO: Дописать документацию!
""" """
def __init__(self, path_to_conf_file: str, section: str = "Main"): def __init__(self, path_to_conf_file: str, section: str = "Main"):
@ -25,7 +24,7 @@ class AppConfig:
""" """
cfg: configparser = configparser.ConfigParser() cfg = configparser.ConfigParser()
try: try:
cfg.read(path.abspath(path_to_conf_file)) cfg.read(path.abspath(path_to_conf_file))
@ -50,9 +49,6 @@ class AppConfig:
_path = path.abspath(self.path_for_config) _path = path.abspath(self.path_for_config)
return _path return _path
def _create_path(self) -> None:
pass
def __repr__(self): def __repr__(self):
return ( return (
f"template = {self.template}\n" f"template = {self.template}\n"

6
config_object.py

@ -1,14 +1,9 @@
from dataclasses import dataclass
import asyncio import asyncio
import os import os
import aiofiles import aiofiles
class ConfigObject: class ConfigObject:
host: str
conf_body: str
path: str
def __init__(self, host: str, conf_body: str, path: str): def __init__(self, host: str, conf_body: str, path: str):
self.host = host self.host = host
self.conf_body = conf_body.replace( self.conf_body = conf_body.replace(
@ -44,6 +39,7 @@ class ConfigFactory:
self.path = path_to_configs_dir self.path = path_to_configs_dir
def create(self, host: str) -> ConfigObject: def create(self, host: str) -> ConfigObject:
"""Конструирует `ConfigObject` используя только хост."""
return ConfigObject(host, self.templ, self.path) return ConfigObject(host, self.templ, self.path)
def __read_config_template_file(self, path_to_file: str) -> str: def __read_config_template_file(self, path_to_file: str) -> str:

71
request_builder.py

@ -1,15 +1,31 @@
"""Модлуль для конструирования и обработки запросов.""" """Модуль для конструирования и обработки запросов."""
from app_config import AppConfig
from aiohttp import ClientResponse
import asyncio import asyncio
from typing import Dict, List, NewType
import aiohttp import aiohttp
from aiohttp import ClientResponse
from aiohttp.client_exceptions import ClientConnectorError, ServerDisconnectedError
from loguru import logger
from app_config import AppConfig
class RequestBulder: class RequestBulder:
def __init__(self, cfg: AppConfig): """Конструктор запросов.
self.cfg = cfg
Attributes
----------
cfg : AppConfig
Объект с конфигом для приложения.
Methods
-------
send_request(url: str, json_body: dict)
Асинхронный метод для отправки запроса. Может принимать пустой json_body.
"""
def __init__(self, cfg: AppConfig) -> None:
"""Инициализация. Объект сесси `aiohttp.ClientSession`
создается здесь. """
self.cfg = cfg
_conn = aiohttp.TCPConnector(limit=cfg.requests_count) _conn = aiohttp.TCPConnector(limit=cfg.requests_count)
self.session = aiohttp.ClientSession(connector=_conn) self.session = aiohttp.ClientSession(connector=_conn)
@ -24,24 +40,47 @@ class RequestBulder:
return True return True
async def send_request(self, url, json_body) -> dict | bool: async def send_request(self, url: str, json_body: dict) -> dict:
"""Выполняет запрос, при успехе возвращает json с ответом, при """Выполняет запрос, при успехе возвращает json с ответом, при
неудаче возвращает False.""" неудаче возвращает пустой dict.
_url = f"{self.cfg.central_host_url}/{url}"
Parameters
----------
url : str
Адрес куда слать запрос. Нужна часть не включающая хост, только get/post.
json_body: Json
Тело хапроса в Json формате.
Returns
-------
dict
Возвращает либо пустой dict, либо json ответа сервера (заполненный dict).
raw_resp = await self.session.get(_url, json=json_body) Examples
--------
>>> await send_request('count', json_body={} )
"""
_url = f"{self.cfg.central_host_url}/{url}"
try:
async with self.session.get(_url, json=json_body) as raw_resp:
if await self.__check_resp(raw_resp): if await self.__check_resp(raw_resp):
json_resp = await raw_resp.json() json_resp: dict = await raw_resp.json()
json_resp.pop("done") json_resp.pop("done")
return json_resp return json_resp
except ClientConnectorError:
return False logger.error(f"Ошибка подключения к серверу {_url}")
# не придумал ничего умнее чем подождать frequency_sec из конфига
await asyncio.sleep(self.cfg.frequency_sec)
except ServerDisconnectedError:
logger.error(f"Сервер отклонил подключение {_url}")
return dict()
async def wait(self) -> None: async def wait(self) -> None:
"""Ждет frequency_sec время.""" """Ждет frequency_sec время."""
await asyncio.sleep(self.cfg.frequency_sec) await asyncio.sleep(self.cfg.frequency_sec)
# def __del__(self): async def close(self) -> None:
# if self.session is not None: """Gracefull shutdown connection."""
# self.session.close() await self.session.close()

20
solution.py

@ -1,9 +1,10 @@
"""Создание конфиг. файлов для хостов."""
import argparse import argparse
import asyncio import asyncio
import os import os
from asyncio import Task from asyncio import Task
from dataclasses import dataclass from dataclasses import dataclass
from typing import List from typing import List, Union
import aiohttp import aiohttp
from aiohttp.client_exceptions import ClientConnectorError from aiohttp.client_exceptions import ClientConnectorError
@ -11,25 +12,26 @@ from loguru import logger
from app_config import AppConfig from app_config import AppConfig
from config_object import ConfigFactory, ConfigObject from config_object import ConfigFactory, ConfigObject
from request_builder import Json, RequestBulder from request_builder import RequestBulder
async def get_records_count(rb: RequestBulder) -> int: async def get_records_count(rb: RequestBulder) -> int:
resp: Json | bool = await rb.send_request("count", json_body={}) """Обертка для получения количества записей с сервера."""
records_count = 0 resp: dict = await rb.send_request("count", json_body={})
if resp:
records_count = resp.get("result") records_count: int = int(resp["result"]) if resp else 0
return records_count return int(records_count)
async def custom_wrapper( async def custom_wrapper(
config_factory: ConfigFactory, config_factory: ConfigFactory,
rb: RequestBulder, rb: RequestBulder,
usr: str, usr: str,
json: Json, json: dict,
) -> None: ) -> None:
resp: Json | bool = await rb.send_request("get", json) """Обертка для создания конфигов и их записи."""
resp: dict = await rb.send_request("get", json)
# Если мы получили валидный ответ, то разбираем пачку хостов из # Если мы получили валидный ответ, то разбираем пачку хостов из
# resp['result'] с созданием для каждой строки кофнига через # resp['result'] с созданием для каждой строки кофнига через

Loading…
Cancel
Save