diff --git a/.gitignore b/.gitignore
index 9aaeae7..1bbc918 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
app/__pycache__
+__pycache__
+.pytest_cache/
venv/
-test.txt
\ No newline at end of file
+test.txt
+diff.txt
\ No newline at end of file
diff --git a/README.md b/README.md
index 507a444..cf24f59 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ source venv/bin/activate
## Run locally
```bash
-uvicorn app.main:app --reload
+python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
Then check:
http://127.0.0.1:8000
@@ -23,5 +23,5 @@ http://127.0.0.1:8000/shorten
```bash
PYTHONPATH=./ pytest
export PYTHONPATH=$(pwd)
-pytest
+python -m pytest --cov=app --cov-report=term-missing
```
\ No newline at end of file
diff --git a/app/core/config.py b/app/core/config.py
index f55452d..54c8793 100644
--- a/app/core/config.py
+++ b/app/core/config.py
@@ -1,36 +1,38 @@
# app/core/config.py
from functools import lru_cache
-from pydantic_settings import BaseSettings, SettingsConfigDict
+from pydantic import BaseSettings
+from typing import List
class Settings(BaseSettings):
- # App
- app_name: str = "URL Shortener API"
- debug: bool = False
+ app_name: str = "URL Shortener"
+ allowed_hosts: List[str] = ["*"]
+ database_url: str
- # Server
+ # Server settings
host: str = "0.0.0.0"
port: int = 8000
base_url: str = "http://localhost:8000"
- # Database
- database_url: str = "sqlite:///./urls.db"
-
+ # Debug flag
+ debug: bool = True
+
# Optional future extensions
- allowed_hosts: list[str] = ["*"]
rate_limit_per_minute: int = 60
- model_config = SettingsConfigDict(
- env_file=".env",
- env_file_encoding="utf-8",
- case_sensitive=False,
- extra="ignore",
- )
+ class Config:
+ env_file = ".env"
+ env_file_encoding = "utf-8"
+ case_sensitive = False
+ extra = "ignore"
-@lru_cache
+
+# Cached singleton-style access
+@lru_cache()
def get_settings() -> Settings:
return Settings()
-# Singleton-style access
+
+# Global settings instance
settings = get_settings()
\ No newline at end of file
diff --git a/app/db/models.py b/app/db/models.py
index 207dc07..f3c37e5 100644
--- a/app/db/models.py
+++ b/app/db/models.py
@@ -4,7 +4,7 @@ from sqlalchemy import String, Integer, DateTime, func, Index
from sqlalchemy.orm import Mapped, mapped_column
from datetime import datetime
from app.db.base import Base
-
+from typing import Optional
class URL(Base):
__tablename__ = "urls"
@@ -40,7 +40,7 @@ class URL(Base):
nullable=False
)
- last_accessed: Mapped[datetime | None] = mapped_column(
+ last_accessed: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True),
nullable=True
)
diff --git a/app/services/url_service.py b/app/services/url_service.py
index f537085..7c2300d 100644
--- a/app/services/url_service.py
+++ b/app/services/url_service.py
@@ -9,7 +9,6 @@ from app.db.models import URL
from app.utils.short_code import generate_short_code
from app.core.config import settings
-
SHORT_CODE_LENGTH = 6
MAX_GENERATION_ATTEMPTS = 5
diff --git a/app/test_main.py b/app/test_main.py
index 9355bf4..bfe170a 100644
--- a/app/test_main.py
+++ b/app/test_main.py
@@ -4,7 +4,7 @@ import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from app.main import app
-from app import settings
+from app.core.config import settings
import tempfile
import pytest
diff --git a/app/utils/__init__.py b/app/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/app/utils/short_code.py b/app/utils/short_code.py
new file mode 100644
index 0000000..54cc355
--- /dev/null
+++ b/app/utils/short_code.py
@@ -0,0 +1,8 @@
+# app/utils/short_code.py
+import string
+import random
+
+def generate_short_code(length: int = 6) -> str:
+ """Generate a random alphanumeric short code."""
+ chars = string.ascii_letters + string.digits
+ return ''.join(random.choices(chars, k=length))
\ No newline at end of file
diff --git a/test.db b/test.db
new file mode 100644
index 0000000..efee9ea
Binary files /dev/null and b/test.db differ