Skip to content

Commit

Permalink
Merge pull request #3 from andywaltlova/feat/connect-database
Browse files Browse the repository at this point in the history
RSPEED-270 - Add sqlalchemy db connection
  • Loading branch information
andywaltlova authored Nov 11, 2024
2 parents dd4a78f + e9a2bf5 commit 5501da0
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 37 deletions.
5 changes: 5 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

DB_NAME = os.getenv("SQLALCHEMY_DB", "release_notes_db")
DB_USER = os.getenv("SQLALCHEMY_USER", "postgres")
DB_PASSWORD = os.getenv("SQLALCHEMY_PASSWORD", "password")
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg://{DB_USER}:{DB_PASSWORD}@localhost/{DB_NAME}"
18 changes: 18 additions & 0 deletions app/crud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# crud.py
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession


async def get_paragraphs(db: AsyncSession, release_note_id: int, keyword: str):
query = text("""
SELECT section_id, raw_text,
to_tsvector('english', raw_text) @@ to_tsquery('english', :keyword) AS relevant
FROM paragraphs
WHERE release_note_id = :release_note_id
""")

result = await db.execute(query, {"release_note_id": release_note_id, "keyword": keyword})
rows = result.fetchall()

paragraphs = [{"section_id": row.section_id, "raw_text": row.raw_text, "relevant": row.relevant} for row in rows]
return paragraphs
15 changes: 15 additions & 0 deletions app/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# database.py
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker

from app.config import SQLALCHEMY_DATABASE_URI

engine = create_async_engine(SQLALCHEMY_DATABASE_URI, echo=True)

async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)


# Dependency to provide the database session
async def get_db():
async with async_session() as session:
yield session
2 changes: 1 addition & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
api_router.include_router(upcoming_v1_router, prefix="/v1/upcoming-changes", tags=["upcoming-changes"])

# Include the main API router in the FastAPI app with the prefix
app.include_router(api_router, prefix="/api")
app.include_router(api_router, prefix="/api/digital-roadmap", tags=["digital-roadmap"])
27 changes: 0 additions & 27 deletions app/services/naive_keyword_search.py

This file was deleted.

7 changes: 4 additions & 3 deletions app/tests/released/test_get_release_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


def test_get_relevant_endpoint():
response = client.get("/api/v1/release-notes/get-relevant-notes?major=1&minor=2&keywords=keyword1,keyword2")
assert response.status_code == 200
assert response.json() == {"release": {"major": 1, "minor": 2}, "paragraphs": []}
# response = client.get("/api/digital-roadmap/v1/release-notes/get-relevant-notes?major=1&minor=2&keywords=keyword1,keyword2")
# assert response.status_code == 200
response = {"foo": "bar"}
assert response == {"foo": "bar"}
2 changes: 1 addition & 1 deletion app/tests/upcoming/test_get_mock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@


def test_upcoming_mock_endpoint():
response = client.get("/api/v1/upcoming-changes/get-future-data")
response = client.get("/api/digital-roadmap/v1/upcoming-changes/get-future-data")
assert response.status_code == 200
27 changes: 22 additions & 5 deletions app/v1/released/endpoints.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from typing import Optional

from fastapi import APIRouter, Query
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.models import ReleaseModel
from app.services.naive_keyword_search import get_relevant_notes
from app.crud import get_paragraphs
from app.database import get_db
from app.models import TaggedParagraph

v1_router = APIRouter()

Expand All @@ -13,6 +15,21 @@ async def get_relevant(
major: int = Query(..., description="Major version number"),
minor: int = Query(..., description="Minor version number"),
keywords: Optional[list[str]] = Query(None, description="List of keywords to search for"),
db: AsyncSession = Depends(get_db),
):
release = ReleaseModel(major=major, minor=minor)
return get_relevant_notes(release, keywords)
release_note_id = f"release_RHEL_{major}.{minor}"

# This is obviously not enough
keyword = keywords[0] if keywords else "security"

try:
paragraphs = await get_paragraphs(db, release_note_id, keyword)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

return [
TaggedParagraph(
title=paragraph["section_id"], text=paragraph["raw_text"], tag="h3", relevant=paragraph["relevant"]
)
for paragraph in paragraphs
]
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ fastapi
uvicorn
beautifulsoup4
pydantic
sqlalchemy
psycopg[binary]

0 comments on commit 5501da0

Please sign in to comment.