Skip to content

Commit 1c25c25

Browse files
committed
add docker compose & ruff
1 parent 89199d1 commit 1c25c25

File tree

13 files changed

+263
-39
lines changed

13 files changed

+263
-39
lines changed

.dockerignore

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Git
2+
.git
3+
.gitignore
4+
.gitattributes
5+
6+
7+
# CI
8+
.codeclimate.yml
9+
.travis.yml
10+
.taskcluster.yml
11+
12+
# Docker
13+
docker-compose.yml
14+
Dockerfile
15+
.docker
16+
.dockerignore
17+
18+
# Byte-compiled / optimized / DLL files
19+
**/__pycache__/
20+
**/*.py[cod]
21+
22+
# C extensions
23+
*.so
24+
25+
# Distribution / packaging
26+
.Python
27+
env/
28+
build/
29+
develop-eggs/
30+
dist/
31+
downloads/
32+
eggs/
33+
lib/
34+
lib64/
35+
parts/
36+
sdist/
37+
var/
38+
*.egg-info/
39+
.installed.cfg
40+
*.egg
41+
42+
# PyInstaller
43+
# Usually these files are written by a python script from a template
44+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
45+
*.manifest
46+
*.spec
47+
48+
# Installer logs
49+
pip-log.txt
50+
pip-delete-this-directory.txt
51+
52+
# Unit test / coverage reports
53+
htmlcov/
54+
.tox/
55+
.coverage
56+
.cache
57+
nosetests.xml
58+
coverage.xml
59+
60+
# Translations
61+
*.mo
62+
*.pot
63+
64+
# Django stuff:
65+
*.log
66+
67+
# Sphinx documentation
68+
docs/_build/
69+
70+
# PyBuilder
71+
target/
72+
73+
# Virtual environment
74+
.env
75+
.venv/
76+
venv/
77+
78+
# PyCharm
79+
.idea
80+
81+
# Python mode for VIM
82+
.ropeproject
83+
**/.ropeproject
84+
85+
# Vim swap files
86+
**/*.swp
87+
88+
# VS Code
89+
.vscode/

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
APP__DEBUG=true
12
APP__PORT=8080
23
APP__URL=https://my.domain
34
APP__WEBHOOK_PATH=/webhook/tg

Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM python:3.12-slim-bullseye AS base
2+
3+
ENV PYTHONFAULTHANDLER=1
4+
ENV PYTHONUNBUFFERED=1
5+
ENV PYTHONHASHSEED=random
6+
ENV PYTHONDONTWRITEBYTECODE 1
7+
ENV PIP_NO_CACHE_DIR=off
8+
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
9+
ENV PIP_DEFAULT_TIMEOUT=100
10+
11+
12+
FROM base AS builder
13+
14+
COPY requirements.txt requirements.txt
15+
16+
ENV VIRTUAL_ENV=/opt/venv
17+
RUN python -m venv $VIRTUAL_ENV
18+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
19+
RUN pip install --no-cache-dir -r requirements.txt
20+
21+
22+
FROM base
23+
ENV VIRTUAL_ENV=/opt/venv
24+
COPY --from=builder $VIRTUAL_ENV $VIRTUAL_ENV
25+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
26+
27+
WORKDIR /app
28+
COPY . /app
29+
30+
EXPOSE 8080
31+
32+
ENTRYPOINT ["python", "main.py"]

bot/configs/config.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from typing import Any, Dict
1+
from typing import Any
22

33
from pydantic import SecretStr
44
from pydantic_settings import BaseSettings
55

66

77
class App(BaseSettings):
8+
debug: bool = True
89
port: int = 8080
910
url: str = 'https://my.domain'
1011
webhook_path: str = '/webhook/tg'
@@ -17,16 +18,13 @@ class TgBot(BaseSettings):
1718
class Settings(BaseSettings):
1819
app: App
1920
tg_bot: TgBot
20-
logging: Dict[str, Any] = {
21+
logging: dict[str, Any] = {
2122
'version': 1,
2223
'disable_existing_loggers': True,
2324
'formatters': {
2425
'default': {
2526
'format': '%(levelname)-8s [%(asctime)s] [%(name)s] %(message)s',
2627
},
27-
'uvicorn_access': {
28-
'format': '%(levelname)-8s [%(asctime)s] [%(name)s] - %(client_addr)s - "%(request_line)s" %(status_code)s',
29-
},
3028
},
3129
'handlers': {
3230
'default': {

bot/handlers/handlers.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
from typing import Optional
2-
31
from aiogram import Bot
42
from aiogram.enums import ChatAction
53
from aiogram.fsm.context import FSMContext
6-
from aiogram.types import Message, CallbackQuery
4+
from aiogram.types import CallbackQuery, Message
75

86
from bot.callbacks.callback import SaveCallbackFactory
97
from bot.keyboards.keyboards import Keyboards
@@ -12,7 +10,6 @@
1210

1311

1412
class Handlers:
15-
1613
def __init__(self, bot: Bot, kb: Keyboards, bot_service: BotService):
1714
self.bot = bot
1815
self.kb = kb
@@ -38,8 +35,8 @@ async def answer_fsm_state_1(self, message: Message, state: FSMContext):
3835

3936
async def answer_fsm_state_2(self, message: Message, state: FSMContext):
4037
await state.update_data(step_2=message.text)
41-
data = await state.get_data()
42-
await message.answer(f"Step 1: {data['step_1']}\n" f"Step 2: {data['step_2']}")
38+
data = await state.get_data()
39+
await message.answer(f"Step 1: {data['step_1']}\nStep 2: {data['step_2']}")
4340
await state.clear()
4441

4542
async def answer_inline_button(self, message: Message):
@@ -53,7 +50,7 @@ async def process_any_inline_button_press(self, callback: CallbackQuery, callbac
5350
await callback.message.answer(text=callback_data.pack())
5451
await callback.answer()
5552

56-
async def __send_message(self, chat_id: int, text: str, reply_to_message_id: Optional[int] = None) -> int:
53+
async def __send_message(self, chat_id: int, text: str, reply_to_message_id: int | None = None) -> int:
5754
await self.bot.send_chat_action(chat_id, ChatAction.TYPING)
5855
message = await self.bot.send_message(chat_id=chat_id, text=text, reply_to_message_id=reply_to_message_id)
5956

bot/keyboards/keyboards.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
from typing import Optional
2-
3-
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
1+
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup
42

53

64
class Keyboards:
7-
85
def __init__(self):
96
pass
107

@@ -16,7 +13,7 @@ def get_start_button(self) -> ReplyKeyboardMarkup:
1613

1714
return ReplyKeyboardMarkup(keyboard=kb_list, resize_keyboard=True, one_time_keyboard=True)
1815

19-
def get_inline_button(self, callback_data: Optional[str] = None) -> InlineKeyboardMarkup:
16+
def get_inline_button(self, callback_data: str | None = None) -> InlineKeyboardMarkup:
2017
inline_kb_list = [
2118
[
2219
InlineKeyboardButton(text='Save', callback_data=callback_data),

bot/middlewares/throttling.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import logging
2-
from typing import Any, Awaitable, Callable, Dict
2+
from collections.abc import Awaitable, Callable
3+
from typing import Any
34

45
from aiogram import BaseMiddleware
56
from aiogram.types import TelegramObject, User
67
from cachetools import TTLCache
78

89
logger = logging.getLogger(__name__)
910

10-
CACHE = TTLCache(maxsize=10_000, ttl=2) # Максимальный размер кэша - 10000 ключей, а время жизни ключа - 5 секунд
11+
CACHE = TTLCache(maxsize=10_000, ttl=2) # Максимальный размер кэша - 10000 ключей, время жизни ключа - 5 секунд
1112

1213

1314
class ThrottlingMiddleware(BaseMiddleware):
14-
1515
async def __call__(
1616
self,
17-
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
17+
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
1818
event: TelegramObject,
19-
data: Dict[str, Any],
19+
data: dict[str, Any],
2020
) -> Any:
2121
user: User = data.get('event_from_user')
2222

bot/services/bot_service.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
class BotService:
2-
32
def __init__(self):
43
pass
54

bot/states/bot_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from aiogram.fsm.state import StatesGroup, State
1+
from aiogram.fsm.state import State, StatesGroup
22

33

44
class BotState(StatesGroup):

docker-compose.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
3+
telegram-bot:
4+
image: telegram-bot
5+
container_name: telegram-bot
6+
build:
7+
context: .
8+
dockerfile: Dockerfile
9+
ports:
10+
- "8080:8080"
11+
restart: always
12+
stop_signal: SIGINT
13+
working_dir: /app
14+
volumes:
15+
- .env:/app/.env:ro

0 commit comments

Comments
 (0)