Skip to content

Commit 3a4367e

Browse files
authored
Merge pull request #139 from grillazz/refactor
Refactor database url
2 parents 8f5c489 + 053fbe0 commit 3a4367e

File tree

5 files changed

+89
-7
lines changed

5 files changed

+89
-7
lines changed

.env

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@ SQL_TEST_DB=testdb
66
SQL_HOST=db
77
SQL_USER=user
88
SQL_PASS=secret
9-
SQL_URL=postgresql+asyncpg://${SQL_USER}:${SQL_PASS}@${SQL_HOST}/${SQL_DB}
9+
#SQL_URL=postgresql+asyncpg://${SQL_USER}:${SQL_PASS}@${SQL_HOST}/${SQL_DB}
1010

11+
# Postgres
12+
POSTGRES_SERVER=db
13+
POSTGRES_PORT=5432
14+
POSTGRES_DB=devdb
15+
POSTGRES_TEST_DB=testdb
16+
POSTGRES_USER=user
17+
POSTGRES_PASSWORD=secret
18+
19+
# Redis
1120
REDIS_HOST=redis
1221
REDIS_PORT=6379
1322
REDIS_DB=2

.github/workflows/build-and-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
SQL_USER: app-user
2424
POSTGRES_PASSWORD: secret
2525
PGPASSWORD: secret
26-
SQL_URL: postgresql+asyncpg://app-user:secret@localhost:5432/testdb
26+
# SQL_URL: postgresql+asyncpg://app-user:secret@localhost:5432/testdb
2727
REDIS_HOST: 127.0.0.1
2828
REDIS_PORT: 6379
2929
REDIS_DB: 2

app/api/nonsense.py

+41
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,44 @@ async def import_nonsense(
107107
finally:
108108
# Ensure that the database session is closed, regardless of whether an error occurred or not
109109
await db_session.close()
110+
111+
112+
# TODO: add websocket to full text search postgres database for nonsense description
113+
114+
# 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:
115+
#
116+
# 1. Install the `websockets` library if you haven't done so already.
117+
# 2. Create a new WebSocket route in your FastAPI application.
118+
# 3. In the WebSocket route, accept a search query from the client.
119+
# 4. Use the search query to perform a full text search on the `nonsense` table in your PostgreSQL database.
120+
# 5. Send the search results back to the client through the WebSocket connection.
121+
#
122+
# Here's how you can implement this:
123+
#
124+
# ```python
125+
# import websockets
126+
# from fastapi import WebSocket
127+
# from sqlalchemy import text
128+
#
129+
# router = APIRouter()
130+
#
131+
# @router.websocket("/ws/nonsense")
132+
# async def websocket_endpoint(websocket: WebSocket):
133+
# await websocket.accept()
134+
# while True:
135+
# data = await websocket.receive_text()
136+
# query = text(f"""
137+
# SELECT * FROM nonsense
138+
# WHERE to_tsvector('english', description) @@ plainto_tsquery('english', :q)
139+
# """)
140+
# result = await db_session.execute(query, {"q": data})
141+
# await websocket.send_json(result.fetchall())
142+
# # ```
143+
#
144+
# 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.
145+
#
146+
# 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.
147+
#
148+
149+
# TODO: https://medium.com/@amitosh/full-text-search-fts-with-postgresql-and-sqlalchemy-edc436330a0c
150+
# TODO: https://www.postgresql.org/docs/13/textsearch-intro.html

app/config.py

+37-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,48 @@
11
import os
22

3-
from pydantic import PostgresDsn, RedisDsn
4-
from pydantic_settings import BaseSettings
3+
from pydantic import PostgresDsn, RedisDsn, computed_field
4+
from pydantic_core import MultiHostUrl
5+
from pydantic_settings import BaseSettings, SettingsConfigDict
56

67

78
class Settings(BaseSettings):
8-
asyncpg_url: PostgresDsn = os.getenv("SQL_URL")
9+
model_config = SettingsConfigDict(
10+
env_file=".env",
11+
env_ignore_empty=True,
12+
extra="ignore"
13+
)
914
redis_url: RedisDsn = os.getenv("REDIS_URL")
1015
jwt_algorithm: str = os.getenv("JWT_ALGORITHM")
1116
jwt_expire: int = os.getenv("JWT_EXPIRE")
1217

18+
SQL_USER: str
19+
SQL_PASS: str
20+
SQL_HOST: str
21+
SQL_DB: str
22+
23+
@computed_field
24+
@property
25+
def asyncpg_url(self) -> PostgresDsn:
26+
"""
27+
This is a computed field that generates a PostgresDsn URL for asyncpg.
28+
29+
The URL is built using the MultiHostUrl.build method, which takes the following parameters:
30+
- scheme: The scheme of the URL. In this case, it is "postgresql+asyncpg".
31+
- username: The username for the SQL database, retrieved from the SQL_USER environment variable.
32+
- password: The password for the SQL database, retrieved from the SQL_PASS environment variable.
33+
- host: The host of the SQL database, retrieved from the SQL_HOST environment variable.
34+
- path: The path of the SQL database, retrieved from the SQL_DB environment variable.
35+
36+
Returns:
37+
PostgresDsn: The constructed PostgresDsn URL for asyncpg.
38+
"""
39+
return MultiHostUrl.build(
40+
scheme="postgresql+asyncpg",
41+
username=self.SQL_USER,
42+
password=self.SQL_PASS,
43+
host=self.SQL_HOST,
44+
path=self.SQL_DB,
45+
)
46+
1347

1448
settings = Settings()

db/create.sql

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
DROP DATABASE IF EXISTS devdb;
2-
CREATE DATABASE devdb;
31
\connect devdb;
42
CREATE SCHEMA shakespeare;
53
CREATE SCHEMA happy_hog;

0 commit comments

Comments
 (0)