Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor database url #139

Merged
merged 3 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ SQL_TEST_DB=testdb
SQL_HOST=db
SQL_USER=user
SQL_PASS=secret
SQL_URL=postgresql+asyncpg://${SQL_USER}:${SQL_PASS}@${SQL_HOST}/${SQL_DB}
#SQL_URL=postgresql+asyncpg://${SQL_USER}:${SQL_PASS}@${SQL_HOST}/${SQL_DB}

# Postgres
POSTGRES_SERVER=db
POSTGRES_PORT=5432
POSTGRES_DB=devdb
POSTGRES_TEST_DB=testdb
POSTGRES_USER=user
POSTGRES_PASSWORD=secret

# Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
SQL_USER: app-user
POSTGRES_PASSWORD: secret
PGPASSWORD: secret
SQL_URL: postgresql+asyncpg://app-user:secret@localhost:5432/testdb
# SQL_URL: postgresql+asyncpg://app-user:secret@localhost:5432/testdb
REDIS_HOST: 127.0.0.1
REDIS_PORT: 6379
REDIS_DB: 2
Expand Down
41 changes: 41 additions & 0 deletions app/api/nonsense.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,44 @@ async def import_nonsense(
finally:
# Ensure that the database session is closed, regardless of whether an error occurred or not
await db_session.close()


# TODO: add websocket to full text search postgres database for nonsense description

# To add a WebSocket to full text search a PostgreSQL database for the `nonsense` description, you can use the `websockets` library in Python. Here's a step-by-step plan:
#
# 1. Install the `websockets` library if you haven't done so already.
# 2. Create a new WebSocket route in your FastAPI application.
# 3. In the WebSocket route, accept a search query from the client.
# 4. Use the search query to perform a full text search on the `nonsense` table in your PostgreSQL database.
# 5. Send the search results back to the client through the WebSocket connection.
#
# Here's how you can implement this:
#
# ```python
# import websockets
# from fastapi import WebSocket
# from sqlalchemy import text
#
# router = APIRouter()
#
# @router.websocket("/ws/nonsense")
# async def websocket_endpoint(websocket: WebSocket):
# await websocket.accept()
# while True:
# data = await websocket.receive_text()
# query = text(f"""
# SELECT * FROM nonsense
# WHERE to_tsvector('english', description) @@ plainto_tsquery('english', :q)
# """)
# result = await db_session.execute(query, {"q": data})
# await websocket.send_json(result.fetchall())
# # ```
#
# This code creates a new WebSocket route at `/ws/nonsense`. When a client connects to this route and sends a message, the message is used as a search query in a full text search on the `nonsense` table. The search results are then sent back to the client through the WebSocket connection.
#
# Please note that this is a basic implementation and might need adjustments based on your specific needs. For example, you might want to add error handling, handle disconnections, or format the search results before sending them back to the client.
#

# TODO: https://medium.com/@amitosh/full-text-search-fts-with-postgresql-and-sqlalchemy-edc436330a0c
# TODO: https://www.postgresql.org/docs/13/textsearch-intro.html
40 changes: 37 additions & 3 deletions app/config.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,48 @@
import os

from pydantic import PostgresDsn, RedisDsn
from pydantic_settings import BaseSettings
from pydantic import PostgresDsn, RedisDsn, computed_field
from pydantic_core import MultiHostUrl
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
asyncpg_url: PostgresDsn = os.getenv("SQL_URL")
model_config = SettingsConfigDict(
env_file=".env",
env_ignore_empty=True,
extra="ignore"
)
redis_url: RedisDsn = os.getenv("REDIS_URL")
jwt_algorithm: str = os.getenv("JWT_ALGORITHM")
jwt_expire: int = os.getenv("JWT_EXPIRE")

SQL_USER: str
SQL_PASS: str
SQL_HOST: str
SQL_DB: str

@computed_field
@property
def asyncpg_url(self) -> PostgresDsn:
"""
This is a computed field that generates a PostgresDsn URL for asyncpg.

The URL is built using the MultiHostUrl.build method, which takes the following parameters:
- scheme: The scheme of the URL. In this case, it is "postgresql+asyncpg".
- username: The username for the SQL database, retrieved from the SQL_USER environment variable.
- password: The password for the SQL database, retrieved from the SQL_PASS environment variable.
- host: The host of the SQL database, retrieved from the SQL_HOST environment variable.
- path: The path of the SQL database, retrieved from the SQL_DB environment variable.

Returns:
PostgresDsn: The constructed PostgresDsn URL for asyncpg.
"""
return MultiHostUrl.build(
scheme="postgresql+asyncpg",
username=self.SQL_USER,
password=self.SQL_PASS,
host=self.SQL_HOST,
path=self.SQL_DB,
)


settings = Settings()
2 changes: 0 additions & 2 deletions db/create.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
DROP DATABASE IF EXISTS devdb;
CREATE DATABASE devdb;
\connect devdb;
CREATE SCHEMA shakespeare;
CREATE SCHEMA happy_hog;
Expand Down
Loading