Karan6124 commited on
Commit
c39e06c
·
1 Parent(s): dc69d08

feat: implement configuration and database session setup for NeonDB and Redis

Browse files
backend/app/config/settings.py CHANGED
@@ -1 +1,40 @@
1
- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+ from pydantic import Field
3
+
4
+ class Settings(BaseSettings):
5
+ PROJECT_NAME: str= "QuantIQ"
6
+ API_V1_STR: str= "/api/v1"
7
+
8
+ # Required environment variables (must be present in your .env file)
9
+ DATABASE_URL: str
10
+ REDIS_URL: str
11
+ GEMINI_API_KEY: str
12
+
13
+ # Optional Razorpay Credentials (defaults to empty string if not set)
14
+ RAZORPAY_KEY_ID: str= Field(default="")
15
+ RAZORPAY_KEY_SECRET: str= Field(default="")
16
+ RAZORPAY_WEBHOOK_SECRET: str= Field(default="")
17
+
18
+ # Auth configuration
19
+ SECRET_KEY: str= Field(default="supersecretkeychangeinproduction")
20
+ ACCESS_TOKEN_EXPIRE_MINUTES: int= 60*24*8
21
+
22
+ @property
23
+ def database_url_async(self) -> str:
24
+ """
25
+ Ensures the database URL uses the asyncpg driver dialect.
26
+ Converts 'postgresql://' to 'postgresql+asyncpg://'
27
+ """
28
+ url= self.DATABASE_URL
29
+ if url.startswith("postgresql://"):
30
+ return url.replace("postgresql://", "postgresql+asyncpg://", 1)
31
+ return url
32
+
33
+ model_config= SettingsConfigDict(
34
+ env_file=".env",
35
+ env_file_encoding="utf-8",
36
+ case_sensitive=True,
37
+ extra="ignore"
38
+ )
39
+
40
+ settings= Settings()
backend/app/database/session.py CHANGED
@@ -1 +1,31 @@
1
- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
2
+ from sqlalchemy.orm import DeclarativeBase
3
+ from backend.app.config.settings import settings
4
+
5
+ # Create async engine for Postgres using the resolved async URL
6
+ engine= create_async_engine(
7
+ settings.database_url_async,
8
+ echo= False,
9
+ future= True
10
+ )
11
+
12
+ # Create session factory
13
+ SessionLocal= async_sessionmaker(
14
+ bind= engine,
15
+ autocommit= False,
16
+ autoflush= False,
17
+ expire_on_commit= False,
18
+ class_= AsyncSession
19
+ )
20
+
21
+ # Declarative base for SQLAlchemy models
22
+ class Base(DeclarativeBase):
23
+ pass
24
+
25
+ # Dependency to retrieve a database session for requests
26
+ async def get_db():
27
+ async with SessionLocal() as session:
28
+ try:
29
+ yield session
30
+ finally:
31
+ await session.close()
pyproject.toml CHANGED
@@ -19,4 +19,6 @@ dependencies = [
19
  "google-generativeai>=0.4.1",
20
  "pydantic-settings>=2.2.1",
21
  "prometheus-fastapi-instrumentator>=7.0.0",
 
 
22
  ]
 
19
  "google-generativeai>=0.4.1",
20
  "pydantic-settings>=2.2.1",
21
  "prometheus-fastapi-instrumentator>=7.0.0",
22
+ "razorpay>=1.4.1",
23
+ "httpx>=0.27.0",
24
  ]
uv.lock CHANGED
@@ -644,6 +644,19 @@ wheels = [
644
  { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
645
  ]
646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  [[package]]
648
  name = "httplib2"
649
  version = "0.31.2"
@@ -692,6 +705,21 @@ wheels = [
692
  { url = "https://files.pythonhosted.org/packages/48/63/b906c01e53f50d432c0defe43ce52764a111dc1bdd028bafbeb54dcfd008/httptools-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77", size = 108209, upload-time = "2026-05-25T22:17:39.473Z" },
693
  ]
694
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695
  [[package]]
696
  name = "idna"
697
  version = "3.18"
@@ -1481,12 +1509,14 @@ dependencies = [
1481
  { name = "asyncpg" },
1482
  { name = "fastapi" },
1483
  { name = "google-generativeai" },
 
1484
  { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" },
1485
  { name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" },
1486
  { name = "pandas-ta" },
1487
  { name = "prometheus-fastapi-instrumentator" },
1488
  { name = "psycopg2-binary" },
1489
  { name = "pydantic-settings" },
 
1490
  { name = "redis" },
1491
  { name = "sqlalchemy", extra = ["mypy"] },
1492
  { name = "uvicorn", extra = ["standard"] },
@@ -1500,11 +1530,13 @@ requires-dist = [
1500
  { name = "asyncpg", specifier = ">=0.29.0" },
1501
  { name = "fastapi", specifier = ">=0.110.0" },
1502
  { name = "google-generativeai", specifier = ">=0.4.1" },
 
1503
  { name = "pandas", specifier = ">=2.2.1" },
1504
  { name = "pandas-ta", specifier = ">=0.3.14b0" },
1505
  { name = "prometheus-fastapi-instrumentator", specifier = ">=7.0.0" },
1506
  { name = "psycopg2-binary", specifier = ">=2.9.9" },
1507
  { name = "pydantic-settings", specifier = ">=2.2.1" },
 
1508
  { name = "redis", specifier = ">=5.0.3" },
1509
  { name = "sqlalchemy", extras = ["mypy"], specifier = ">=2.0.28" },
1510
  { name = "uvicorn", extras = ["standard"], specifier = ">=0.28.0" },
@@ -1512,6 +1544,18 @@ requires-dist = [
1512
  { name = "yfinance", specifier = ">=0.2.37" },
1513
  ]
1514
 
 
 
 
 
 
 
 
 
 
 
 
 
1515
  [[package]]
1516
  name = "redis"
1517
  version = "8.0.0"
 
644
  { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
645
  ]
646
 
647
+ [[package]]
648
+ name = "httpcore"
649
+ version = "1.0.9"
650
+ source = { registry = "https://pypi.org/simple" }
651
+ dependencies = [
652
+ { name = "certifi" },
653
+ { name = "h11" },
654
+ ]
655
+ sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
656
+ wheels = [
657
+ { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
658
+ ]
659
+
660
  [[package]]
661
  name = "httplib2"
662
  version = "0.31.2"
 
705
  { url = "https://files.pythonhosted.org/packages/48/63/b906c01e53f50d432c0defe43ce52764a111dc1bdd028bafbeb54dcfd008/httptools-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77", size = 108209, upload-time = "2026-05-25T22:17:39.473Z" },
706
  ]
707
 
708
+ [[package]]
709
+ name = "httpx"
710
+ version = "0.28.1"
711
+ source = { registry = "https://pypi.org/simple" }
712
+ dependencies = [
713
+ { name = "anyio" },
714
+ { name = "certifi" },
715
+ { name = "httpcore" },
716
+ { name = "idna" },
717
+ ]
718
+ sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
719
+ wheels = [
720
+ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
721
+ ]
722
+
723
  [[package]]
724
  name = "idna"
725
  version = "3.18"
 
1509
  { name = "asyncpg" },
1510
  { name = "fastapi" },
1511
  { name = "google-generativeai" },
1512
+ { name = "httpx" },
1513
  { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" },
1514
  { name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" },
1515
  { name = "pandas-ta" },
1516
  { name = "prometheus-fastapi-instrumentator" },
1517
  { name = "psycopg2-binary" },
1518
  { name = "pydantic-settings" },
1519
+ { name = "razorpay" },
1520
  { name = "redis" },
1521
  { name = "sqlalchemy", extra = ["mypy"] },
1522
  { name = "uvicorn", extra = ["standard"] },
 
1530
  { name = "asyncpg", specifier = ">=0.29.0" },
1531
  { name = "fastapi", specifier = ">=0.110.0" },
1532
  { name = "google-generativeai", specifier = ">=0.4.1" },
1533
+ { name = "httpx", specifier = ">=0.27.0" },
1534
  { name = "pandas", specifier = ">=2.2.1" },
1535
  { name = "pandas-ta", specifier = ">=0.3.14b0" },
1536
  { name = "prometheus-fastapi-instrumentator", specifier = ">=7.0.0" },
1537
  { name = "psycopg2-binary", specifier = ">=2.9.9" },
1538
  { name = "pydantic-settings", specifier = ">=2.2.1" },
1539
+ { name = "razorpay", specifier = ">=1.4.1" },
1540
  { name = "redis", specifier = ">=5.0.3" },
1541
  { name = "sqlalchemy", extras = ["mypy"], specifier = ">=2.0.28" },
1542
  { name = "uvicorn", extras = ["standard"], specifier = ">=0.28.0" },
 
1544
  { name = "yfinance", specifier = ">=0.2.37" },
1545
  ]
1546
 
1547
+ [[package]]
1548
+ name = "razorpay"
1549
+ version = "2.0.1"
1550
+ source = { registry = "https://pypi.org/simple" }
1551
+ dependencies = [
1552
+ { name = "requests" },
1553
+ ]
1554
+ sdist = { url = "https://files.pythonhosted.org/packages/d1/e4/877eb8ba68bb5212021b25a4f97b6c3f693e08bb6b319fc97c966c4391a3/razorpay-2.0.1.tar.gz", hash = "sha256:a766b9019e496c995906f75c31900bff8b2709bea251f1771925d742cba53e5b", size = 197169, upload-time = "2026-03-09T12:59:03.445Z" }
1555
+ wheels = [
1556
+ { url = "https://files.pythonhosted.org/packages/7f/35/e8fbf239cb16595007839408f7645bc952d8490f5dd50f9049434f296ce8/razorpay-2.0.1-py3-none-any.whl", hash = "sha256:e6a60c78203a3e1d3fc428e6fadf15bc67f75bd67217eaf9dc9925c87e98bc7a", size = 176920, upload-time = "2026-03-09T12:59:01.99Z" },
1557
+ ]
1558
+
1559
  [[package]]
1560
  name = "redis"
1561
  version = "8.0.0"