Skip to content

Commit 147e529

Browse files
committed
Update pre-commit configuration, enhance README, add CLI for config display, and update dependencies
1 parent 091f9f9 commit 147e529

File tree

6 files changed

+71
-46
lines changed

6 files changed

+71
-46
lines changed

.pre-commit-config.yaml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
\
21
# See https://pre-commit.com for more information
32
# See https://pre-commit.com/hooks.html for more hooks
43
repos:
5-
- repo: https://github.com/astral-sh/ruff-pre-commit
6-
# Ruff version.
7-
rev: v0.5.5
4+
- repo: https://github.com/pre-commit/pre-commit-hooks
5+
rev: v4.6.0 # Use a recent version
86
hooks:
9-
# Run the linter.
10-
- id: ruff
11-
args: [--fix]
12-
# Run the formatter.
13-
- id: ruff-format
7+
- id: trailing-whitespace
8+
- id: end-of-file-fixer
9+
- id: check-yaml
10+
- id: check-toml
11+
- id: check-added-large-files

README.md

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# FastAPI User Authentication API
22

3-
[![Python Version][python-shield]][python-url]
4-
[![FastAPI Version][fastapi-shield]][fastapi-url]
5-
[![Code style: ruff][ruff-shield]][ruff-url]
6-
[![Tests][tests-shield]][tests-url]
7-
[![Coverage][coverage-shield]][coverage-url]
3+
[![CI Pipeline](https://github.com/nim444/fastapi-auth-multi-db/actions/workflows/ci.yml/badge.svg)](https://github.com/nim444/fastapi-auth-multi-db/actions/workflows/ci.yml)
4+
[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/)
5+
[![FastAPI >=0.115](https://img.shields.io/badge/fastapi->=0.115-green.svg)](https://fastapi.tiangolo.com/)
6+
[![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7+
[![Tests passing](https://img.shields.io/badge/Tests-passing-brightgreen.svg)](#running-tests)
8+
[![Coverage: 100%](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg)](https://codecov.io/gh/nim444/fastapi-auth-multi-db) <!-- Assuming Codecov is setup -->
89

9-
A robust FastAPI application demonstrating user registration, JWT authentication, and a flexible repository pattern supporting SQLite, PostgreSQL, and MongoDB backends.
10+
A robust FastAPI application demonstrating user registration, JWT authentication (including refresh tokens), and a flexible repository pattern supporting SQLite, PostgreSQL, and MongoDB backends.
1011

1112
## Purpose
1213

@@ -21,12 +22,13 @@ This project serves as a template or starting point for building secure and scal
2122

2223
* JWT-based authentication (login, refresh tokens).
2324
* User registration with password hashing (bcrypt) and validation.
24-
* Protected user profile endpoint.
25+
* Protected user profile endpoint (`/users/me`).
2526
* Flexible database layer using the Repository Pattern.
26-
* Configuration management with `Dynaconf` (`settings.toml`, `.secrets.toml`, environment variables).
27+
* Configuration management with `Dynaconf` (`settings.toml`, `.secrets.toml`, environment variables with `FAPI_` prefix).
2728
* Asynchronous support throughout (FastAPI, database drivers).
2829
* Automated API documentation (Swagger UI & ReDoc).
29-
* Comprehensive test suite with `pytest`.
30+
* Comprehensive test suite with `pytest` (including coverage).
31+
* Health check endpoint (`/health`).
3032

3133
## Technology Stack
3234

@@ -35,8 +37,9 @@ This project serves as a template or starting point for building secure and scal
3537
* **Authentication:** python-jose (JWT), passlib, bcrypt
3638
* **Database ORM/Driver:**
3739
* SQLAlchemy (>=2.0.40) for SQL databases
38-
* Motor (via `mongodb_repository.py`, requires separate install if used) for MongoDB
40+
* Motor (>=3.5.0, via `mongodb_repository.py`, requires separate install if used) for MongoDB
3941
* Psycopg2 (requires separate install if using PostgreSQL)
42+
* aiosqlite (>=0.20.0, requires separate install if using async SQLite `sqlite+aiosqlite`)
4043
* **Configuration:** Dynaconf (>=3.2.0)
4144
* **Testing:** pytest, pytest-asyncio, pytest-cov, httpx
4245
* **Dependency Management:** uv
@@ -94,10 +97,11 @@ This project serves as a template or starting point for building secure and scal
9497
# Install DB-specific drivers if needed (not included by default)
9598
# uv pip install psycopg2-binary # For PostgreSQL
9699
# uv pip install motor # For MongoDB
100+
# uv pip install aiosqlite # For async SQLite
97101
```
98102

99103
4. **Configure Settings:**
100-
* Settings are managed by `Dynaconf`, loading from `config/settings.toml`, `config/.secrets.toml`, and environment variables.
104+
* Settings are managed by `Dynaconf`, loading from `config/settings.toml`, `config/.secrets.toml`, and environment variables (prefixed with `FAPI_`, e.g., `FAPI_DATABASE_TYPE`, `FAPI_JWT_SECRET_KEY`).
101105
* **Create `config/.secrets.toml`** by copying `config/.secrets.toml.example`. Add your `JWT_SECRET_KEY` (must be strong and secret). **Do not commit `.secrets.toml`**.
102106

103107
```toml
@@ -116,18 +120,11 @@ This project serves as a template or starting point for building secure and scal
116120
* If using MongoDB, set `mongo_db_name`.
117121

118122
5. **Initialize Database:**
119-
* **SQL (SQLite/PostgreSQL):** This project uses Alembic for migrations.
123+
* **SQL (SQLite/PostgreSQL):** This project includes `alembic` as a dependency for potential migrations.
120124
* Ensure your database exists.
121-
* Run migrations: `alembic upgrade head`
122-
* *(You might need to configure Alembic first if not already set up - check for an `alembic.ini` file and a `migrations/` directory)*
123-
* **MongoDB:** Ensure unique indexes are created for the `users` collection (username, email). This can be done manually or added to the application startup logic.
124-
125-
```javascript
126-
// Example in MongoDB shell:
127-
use your_db_name; // As defined in settings.toml (mongo_db_name)
128-
db.users.createIndex({ "username": 1 }, { unique: true });
129-
db.users.createIndex({ "email": 1 }, { unique: true });
130-
```
125+
* If you have Alembic migrations set up (e.g., `alembic.ini` file and a `migrations/` directory), run: `alembic upgrade head`
126+
* *(If Alembic is not fully configured, you may need to initialize it or manage schema changes manually)*
127+
* **MongoDB:** Ensure your MongoDB server is running. The application will automatically attempt to create the required unique indexes for the `users` collection (on `username` and `email`) when it starts up, using the database name specified by `mongo_db_name` in your settings.
131128

132129
## Running the Application
133130

@@ -162,6 +159,15 @@ PYTHONPATH=. pytest --cov=app --cov-report=term-missing --cov-report=html
162159

163160
Coverage report will be in the `htmlcov/` directory.
164161

162+
## Running GitHub Actions Locally (Optional)
163+
164+
If you have `act` installed, you can simulate GitHub Actions workflows locally. This is particularly useful for testing CI/CD pipelines before pushing changes.
165+
166+
```bash
167+
# Run workflows, specifying architecture if needed (e.g., for M1/M2 Macs)
168+
act --container-architecture linux/amd64
169+
```
170+
165171
## API Documentation
166172

167173
Once the server is running, access the interactive API documentation:
@@ -180,15 +186,3 @@ Once the server is running, access the interactive API documentation:
180186
4. If switching to SQL, ensure the database exists and migrations are applied (`alembic upgrade head`).
181187
5. If switching to MongoDB, ensure indexes exist.
182188
6. Restart the application: `uvicorn main:app --reload ...`
183-
184-
<!-- Badges Definitions (Update URLs as needed) -->
185-
[python-shield]: https://img.shields.io/badge/Python->=3.13-blue.svg
186-
[python-url]: https://www.python.org/downloads/
187-
[fastapi-shield]: https://img.shields.io/badge/FastAPI->=0.115-green.svg
188-
[fastapi-url]: https://fastapi.tiangolo.com/
189-
[ruff-shield]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
190-
[ruff-url]: https://github.com/astral-sh/ruff
191-
[tests-shield]: https://img.shields.io/badge/Tests-passing-brightgreen.svg
192-
[tests-url]: #running-tests <!-- Link to test section -->
193-
[coverage-shield]: https://img.shields.io/badge/Coverage-100%25-brightgreen.svg
194-
[coverage-url]: #running-tests <!-- Link to test section -->

app/cli.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# filepath: /Users/nk/Projects/_/fapi/app/cli.py
2+
import typer
3+
4+
from app.core.config import settings
5+
6+
app = typer.Typer()
7+
8+
9+
@app.command()
10+
def show_config():
11+
"""Display the current configuration settings."""
12+
print("Current Configuration:")
13+
print(f" Database Type: {settings.database_type}")
14+
print(f" SQL Database URL: {settings.get('sql_database_url', 'Not Set')}")
15+
print(f" Mongo Database URL: {settings.get('mongo_database_url', 'Not Set')}")
16+
print(f" Mongo DB Name: {settings.get('mongo_db_name', 'Not Set')}")
17+
print(f" JWT Secret Key: {'Set' if settings.get('jwt_secret_key') else 'Not Set'}")
18+
19+
20+
# Add more commands here as needed
21+
# Example:
22+
# @app.command()
23+
# def create_user(username: str, email: str, password: str):
24+
# """Create a new user (requires async handling or separate logic)."""
25+
# print(f"Creating user {username} (implementation needed)")
26+
27+
28+
if __name__ == "__main__":
29+
app()

config/settings.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ database_type = "mongodb" # Options: sqlite, postgres, mongodb
1010
# --- SQL Databases (SQLite, PostgreSQL) ---
1111
sql_database_url = "sqlite:///./test.db" # Keep a default even if unused
1212

13-
# --- MongoDB ---
13+
# --- MongoDB ---
1414
# Add MONGO_DATABASE_URL to .secrets.toml if it contains credentials
1515
# Example: MONGO_DATABASE_URL = "mongodb://user:password@localhost:27017/"
1616
# If no auth: MONGO_DATABASE_URL = "mongodb://localhost:27017/"
@@ -33,4 +33,4 @@ reload = false
3333
# Example for MongoDB in production:
3434
# database_type = "mongodb"
3535
# mongo_database_url = "mongodb://prod_user:prod_password@prod_host:27017/"
36-
# mongo_db_name = "prod_fastapi_db"
36+
# mongo_db_name = "prod_fastapi_db"

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies = [
1515
"python-multipart>=0.0.6",
1616
"dynaconf>=3.2.0",
1717
"httpx>=0.28.1",
18+
"typer[all]>=0.12.5", # Add typer
1819
]
1920

2021
[project.optional-dependencies]
@@ -58,3 +59,6 @@ line-ending = "auto"
5859
where = ["."]
5960
include = ["app*"]
6061
exclude = ["tests*"]
62+
63+
[project.scripts]
64+
fapi-cli = "app.cli:app" # Add script entry point

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def db_session(test_engine):
3232

3333

3434
@pytest.fixture(autouse=True)
35-
def override_get_repository(db_session):
35+
def _override_get_repository(db_session):
3636
def _get_repo_override():
3737
return SQLAlchemyRepository(db_session)
3838

0 commit comments

Comments
 (0)