Skip to content
This repository was archived by the owner on Jul 3, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
.venv
__pycache__
venv
idea
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/task-python.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

137 changes: 137 additions & 0 deletions Repositories/ServiceRepo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import datetime
import uuid
import pymongo

from db.db_connect import db
from model.service import Service


STATE_WORK = 'work'
STATE_NOT_WORK = 'notwork'


class ServiceRepo():

@staticmethod
async def get_all():
""" Выводит список сервисов """
items = db.get_collection('service').find()
list_items = []
async for item in items:
list_items.append(item)
return list_items

@staticmethod
async def get_actual_state_service():
""" Выводит список сервисов с актуальным состоянием """

services = await db.service.distinct('name')
list_services = []
for service in services:
actual_state = (
db.get_collection('service')
.find({'name': service})
.sort('state_dt', pymongo.DESCENDING)
.limit(1)
)
list_services.append(await actual_state.to_list(1))
return list_services

@staticmethod
async def get_state_data(state: str):
""" Dсе данные по каждому состоянию """

states = (
db.get_collection('service')
.find({'state': state})
.sort('state_dt', pymongo.DESCENDING)
)
list_state = []
async for state in states:
list_state.append(state)
return list_state

@staticmethod
async def get_service_by_name(name: str):
""" По имени сервиса выдает историю изменения состояния """

services = (
db.get_collection('service')
.find({'name': name})
.sort('state_dt', pymongo.DESCENDING)
)
list_service = []
async for service in services:
list_service.append(service)
return list_service

@staticmethod
async def get_sla(name: str, date_start: datetime.datetime, date_end: datetime.datetime):
""" По указанному интервалу выдается информация о том сколько не работал сервис и считает SLA """

services = (
db.get_collection('service')
.find({'name': name, 'state_dt': {'$gt': date_start, '$lt': date_end}})
.sort('state_dt', pymongo.DESCENDING)
)
previous_service = (
db.get_collection('service')
.find({'name': name, 'state_dt': {'$lt': date_start}})
.sort('state_dt', pymongo.DESCENDING)
.limit(1)
)
list_state = []
downtime = datetime.timedelta()
downtime_end = None
downtime_start = None

async for service in previous_service:
if service['state'] == STATE_NOT_WORK:
list_state.append(service)

async for service in services:
if service['state'] == STATE_NOT_WORK:
downtime_start = service['state_dt']
if downtime_end:
downtime += downtime_end - downtime_start
downtime_end = None
continue
downtime += date_end - downtime_start
elif service['state'] == STATE_WORK:
downtime_end = service['state_dt']

if list_state and downtime_end:
downtime += downtime_end - date_start
list_state.pop()
elif list_state and downtime_start:
downtime += downtime_start - date_start
list_state.pop()

sla = get_formatted_sla(date_start, date_end, downtime)
return sla


@staticmethod
async def insert(service: Service):
""" Получает и сохраняет данные: имя, состояние, описание """

id = str(uuid.uuid4())
service.id = id
service = service.dict(exclude={})
service['_id'] = id
service.pop('id')
await db.get_collection('service').insert_one(service)
return service

@staticmethod
async def delete_one(id: str):
""" Удаление сервиса """

return await db.get_collection('service').delete_one({'_id': id})


def get_formatted_sla(date_start: datetime.datetime, date_end: datetime.datetime, downtime: datetime.timedelta):
""" Форматирование строки SLA """

sla = ((date_end - date_start) - downtime) / (date_end - date_start) * 100
return '{0:.0f} hours'.format(downtime.total_seconds() // 3600), '{0:.3f}%'.format(sla)
1 change: 1 addition & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_URL = "mongodb://localhost:27017"
8 changes: 8 additions & 0 deletions db/db_connect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import motor.motor_asyncio
from fastapi import FastAPI

from config import DB_URL


app = FastAPI()
db = motor.motor_asyncio.AsyncIOMotorClient(DB_URL).service
6 changes: 6 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from fastapi import FastAPI
from routers import service


app = FastAPI()
app.include_router(service.router)
10 changes: 10 additions & 0 deletions model/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import datetime
from pydantic import BaseModel, Field


class Service(BaseModel):
id: str = ''
name: str = Field(include=True)
state: str = Field(include=True)
description: str = Field(include=True)
state_dt: datetime.datetime = Field(default=datetime.datetime.now())
44 changes: 44 additions & 0 deletions routers/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from datetime import datetime
from fastapi import APIRouter

from Repositories.ServiceRepo import ServiceRepo
from model.service import Service


router = APIRouter(prefix="/service", tags=['/service'])


@router.get("/")
async def get_all():
return await ServiceRepo.get_all()


@router.get("/actual_state_service")
async def actual_state_service():
return await ServiceRepo.get_actual_state_service()


@router.get("/get_state_data")
async def get_state_data(state: str):
return await ServiceRepo.get_state_data(state)


@router.get("/get_sla")
async def get_state_data(name: str, date_start: datetime, date_end: datetime):
return await ServiceRepo.get_sla(name, date_start, date_end)


@router.get("/get_service_by_name")
async def get_service_by_name(name: str):
return await ServiceRepo.get_service_by_name(name)


@router.post("/add_service", status_code=201)
async def add_tabel(service: Service):
_service = await ServiceRepo.insert(service)
return _service


@router.delete("/delete", status_code=200)
async def delete_user(id: str):
await ServiceRepo.delete_one(id)