This commit is contained in:
2024-12-11 16:16:49 +03:00
commit b2699db727
12 changed files with 481 additions and 0 deletions

99
main.py Normal file
View File

@@ -0,0 +1,99 @@
from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from database import engine, SessionLocal, Base
import models
import schemas
from sqlalchemy import select, update
from sqlalchemy.orm import aliased
app = FastAPI(
title="Сервис Счетчиков",
description="Сервис для инкрементирования, получения и сброса счетчиков с поддержкой namespaces, приложений и версий.",
version="1.0.0"
)
# Создаем таблицы в базе данных
Base.metadata.create_all(bind=engine)
# Зависимость для получения сессии базы данных
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/{namespace}/{application}/{version}", response_model=schemas.CounterResponse, summary="Инкрементировать счетчик и получить новое значение")
def increment_counter(namespace: str, application: str, version: str, db: Session = Depends(get_db)):
try:
# Попытка найти существующий счетчик
counter = db.query(models.Counter).filter_by(
namespace=namespace,
application=application,
version=version
).with_for_update().first()
if counter:
counter.value += 1
else:
# Если счетчик не существует, создать новый с value=1
counter = models.Counter(
namespace=namespace,
application=application,
version=version,
value=1
)
db.add(counter)
db.commit()
db.refresh(counter)
return counter
except IntegrityError:
db.rollback()
raise HTTPException(status_code=500, detail="Ошибка при доступе к базе данных.")
@app.get("/{namespace}/{application}/{version}", response_model=schemas.CounterResponse, summary="Получить текущее значение счетчика")
def get_counter(namespace: str, application: str, version: str, db: Session = Depends(get_db)):
counter = db.query(models.Counter).filter_by(
namespace=namespace,
application=application,
version=version
).first()
if not counter:
# Если счетчик не найден, вернуть значение 0
return schemas.CounterResponse(
namespace=namespace,
application=application,
version=version,
value=0
)
return counter
@app.delete("/{namespace}/{application}/{version}", response_model=schemas.CounterResponse, summary="Сбросить счетчик до 0")
def reset_counter(namespace: str, application: str, version: str, db: Session = Depends(get_db)):
counter = db.query(models.Counter).filter_by(
namespace=namespace,
application=application,
version=version
).with_for_update().first()
if counter:
counter.value = 0
else:
# Если счетчик не существует, создать его с value=0
counter = models.Counter(
namespace=namespace,
application=application,
version=version,
value=0
)
db.add(counter)
db.commit()
db.refresh(counter)
return counter