Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logic initialisation + TG bot addition (#3) #5

Merged
merged 54 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f8e97b9
ping service initial
parfenovma Feb 3, 2023
ab12c94
daily wtf commit
parfenovma Feb 4, 2023
6cf5c64
alert pipeline initial
parfenovma Feb 8, 2023
aadfa1d
fixes
parfenovma Feb 10, 2023
4513377
add_metric impl done
parfenovma Feb 12, 2023
61d73e6
change delay on alert impl
parfenovma Feb 12, 2023
e232430
admin creds in dotenv
parfenovma Feb 13, 2023
3042561
ping tests initial
parfenovma Feb 13, 2023
76593ed
ping api tests complete
parfenovma Feb 13, 2023
91a2de1
scheduler service tests initial
parfenovma Feb 13, 2023
fe484f5
Implimenting authlib
Wudext Apr 10, 2023
80dab9a
Deleting __pycache__
Wudext Apr 10, 2023
caef12d
Update requirements.txt
Wudext Apr 10, 2023
f5bc0f4
Merge branch 'ping' of https://github.com/profcomff/aciniformes-proje…
Wudext Apr 10, 2023
7142f36
Test fix
Wudext Apr 13, 2023
a10b8b3
Update requirements.dev.txt
Wudext Apr 13, 2023
c8b7f2a
TG Bot logic initialisation (kinda) + scheduler logic fix
Wudext Apr 17, 2023
94b66d1
I don`t know what im doing
Wudext Apr 19, 2023
c058235
OMFG it`s working
Wudext Apr 24, 2023
62ee349
Fixing tests
Wudext Apr 24, 2023
931db77
Fix migrations
Wudext Apr 24, 2023
dd8fc4d
Cleaning up
Wudext Apr 24, 2023
c236e4b
Fixing tests (not realy) + adding README.md
Wudext Apr 29, 2023
2440236
Finishing tests
Wudext May 6, 2023
e3350d2
Fix test
Wudext May 6, 2023
3ebd20b
Семён меня не любит(
Wudext May 15, 2023
3c37886
Fix tests (kinda)
Wudext May 15, 2023
bada526
Fixing again
Wudext May 15, 2023
f3949ff
Kinda fix but actually no
Wudext May 22, 2023
11bd062
Fix test (finally блять)
Wudext May 27, 2023
b0a072b
ы
Wudext May 27, 2023
fc316a4
хватит с меня
Wudext May 27, 2023
b965e93
Fixing
Wudext May 29, 2023
b5ca78b
Docker + makefile
Wudext May 29, 2023
a63573b
Fix session + delete abstract classes + change metric/alert logic
Wudext Jul 6, 2023
518e3bf
Black + isort
Wudext Jul 6, 2023
cb41ea8
Check for addition/deletion while working
Wudext Jul 11, 2023
a211f88
Black + Isort (again блять)
Wudext Jul 11, 2023
2f4d7cb
Pydantic 2 + fix requirements.txt
Wudext Jul 11, 2023
6b87bba
Fix migrations
Wudext Jul 11, 2023
eb079da
Delete .idea directory
Wudext Jul 15, 2023
5be400e
Alert and Receiver schema fix + test fix
Wudext Jul 15, 2023
0512d88
Dockerfile for pinger + ping fix + update requirements.txt
Wudext Jul 16, 2023
d17dbd2
Dockerfile fix + local startup fix
Wudext Jul 21, 2023
71237da
начало моей работы над этой помойкой
grigoriev-semyon Jul 22, 2023
cb28f3a
фикс тестов
grigoriev-semyon Jul 23, 2023
ca789a1
lint
grigoriev-semyon Jul 23, 2023
7bef0c4
добавил фетч фетчеров поо расписанию
grigoriev-semyon Jul 23, 2023
ea64080
пофиксил пинг
grigoriev-semyon Jul 23, 2023
052e73c
loop sigint handler
grigoriev-semyon Jul 23, 2023
0ce30a3
crud service del
grigoriev-semyon Jul 23, 2023
7959f58
async
grigoriev-semyon Jul 23, 2023
7e1e425
async
grigoriev-semyon Jul 23, 2023
14754b6
review
grigoriev-semyon Jul 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Tests
name: Python package

on:
pull_request:
Expand All @@ -8,17 +8,18 @@ jobs:
test:
name: Unit tests
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@master
- name: Set up docker
uses: docker-practice/actions-setup-docker@master
- name: Run postgres
run: |
docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust --name db-test postgres:15-alpine
- uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'
- name: Install dependencies
run: |
python -m ensurepip
Expand All @@ -29,10 +30,39 @@ jobs:
DB_DSN=postgresql://postgres@localhost:5432/postgres alembic upgrade head
- name: Build coverage file
run: |
DB_DSN=postgresql://postgres@localhost:5432/postgres pytest --cache-clear --cov=aciniformes_backend tests > pytest-coverage.txt
DB_DSN=postgresql://postgres@localhost:5432/postgres pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered tests/ | tee pytest-coverage.txt
- name: Print report
if: always()
run: |
cat pytest-coverage.txt
- name: Comment coverage
uses: coroo/[email protected]
- name: Pytest coverage comment
uses: MishaKav/pytest-coverage-comment@main
with:
pytest-coverage-path: ./pytest-coverage.txt
title: Coverage Report
badge-title: Code Coverage
hide-badge: false
hide-report: false
create-new-comment: false
hide-comment: false
report-only-changed-files: false
remove-link-from-badge: false
junitxml-path: ./pytest.xml
junitxml-title: Summary
linting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.11
- uses: isort/isort-action@master
with:
requirementsFiles: "requirements.txt requirements.dev.txt"
- uses: psf/black@stable
- name: Comment if linting failed
if: ${{ failure() }}
uses: thollander/actions-comment-pull-request@v2
with:
message: |
:poop: Code linting failed, use `black` and `isort` to fix it.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,3 @@ dmypy.json

# Pyre type checker
.pyre/
client_secret.json
static/**
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
ENV APP_NAME=aciniformes_backend
ENV APP_MODULE=${APP_NAME}.routes.base:app

COPY ./requirements.txt /app/
COPY ./logging_prod.conf /app/
COPY ./logging_test.conf /app/
COPY ./.env /app/
RUN pip install -U -r /app/requirements.txt

COPY ./alembic.ini /alembic.ini
COPY ./migrations /migrations/

COPY . /app
29 changes: 29 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2022, Профком студентов физфака МГУ
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
run:
source ./venv/bin/activate && uvicorn --reload --log-config logging_dev.conf aciniformes_backend.routes.base:app

configure: venv
source ./venv/bin/activate && pip install -r requirements.dev.txt -r requirements.txt

venv:
python3.11 -m venv venv

atomic-format:
autoflake -r --in-place --remove-all-unused-imports ./$(module)
isort ./$(module)
black ./$(module)

format:
make atomic-format module=pinger_backend
make atomic-format module=aciniformes_backend
make atomic-format module=settings.py

db:
docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust --name db-pinger_backend postgres:15

migrate:
alembic upgrade head
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Aciniformes-project

Проект пингера сервисов профкома ФФ МГУ. Позволяет пользователю просто и быстро проверять работоспособность любого сайта и сервиса и получать отчет через telegram бота.


# Функционал

1. Опрос любого сервиса или сайта на работоспособность
2. Создание расписания проверок указанных сайтов/сервисов
3. Получение удобного отчета о проверке через telegram бота

# Разработка
Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка


# Quick Start
1. Перейдите в папку проекта

2. Создайте виртуальное окружение командой:
`foo@bar:~$ python3 -m venv ./venv/`
3. Установите библиотеки командой:
`foo@bar:~$ pip install -m requirements.txt`
4. Установите все переменные окружения (см. CONTRIBUTING.md)
5. Запускайте приложение!
`foo@bar:~$ python -m services-backend`


# Использование
1. Создание получателя сообщений
1. Получить или узнать токен telegram бота, через которого будет посылаться сообщение
2. Узнать id чата-получателя в telegram
3. Создать получателя сообщений, выполнив запрос POST /receiver с телом: `{"url": "https://api.telegram.org/bot{токен_бота}/sendMessage", "method": "post", "receiver_body": {"chat_id": id_получателя, "text": текст_сообщения}`

2. Создание опрашиваемого сервиса
1. Выполнить запрос POST /fetcher с телом: `"{
"type_": "get/post/ping",
"address": "ссылка на опрашиваемый сайт",
"fetch_data": "{}" (Имеет смысла заполнять только если в type_ указан post запрос),
"delay_ok": частота опроса при успешном запросе,
"delay_fail": частота опроса при неудавшемся запросе
}"`

# Параметризация и плагины
BOT_TOKEN - токен бота-отправителя отчетов

# Ссылки
Документация проекта - https://api.test.profcomff.com/?urls.primaryName=pinger#

Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка
Binary file removed aciniformes_backend/__init__.pyc
Binary file not shown.
1 change: 1 addition & 0 deletions aciniformes_backend/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

from .routes import app


if __name__ == "__main__":
uvicorn.run(app)
Binary file not shown.
8 changes: 4 additions & 4 deletions aciniformes_backend/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .metric import Metric
from .fetcher import Fetcher
from .alerts import Alert, Receiver
from .base import BaseModel
from .auth import Auth
from .fetcher import Fetcher, FetcherType
from .metric import Metric


__all__ = ["Metric", "Fetcher", "Alert", "Receiver", "BaseModel", "Auth"]
__all__ = ["Metric", "Fetcher", "Alert", "Receiver", "BaseModel", "FetcherType"]
28 changes: 15 additions & 13 deletions aciniformes_backend/models/alerts.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
"""Классы хранения настроек нотификаций
"""
from datetime import datetime
from .base import BaseModel
from sqlalchemy import JSON, DateTime, ForeignKey, Integer, String
from enum import Enum

from sqlalchemy import JSON, DateTime
from sqlalchemy import Enum as DbEnum
from sqlalchemy import Integer, String
from sqlalchemy.orm import Mapped, mapped_column

from .base import BaseModel


class Method(str, Enum):
POST: str = "post"
GET: str = "get"


class Receiver(BaseModel):
id_: Mapped[int] = mapped_column("id", Integer, primary_key=True)
name: Mapped[str] = mapped_column(String, nullable=False)
chat_id: Mapped[int] = mapped_column(Integer, nullable=False)
url: Mapped[str] = mapped_column(String, nullable=False)
method: Mapped[Method] = mapped_column(DbEnum(Method, native_enum=False), nullable=False)
receiver_body: Mapped[dict] = mapped_column(JSON, nullable=False)
create_ts: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
modify_ts: Mapped[datetime] = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)


class Alert(BaseModel):
id_: Mapped[int] = mapped_column("id", Integer, primary_key=True)
data = mapped_column(JSON, nullable=False)
receiver: Mapped[int] = mapped_column(
Integer, ForeignKey("receiver.id", ondelete="CASCADE"), nullable=False
)
filter = mapped_column(String, nullable=False)
create_ts = mapped_column(DateTime, default=datetime.utcnow)
modify_ts = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
15 changes: 0 additions & 15 deletions aciniformes_backend/models/auth.py

This file was deleted.

3 changes: 2 additions & 1 deletion aciniformes_backend/models/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
from sqlalchemy.orm import declared_attr, as_declarative

from sqlalchemy.orm import as_declarative, declared_attr


@as_declarative()
Expand Down
30 changes: 9 additions & 21 deletions aciniformes_backend/models/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,29 @@
"""
from datetime import datetime
from enum import Enum
from .base import BaseModel

import sqlalchemy
from sqlalchemy import JSON, DateTime, Integer, String
from sqlalchemy import DateTime, Integer, String
from sqlalchemy.orm import Mapped, mapped_column

from .base import BaseModel


class FetcherType(str, Enum):
GET = "get_ok" # Пишет True, если GET запрос вернул статус 200..299
POST = "post_ok" # Пишет True, если POST запрос вернул статус 200..299
PING = "ping_ok" # Пишет True, если PING успешный
GET = "get" # Пишет положительную метрику, если GET запрос вернул статус 200..299
POST = "post" # Пишет положительную метрику, если POST запрос вернул статус 200..299
PING = "ping" # Пишет положительную метрику, если PING успешный


class Fetcher(BaseModel):
id_: Mapped[int] = mapped_column("id", Integer, primary_key=True)
name: Mapped[str] = mapped_column(String, nullable=False)
type_: Mapped[FetcherType] = mapped_column(
"type", sqlalchemy.Enum(FetcherType, native_enum=False), nullable=False
)
type_: Mapped[FetcherType] = mapped_column("type", sqlalchemy.Enum(FetcherType, native_enum=False), nullable=False)
address: Mapped[str] = mapped_column(String, nullable=False)
fetch_data: Mapped[str] = mapped_column(
String
) # Данные, которые передаются в теле POST запроса
metrics: Mapped[dict] = mapped_column(
JSON, default={}, nullable=False
) # Статическая часть метрик
metric_name: Mapped[str] = mapped_column(
String, nullable=False
) # Название динамической части метрик
fetch_data: Mapped[str] = mapped_column(String, nullable=True) # Данные, которые передаются в теле POST запроса
delay_ok: Mapped[int] = mapped_column(
Integer, default=300, nullable=False
) # Через сколько секунд повторить запрос, если предыдущий успешный
delay_fail: Mapped[int] = mapped_column(
Integer, default=30, nullable=False
) # Через сколько секунд повторить запрос, если предыдущий неуспешный
create_ts: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
modify_ts: Mapped[datetime] = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
11 changes: 7 additions & 4 deletions aciniformes_backend/models/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
"""

from datetime import datetime
from .base import BaseModel
from sqlalchemy import Integer, JSON, DateTime

from sqlalchemy import Boolean, Float, Integer, String
from sqlalchemy.orm import Mapped, mapped_column

from .base import BaseModel


class Metric(BaseModel):
id_: Mapped[int] = mapped_column("id", Integer, primary_key=True)
metrics: Mapped[dict] = mapped_column(JSON, nullable=False)
create_ts: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
name: Mapped[str] = mapped_column("name", String, nullable=False)
ok: Mapped[bool] = mapped_column("ok", Boolean, nullable=False, default=True)
time_delta: Mapped[float] = mapped_column(Float, default=datetime.utcnow)
3 changes: 3 additions & 0 deletions aciniformes_backend/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from .base import app


__all__ = ["app"]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading