init commit
This commit is contained in:
0
app/api/__init__.py
Normal file
0
app/api/__init__.py
Normal file
10
app/api/main.py
Normal file
10
app/api/main.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from fastapi import FastAPI
|
||||
from app.core.config import settings
|
||||
from app.api.routes import templates as templates_router
|
||||
|
||||
app = FastAPI(title="TG Autoposting API", version="0.1.0")
|
||||
app.include_router(templates_router.router)
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "ok", "env": settings.env}
|
||||
142
app/api/routes/templates.py
Normal file
142
app/api/routes/templates.py
Normal file
@@ -0,0 +1,142 @@
|
||||
# # app/api/routes/templates.py
|
||||
# from __future__ import annotations
|
||||
# from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
# from sqlalchemy import select, or_
|
||||
# from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
# from app.db.session import get_async_session
|
||||
# from app.models.templates import Template
|
||||
# from app.api.schemas.template import TemplateIn, TemplateOut
|
||||
# from app.services.templates import count_templates
|
||||
|
||||
# router = APIRouter(prefix="/templates", tags=["templates"])
|
||||
|
||||
# # Заглушка аутентификации
|
||||
# async def get_owner_id(x_user_id: int | None = None):
|
||||
# return x_user_id or 0
|
||||
|
||||
# @router.post("/", response_model=TemplateOut)
|
||||
# async def create_tpl(
|
||||
# data: TemplateIn,
|
||||
# owner_id: int = Depends(get_owner_id),
|
||||
# s: AsyncSession = Depends(get_async_session),
|
||||
# ):
|
||||
# tpl = Template(owner_id=owner_id, **data.model_dump())
|
||||
# s.add(tpl)
|
||||
# await s.commit()
|
||||
# await s.refresh(tpl)
|
||||
# return tpl
|
||||
|
||||
# @router.get("/", response_model=list[TemplateOut])
|
||||
# async def list_tpls(
|
||||
# owner_id: int = Depends(get_owner_id),
|
||||
# limit: int = Query(20, ge=1, le=100),
|
||||
# offset: int = Query(0, ge=0),
|
||||
# q: str | None = Query(default=None),
|
||||
# s: AsyncSession = Depends(get_async_session),
|
||||
# ):
|
||||
# stmt = select(Template).where(
|
||||
# Template.owner_id == owner_id,
|
||||
# Template.is_archived.is_(False),
|
||||
# )
|
||||
# if q:
|
||||
# like = f"%{q}%"
|
||||
# stmt = stmt.where(or_(Template.name.ilike(like), Template.title.ilike(like)))
|
||||
# stmt = stmt.order_by(Template.updated_at.desc()).limit(limit).offset(offset)
|
||||
# res = await s.execute(stmt)
|
||||
# return list(res.scalars())
|
||||
|
||||
# @router.get("/count")
|
||||
# async def count_tpls(
|
||||
# owner_id: int = Depends(get_owner_id),
|
||||
# q: str | None = None,
|
||||
# ):
|
||||
# total = await count_templates(owner_id, q)
|
||||
# return {"total": total}
|
||||
|
||||
# @router.delete("/{tpl_id}")
|
||||
# async def delete_tpl(
|
||||
# tpl_id: int,
|
||||
# owner_id: int = Depends(get_owner_id),
|
||||
# s: AsyncSession = Depends(get_async_session),
|
||||
# ):
|
||||
# res = await s.execute(select(Template).where(
|
||||
# Template.id == tpl_id,
|
||||
# Template.owner_id == owner_id
|
||||
# ))
|
||||
# tpl = res.scalars().first()
|
||||
# if not tpl:
|
||||
# raise HTTPException(404, "not found")
|
||||
# await s.delete(tpl)
|
||||
# await s.commit()
|
||||
# return {"ok": True}
|
||||
|
||||
|
||||
# app/api/routes/templates.py
|
||||
from __future__ import annotations
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy import select, or_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db.session import get_async_session
|
||||
from app.models.templates import Template
|
||||
from app.api.schemas.template import TemplateIn, TemplateOut
|
||||
from app.services.templates import count_templates
|
||||
|
||||
router = APIRouter(prefix="/templates", tags=["templates"])
|
||||
|
||||
async def get_owner_id(x_user_id: int | None = None):
|
||||
return x_user_id or 0
|
||||
|
||||
@router.post("/", response_model=TemplateOut)
|
||||
async def create_tpl(
|
||||
data: TemplateIn,
|
||||
owner_id: int = Depends(get_owner_id),
|
||||
s: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
tpl = Template(owner_id=owner_id, **data.model_dump())
|
||||
s.add(tpl)
|
||||
await s.commit()
|
||||
await s.refresh(tpl)
|
||||
return tpl
|
||||
|
||||
@router.get("/", response_model=list[TemplateOut])
|
||||
async def list_tpls(
|
||||
owner_id: int = Depends(get_owner_id),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
offset: int = Query(0, ge=0),
|
||||
q: str | None = Query(default=None),
|
||||
s: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
stmt = select(Template).where(
|
||||
Template.owner_id == owner_id,
|
||||
Template.is_archived.is_(False),
|
||||
)
|
||||
if q:
|
||||
like = f"%{q}%"
|
||||
stmt = stmt.where(or_(Template.name.ilike(like), Template.title.ilike(like)))
|
||||
stmt = stmt.order_by(Template.updated_at.desc()).limit(limit).offset(offset)
|
||||
res = await s.execute(stmt)
|
||||
return list(res.scalars())
|
||||
|
||||
@router.get("/count")
|
||||
async def count_tpls(owner_id: int = Depends(get_owner_id), q: str | None = None):
|
||||
total = await count_templates(owner_id, q)
|
||||
return {"total": total}
|
||||
|
||||
@router.delete("/{tpl_id}")
|
||||
async def delete_tpl(
|
||||
tpl_id: int,
|
||||
owner_id: int = Depends(get_owner_id),
|
||||
s: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
res = await s.execute(select(Template).where(
|
||||
Template.id == tpl_id,
|
||||
Template.owner_id == owner_id
|
||||
))
|
||||
tpl = res.scalars().first()
|
||||
if not tpl:
|
||||
raise HTTPException(404, "not found")
|
||||
await s.delete(tpl)
|
||||
await s.commit()
|
||||
return {"ok": True}
|
||||
0
app/api/schemas/__init__.py
Normal file
0
app/api/schemas/__init__.py
Normal file
0
app/api/schemas/base.py
Normal file
0
app/api/schemas/base.py
Normal file
0
app/api/schemas/keyboard.py
Normal file
0
app/api/schemas/keyboard.py
Normal file
0
app/api/schemas/post.py
Normal file
0
app/api/schemas/post.py
Normal file
17
app/api/schemas/template.py
Normal file
17
app/api/schemas/template.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from __future__ import annotations
|
||||
from typing import Optional, Literal
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
class TemplateIn(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=64)
|
||||
title: Optional[str] = None
|
||||
type: Literal["text","photo","video","animation"] = "text"
|
||||
content: str
|
||||
keyboard_tpl: Optional[list[dict]] = None
|
||||
parse_mode: Optional[str] = "HTML"
|
||||
visibility: Literal["private","org","public"] = "private"
|
||||
|
||||
class TemplateOut(TemplateIn):
|
||||
id: int
|
||||
is_archived: bool
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
Reference in New Issue
Block a user