|
1 |
| -... |
| 1 | +import logging |
| 2 | +import os |
| 3 | +import time |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +import requests |
| 7 | +import telegram |
| 8 | +from dotenv import load_dotenv |
2 | 9 |
|
3 | 10 | load_dotenv()
|
4 | 11 |
|
5 | 12 |
|
6 |
| -PRACTICUM_TOKEN = ... |
7 |
| -TELEGRAM_TOKEN = ... |
8 |
| -TELEGRAM_CHAT_ID = ... |
| 13 | +class ServiceError(Exception): |
| 14 | + pass |
| 15 | + |
| 16 | + |
| 17 | +class ConnectingError(Exception): |
| 18 | + pass |
| 19 | + |
| 20 | + |
| 21 | +class EndpointError(Exception): |
| 22 | + pass |
| 23 | + |
| 24 | + |
| 25 | +class MessageSendingError(Exception): |
| 26 | + pass |
| 27 | + |
| 28 | + |
| 29 | +class GlobalsError(Exception): |
| 30 | + pass |
| 31 | + |
| 32 | + |
| 33 | +class GlobalIsNullError(Exception): |
| 34 | + pass |
| 35 | + |
| 36 | + |
| 37 | +class HomeworkTypeError(Exception): |
| 38 | + pass |
| 39 | + |
| 40 | + |
| 41 | +CONNECTION_ERROR = '{error}, {url}, {headers}, {params}' |
| 42 | +SERVICE_REJECTION = '{code},' |
| 43 | +WRONG_ENDPOINT = '{response_status}, {url}, {headers}, {params}' |
| 44 | +WRONG_HOMEWORK_STATUS = '{}' |
| 45 | +WRONG_DATA_TYPE = 'Неверный тип данных {type}, вместо "dict".' |
| 46 | +HOMEWORK_STATUS = '{}' |
| 47 | +STATUS_IS_CHANGED = '{verdict}, {homework}' |
| 48 | +STATUS_IS_NOT_CHANGED = 'Статус не изменился, нет записей.' |
| 49 | +FAILURE_TO_SEND_MESSAGE = '{error}, {message}' |
| 50 | +GLOBAL_VARIABLE_IS_MISSING = 'Отсутствует глобальная переменная {}' |
| 51 | +GLOBAL_VARIABLE_IS_EMPTY = 'Пустая глобальная переменная {}' |
| 52 | +MESSAGE_IS_SENT = 'Сообщение {} отправлено' |
| 53 | + |
| 54 | +PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN') |
| 55 | +TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN') |
| 56 | +TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID') |
9 | 57 |
|
10 | 58 | RETRY_TIME = 600
|
11 | 59 | ENDPOINT = 'https://practicum.yandex.ru/api/user_api/homework_statuses/'
|
|
20 | 68 |
|
21 | 69 |
|
22 | 70 | def send_message(bot, message):
|
23 |
| - ... |
| 71 | + '''Отправляет сообщение пользователю в Телегу.''' |
| 72 | + try: |
| 73 | + bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=message) |
| 74 | + except Exception as error: |
| 75 | + raise MessageSendingError(FAILURE_TO_SEND_MESSAGE.format( |
| 76 | + error=error, |
| 77 | + message=message, |
| 78 | + )) |
| 79 | + else: |
| 80 | + logging.info(f'Message \'{message}\' is sent') |
24 | 81 |
|
25 | 82 |
|
26 | 83 | def get_api_answer(current_timestamp):
|
| 84 | + '''Делает запрос к единственному эндпоинту API-сервиса.''' |
27 | 85 | timestamp = current_timestamp or int(time.time())
|
28 | 86 | params = {'from_date': timestamp}
|
29 |
| - |
30 |
| - ... |
| 87 | + headers = {'Authorization': f'OAuth {PRACTICUM_TOKEN}'} |
| 88 | + all_params = dict(url=ENDPOINT, headers=headers, params=params) |
| 89 | + try: |
| 90 | + response = requests.get(**all_params) |
| 91 | + except telegram.error.TelegramError as error: |
| 92 | + raise telegram.TelegramError(CONNECTION_ERROR.format( |
| 93 | + error=error, |
| 94 | + **all_params, |
| 95 | + )) |
| 96 | + response_status = response.status_code |
| 97 | + if response_status != 200: |
| 98 | + raise EndpointError(WRONG_ENDPOINT.format( |
| 99 | + response_status=response_status, |
| 100 | + **all_params, |
| 101 | + )) |
| 102 | + return response.json() |
31 | 103 |
|
32 | 104 |
|
33 | 105 | def check_response(response):
|
34 |
| - |
35 |
| - ... |
| 106 | + ''' |
| 107 | + Возвращает домашку, если есть, |
| 108 | + а так же проверяет валидность её статуса. |
| 109 | + ''' |
| 110 | + try: |
| 111 | + return response['homeworks'][0] |
| 112 | + except 'code' in response: |
| 113 | + raise ServiceError(SERVICE_REJECTION.format( |
| 114 | + code=response.get('code'), |
| 115 | + )) |
36 | 116 |
|
37 | 117 |
|
38 | 118 | def parse_status(homework):
|
39 |
| - homework_name = ... |
40 |
| - homework_status = ... |
| 119 | + '''Возвращает текст сообщения от ревьюера.''' |
| 120 | + data_type = type(homework) |
| 121 | + if data_type != dict: |
| 122 | + raise HomeworkTypeError(WRONG_DATA_TYPE.format(data_type)) |
| 123 | + homework_name = homework.get('homework_name') |
| 124 | + homework_status = homework.get('status') |
41 | 125 |
|
42 |
| - ... |
| 126 | + if homework_status not in HOMEWORK_STATUSES: |
| 127 | + raise NameError(WRONG_HOMEWORK_STATUS.format(homework_status)) |
43 | 128 |
|
44 |
| - verdict = ... |
45 |
| - |
46 |
| - ... |
| 129 | + verdict = HOMEWORK_STATUSES[homework_status] |
47 | 130 |
|
48 | 131 | return f'Изменился статус проверки работы "{homework_name}". {verdict}'
|
49 | 132 |
|
50 | 133 |
|
51 | 134 | def check_tokens():
|
52 |
| - ... |
| 135 | + '''Проверяет доступность переменных окружения.''' |
| 136 | + for key in ( |
| 137 | + 'PRACTICUM_TOKEN', |
| 138 | + 'TELEGRAM_TOKEN', |
| 139 | + 'TELEGRAM_CHAT_ID', |
| 140 | + 'ENDPOINT' |
| 141 | + ): |
| 142 | + if globals()[key] is None: |
| 143 | + logging.error(GLOBAL_VARIABLE_IS_MISSING.format(key)) |
| 144 | + return False |
| 145 | + elif not globals()[key]: |
| 146 | + logging.error(GLOBAL_VARIABLE_IS_EMPTY.format(key)) |
| 147 | + return False |
| 148 | + return True |
53 | 149 |
|
54 | 150 |
|
55 | 151 | def main():
|
56 | 152 | """Основная логика работы бота."""
|
57 | 153 |
|
58 |
| - ... |
| 154 | + if not check_tokens(): |
| 155 | + raise GlobalsError('Ошибка глобальной переменной. Смотрите логи.') |
| 156 | + check_tokens() |
59 | 157 |
|
60 | 158 | bot = telegram.Bot(token=TELEGRAM_TOKEN)
|
61 | 159 | current_timestamp = int(time.time())
|
62 | 160 |
|
63 |
| - ... |
64 |
| - |
65 | 161 | while True:
|
66 | 162 | try:
|
67 |
| - response = ... |
68 |
| - |
69 |
| - ... |
70 |
| - |
71 |
| - current_timestamp = ... |
| 163 | + response = get_api_answer(current_timestamp) |
| 164 | + homework = check_response(response) |
| 165 | + message = parse_status(homework) |
| 166 | + send_message(bot, message) |
| 167 | + print(response) |
| 168 | + current_timestamp = response.get('current_date') |
72 | 169 | time.sleep(RETRY_TIME)
|
73 | 170 |
|
| 171 | + except IndexError: |
| 172 | + message = 'Статус работы не изменился' |
| 173 | + send_message(bot, message) |
| 174 | + time.sleep(RETRY_TIME) |
74 | 175 | except Exception as error:
|
75 | 176 | message = f'Сбой в работе программы: {error}'
|
76 |
| - ... |
| 177 | + send_message(bot, message) |
77 | 178 | time.sleep(RETRY_TIME)
|
78 | 179 | else:
|
79 |
| - ... |
| 180 | + logging.info(MESSAGE_IS_SENT.format(message)) |
80 | 181 |
|
81 | 182 |
|
82 | 183 | if __name__ == '__main__':
|
| 184 | + logging.basicConfig( |
| 185 | + format='%(asctime)s, %(message)s, %(lineno)d, %(name)s', |
| 186 | + filemode='w', |
| 187 | + filename=f'{Path(__file__).stem}.log', |
| 188 | + level=logging.INFO, |
| 189 | + ) |
83 | 190 | main()
|
0 commit comments