Browse Source

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

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

6
app_config.py

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

6
config_object.py

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

75
request_builder.py

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

20
solution.py

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

Loading…
Cancel
Save