Skip to content

Commit 64c90d2

Browse files
committed
add an endpoint that writes to db
1 parent 12f792b commit 64c90d2

File tree

9 files changed

+146
-12
lines changed

9 files changed

+146
-12
lines changed

Taskfile.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ version: '3'
33
vars:
44
FRONTEND_DIR: frontend
55
BACKEND_DIR: backend
6+
PROD_HOST: vpsjim
7+
PROD_DB_PATH: ~/pingmaster/data/sql_app.db
68

79
tasks:
810
install:
@@ -96,4 +98,22 @@ tasks:
9698
desc: Arrête les conteneurs Docker
9799
dir: '{{.BACKEND_DIR}}'
98100
cmds:
99-
- docker-compose down
101+
- docker-compose down
102+
103+
db:download:
104+
desc: Download the production database
105+
cmds:
106+
- mkdir -p {{.BACKEND_DIR}}/data
107+
- scp {{.PROD_HOST}}:{{.PROD_DB_PATH}} {{.BACKEND_DIR}}/data/prod_db.db
108+
- echo "Production database downloaded to {{.BACKEND_DIR}}/data/prod_db.db"
109+
110+
db:view:
111+
desc: Open the downloaded production database in VS Code
112+
cmds:
113+
- code {{.BACKEND_DIR}}/data/prod_db.db
114+
115+
db:manage:
116+
desc: Download and view the production database
117+
cmds:
118+
- task: db:download
119+
- task: db:view
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from fastapi import APIRouter, Depends
2+
from sqlalchemy.orm import Session
3+
from app.db.session import get_db
4+
from app.db.models import Message
5+
from pydantic import BaseModel
6+
7+
router = APIRouter()
8+
9+
class MessageCreate(BaseModel):
10+
content: str
11+
12+
class MessageResponse(BaseModel):
13+
id: int
14+
content: str
15+
16+
class Config:
17+
from_attributes = True
18+
19+
@router.post("/messages/", response_model=MessageResponse, status_code=201)
20+
def create_message(
21+
message: MessageCreate,
22+
db: Session = Depends(get_db)
23+
):
24+
db_message = Message(content=message.content)
25+
db.add(db_message)
26+
db.commit()
27+
db.refresh(db_message)
28+
return db_message

backend/app/db/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from sqlalchemy import Column, Integer, String, DateTime
2+
from sqlalchemy.sql import func
3+
from .session import Base
4+
5+
class Message(Base):
6+
__tablename__ = "messages"
7+
8+
id = Column(Integer, primary_key=True, index=True)
9+
content = Column(String, nullable=False)
10+
created_at = Column(DateTime(timezone=True), server_default=func.now())

backend/app/db/session.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from sqlalchemy import create_engine
2+
from sqlalchemy.orm import sessionmaker, declarative_base
3+
4+
SQLITE_URL = "sqlite:///./sql_app.db"
5+
6+
engine = create_engine(SQLITE_URL)
7+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
8+
Base = declarative_base()
9+
10+
def get_db():
11+
db = SessionLocal()
12+
try:
13+
yield db
14+
finally:
15+
db.close()
16+
17+
def init_db():
18+
Base.metadata.create_all(bind=engine)

backend/app/main.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
from fastapi import FastAPI
2-
from app.api.endpoints import hello
2+
from app.api.endpoints import hello, messages
3+
from app.db.session import init_db
34

45
app = FastAPI(
56
title="MonitoringDashboard API",
67
description="Backend API for Monitoring Dashboard",
78
version="0.1.0"
89
)
910

10-
# Include routers
11-
app.include_router(hello.router, prefix="/api")
11+
@app.on_event("startup")
12+
def startup_event():
13+
init_db()
14+
15+
app.include_router(hello.router, prefix="/api")
16+
app.include_router(messages.router, prefix="/api")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from fastapi.testclient import TestClient
2+
3+
def test_create_message(client: TestClient):
4+
response = client.post(
5+
"/api/messages/",
6+
json={"content": "Test message"}
7+
)
8+
assert response.status_code == 201
9+
data = response.json()
10+
assert "id" in data
11+
assert data["content"] == "Test message"

backend/app/tests/conftest.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
11
import pytest
2+
from sqlalchemy import create_engine
3+
from sqlalchemy.orm import sessionmaker
24
from fastapi.testclient import TestClient
5+
from app.db.session import Base, get_db
36
from app.main import app
47

8+
SQLITE_TEST_URL = "sqlite:///./test.db"
9+
10+
@pytest.fixture
11+
def test_db():
12+
engine = create_engine(SQLITE_TEST_URL, connect_args={"check_same_thread": False})
13+
Base.metadata.create_all(bind=engine)
14+
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
15+
16+
def override_get_db():
17+
try:
18+
db = TestingSessionLocal()
19+
yield db
20+
finally:
21+
db.close()
22+
23+
app.dependency_overrides[get_db] = override_get_db
24+
yield TestingSessionLocal
25+
Base.metadata.drop_all(bind=engine)
26+
527
@pytest.fixture
6-
def client():
28+
def client(test_db):
729
return TestClient(app)

backend/pytest.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[pytest]
2+
markers =
3+
asyncio: mark a test as an asyncio test.

backend/requirements.txt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1-
fastapi>=0.104.0
2-
uvicorn>=0.24.0
3-
pytest>=7.4.3
4-
httpx>=0.25.1
5-
sqlalchemy>=2.0.23
6-
aiosqlite>=0.19.0
7-
python-dotenv>=1.0.0
1+
aiosqlite==0.20.0
2+
annotated-types==0.7.0
3+
anyio==4.6.2.post1
4+
certifi==2024.8.30
5+
click==8.1.7
6+
fastapi==0.115.6
7+
greenlet==3.1.1
8+
h11==0.14.0
9+
httpcore==1.0.7
10+
httpx==0.28.0
11+
idna==3.10
12+
iniconfig==2.0.0
13+
packaging==24.2
14+
pluggy==1.5.0
15+
pydantic==2.10.3
16+
pydantic_core==2.27.1
17+
pytest==8.3.4
18+
pytest-asyncio==0.24.0
19+
python-dotenv==1.0.1
20+
sniffio==1.3.1
21+
SQLAlchemy==2.0.36
22+
starlette==0.41.3
23+
typing_extensions==4.12.2
24+
uvicorn==0.32.1

0 commit comments

Comments
 (0)