betonski cegli lp

This commit is contained in:
2025-04-17 12:00:14 +00:00
parent 52603a5d1a
commit 9b8c3902de
4 changed files with 141 additions and 7 deletions

80
index.html Normal file
View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Items CRUD App</title>
<style>
body { font-family: Arial; padding: 2rem; }
input, button { margin: 5px; padding: 0.5rem; }
ul { list-style-type: none; padding: 0; }
li { margin-bottom: 10px; }
</style>
</head>
<body>
<h1>Items List (CRUD)</h1>
<input type="text" id="name" placeholder="Item name" />
<input type="text" id="description" placeholder="Description" />
<button onclick="createItem()">Add Item</button>
<ul id="item-list"></ul>
<script>
const API_BASE = "http://localhost:8000/v1";
async function fetchItems() {
const res = await fetch(`${API_BASE}/items`);
const items = await res.json();
const list = document.getElementById("item-list");
list.innerHTML = "";
items.forEach(item => {
const li = document.createElement("li");
li.innerHTML = `
<strong>${item.name}</strong>: ${item.description}
<button onclick="deleteItem(${item.id})">Delete</button>
<button onclick="editItem(${item.id}, '${item.name}', '${item.description}')">Edit</button>
`;
list.appendChild(li);
});
}
async function createItem() {
const name = document.getElementById("name").value;
const description = document.getElementById("description").value;
await fetch(`${API_BASE}/items/`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, description })
});
document.getElementById("name").value = "";
document.getElementById("description").value = "";
fetchItems();
}
async function deleteItem(id) {
await fetch(`${API_BASE}/items/${id}`, { method: "DELETE" });
fetchItems();
}
function editItem(id, currentName, currentDesc) {
const newName = prompt("New name:", currentName);
const newDesc = prompt("New description:", currentDesc);
if (newName && newDesc) {
updateItem(id, newName, newDesc);
}
}
async function updateItem(id, name, description) {
await fetch(`${API_BASE}/items/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, description })
});
fetchItems();
}
fetchItems();
</script>
</body>
</html>

65
main.py
View File

@@ -1,20 +1,28 @@
from fastapi import FastAPI, Depends, HTTPException
from fastapi_versioning import VersionedFastAPI, version
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from sqlalchemy.exc import NoResultFound
from pydantic import BaseModel
from typing import List
from models import Base, Item as ItemModel
from database import engine, SessionLocal
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi_versioning import VersionedFastAPI
from fastapi_versioning import version
app = FastAPI()
# Create tables
@app.on_event("startup")
async def on_startup():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
# Pydantic Schemas
class ItemCreate(BaseModel):
name: str
description: str = None
@@ -25,31 +33,76 @@ class ItemRead(ItemCreate):
class Config:
orm_mode = True
# Dependency
async def get_session() -> AsyncSession:
async with SessionLocal() as session:
yield session
@app.get("/")
@version(1)
def read_root():
return "TODO app"
return "Items app"
@app.get("/")
@version(2)
def read_root():
return "Items v2 app"
@app.post("/items/", response_model=ItemRead)
@version(1)
async def create_item(item: ItemCreate, session: AsyncSession = Depends(get_session)):
return "todo"
db_item = ItemModel(name=item.name, description=item.description)
session.add(db_item)
await session.commit()
await session.refresh(db_item)
return db_item
@app.get("/items/", response_model=List[ItemRead])
@version(1)
async def read_items(session: AsyncSession = Depends(get_session)):
result = await session.execute(select(ItemModel))
return result.scalars().all()
@app.get("/items/{item_id}", response_model=ItemRead)
@version(1)
async def read_item(item_id: int, session: AsyncSession = Depends(get_session)):
return "todo"
result = await session.execute(select(ItemModel).where(ItemModel.id == item_id))
item = result.scalar_one_or_none()
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
@app.put("/items/{item_id}", response_model=ItemRead)
@version(1)
async def update_item(item_id: int, item: ItemCreate, session: AsyncSession = Depends(get_session)):
return "todo"
result = await session.execute(select(ItemModel).where(ItemModel.id == item_id))
db_item = result.scalar_one_or_none()
if not db_item:
raise HTTPException(status_code=404, detail="Item not found")
db_item.name = item.name
db_item.description = item.description
await session.commit()
await session.refresh(db_item)
return db_item
@app.delete("/items/{item_id}")
@version(1)
async def delete_item(item_id: int, session: AsyncSession = Depends(get_session)):
return "todo"
result = await session.execute(select(ItemModel).where(ItemModel.id == item_id))
db_item = result.scalar_one_or_none()
if not db_item:
raise HTTPException(status_code=404, detail="Item not found")
await session.delete(db_item)
await session.commit()
return {"detail": "Item deleted"}
app = VersionedFastAPI(app, version_format='{major}', prefix_format='/v{major}')
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.mount("/", StaticFiles(directory=".", html=True), name="static")

View File

@@ -2,3 +2,4 @@ fastapi
uvicorn[standard]
sqlalchemy>=2.0
aiosqlite
fastapi-versioning

BIN
test.db

Binary file not shown.