Skip to content

Commit

Permalink
Merge pull request #34 from rafsaf/release-5.0
Browse files Browse the repository at this point in the history
Release 5.0
  • Loading branch information
rafsaf authored Nov 5, 2023
2 parents 91a3596 + c118cf6 commit 3cf67c9
Show file tree
Hide file tree
Showing 15 changed files with 887 additions and 991 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_docker_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.11"
python-version: "3.12"

- name: Generate projects from templates using cookiecutter
# minimal_project folder
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/manual_build_docker_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.11"
python-version: "3.12"

- name: Generate projects from templates using cookiecutter
# minimal_project folder
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.11"
python-version: "3.12"

# Below will create fresh template in path: minimal_project
- name: Generate project from template using cookiecutter
Expand Down Expand Up @@ -61,5 +61,5 @@ jobs:
TEST_DATABASE_DB: postgres
run: |
cd minimal_project
poetry run flake8 app --count --exit-zero --statistics
poetry run ruff app
poetry run coverage run -m pytest
33 changes: 12 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
<a href="https://minimal-fastapi-postgres-template.rafsaf.pl/" target="_blank">
<img src="https://img.shields.io/badge/live%20example-https%3A%2F%2Fminimal--fastapi--postgres--template.rafsaf.pl-blueviolet" alt="Live example">
</a>
<a href="https://github.com/rafsaf/minimal-fastapi-postgres-template/blob/main/LICENSE" target="_blank">
<img src="https://img.shields.io/github/license/rafsaf/minimal-fastapi-postgres-template" alt="License">
</a>
<a href="https://docs.python.org/3/whatsnew/3.11.html" target="_blank">
<img src="https://img.shields.io/badge/python-3.11-blue" alt="Python">
</a>
<a href="https://github.com/psf/black" target="_blank">
<img src="https://img.shields.io/badge/code%20style-black-lightgrey" alt="Black">
</a>
<a href="https://github.com/rafsaf/minimal-fastapi-postgres-template/actions/workflows/tests.yml" target="_blank">
<img src="https://github.com/rafsaf/minimal-fastapi-postgres-template/workflows/tests/badge.svg" alt="Tests">
</a>
[![Live example](https://img.shields.io/badge/live%20example-https%3A%2F%2Fminimal--fastapi--postgres--template.rafsaf.pl-blueviolet)](https://minimal-fastapi-postgres-template.rafsaf.pl/)
[![License](https://img.shields.io/github/license/rafsaf/minimal-fastapi-postgres-template)](https://github.com/rafsaf/minimal-fastapi-postgres-template/blob/main/LICENSE)
[![Python 3.12](https://img.shields.io/badge/python-3.12-blue)](https://docs.python.org/3/whatsnew/3.12.html)
[![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)
[![Black](https://img.shields.io/badge/code%20style-black-lightgrey)](https://github.com/psf/black)
[![Tests](https://github.com/rafsaf/minimal-fastapi-postgres-template/actions/workflows/tests.yml/badge.svg)](https://github.com/rafsaf/minimal-fastapi-postgres-template/actions/workflows/tests.yml)

# Minimal async FastAPI + PostgreSQL template

Expand Down Expand Up @@ -42,9 +33,9 @@
- [x] [Alembic](https://alembic.sqlalchemy.org/en/latest/) migrations
- [x] Very minimal project structure yet ready for quick start building new apps
- [x] Refresh token endpoint (not only access like in official template)
- [x] Two databases in docker-compose.yml (second one for tests) and ready to go Dockerfile with [Uvicorn](https://www.uvicorn.org/) webserver
- [x] [Poetry](https://python-poetry.org/docs/) and Python 3.11 based
- [x] `pre-commit` with poetry export, autoflake, black, isort and flake8
- [x] Two databases in docker-compose.yml (second one for tests) and ready to go Dockerfile with [uvicorn](https://www.uvicorn.org/) webserver
- [x] [Poetry](https://python-poetry.org/docs/) and Python 3.12 based
- [x] `pre-commit` with poetry export and [ruff](https://github.com/astral-sh/ruff)
- [x] Rich setup for pytest async tests with few included and extensible `conftest.py`

<br>
Expand All @@ -69,16 +60,16 @@ cookiecutter https://github.com/rafsaf/minimal-fastapi-postgres-template

```bash
cd project_name
### Poetry install (python3.11)
### Poetry install (python3.12)
poetry install

### Optionally there is also `requirements-dev.txt` file
python3.11 -m venv venv
python3.12 -m venv venv
source venv/bin/activate
pip install -r requirements-dev.txt
```

Note, be sure to use `python3.11` with this template with either poetry or standard venv & pip, if you need to stick to some earlier python version, you should adapt it yourself (remove new versions specific syntax for example `str | int` for python < 3.10 or `tomllib` for python < 3.11)
Note, be sure to use `python3.12` with this template with either poetry or standard venv & pip, if you need to stick to some earlier python version, you should adapt it yourself (remove new versions specific syntax for example `str | int` for python < 3.10 or `tomllib` for python < 3.11)

### 3. Setup databases

Expand Down
11 changes: 0 additions & 11 deletions {{cookiecutter.project_name}}/.flake8

This file was deleted.

53 changes: 9 additions & 44 deletions {{cookiecutter.project_name}}/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-yaml
- id: trailing-whitespace

- repo: https://github.com/myint/autoflake
rev: "v2.0.1"
hooks:
- id: autoflake
args:
[
"--recursive",
"--in-place",
"--remove-unused-variables",
"--remove-all-unused-imports",
"--ignore-init-module-imports",
]

- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args:
[
"--py3-plus",
"--py36-plus",
"--py37-plus",
"--py38-plus",
"--py39-plus",
"--py310-plus",
"--py311-plus",
]
files: ".*"

- repo: https://github.com/psf/black
rev: "23.1.0"
rev: "23.10.1"
hooks:
- id: black

- repo: https://github.com/pycqa/isort
rev: "5.12.0"
hooks:
- id: isort

- repo: https://github.com/PyCQA/flake8
rev: "6.0.0"
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.4
hooks:
- id: flake8
- id: ruff
args: [--fix]

- repo: https://github.com/python-poetry/poetry
rev: "1.3.0"
rev: "1.7.0"
hooks:
- id: poetry-export
args: ["-o", "requirements.txt", "--without-hashes"]

- repo: https://github.com/python-poetry/poetry
rev: "1.3.0"
rev: "1.7.0"
hooks:
- id: poetry-export
args:
["-o", "requirements-dev.txt", "--without-hashes", "--with", "dev"]
args: ["-o", "requirements-dev.txt", "--without-hashes", "--with=dev"]
2 changes: 1 addition & 1 deletion {{cookiecutter.project_name}}/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11.1-slim-bullseye
FROM python:3.12.0-slim-bullseye

ENV PYTHONUNBUFFERED 1
WORKDIR /build
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_name}}/app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
Note, complex types like lists are read as json-encoded strings.
"""

import tomllib
from functools import cached_property
from pathlib import Path
from typing import Literal

import tomllib
from pydantic import AnyHttpUrl, EmailStr, PostgresDsn, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict

Expand Down
8 changes: 4 additions & 4 deletions {{cookiecutter.project_name}}/app/tests/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from httpx import AsyncClient
from httpx import AsyncClient, codes

from app.main import app
from app.models import User
Expand All @@ -14,7 +14,7 @@ async def test_auth_access_token(client: AsyncClient, default_user: User):
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
assert response.status_code == 200
assert response.status_code == codes.OK
token = response.json()
assert token["token_type"] == "Bearer"
assert "access_token" in token
Expand All @@ -35,7 +35,7 @@ async def test_auth_access_token_fail_no_user(client: AsyncClient):
headers={"Content-Type": "application/x-www-form-urlencoded"},
)

assert response.status_code == 400
assert response.status_code == codes.BAD_REQUEST
assert response.json() == {"detail": "Incorrect email or password"}


Expand All @@ -53,7 +53,7 @@ async def test_auth_refresh_token(client: AsyncClient, default_user: User):
new_token_response = await client.post(
app.url_path_for("refresh_token"), json={"refresh_token": refresh_token}
)
assert new_token_response.status_code == 200
assert new_token_response.status_code == codes.OK
token = new_token_response.json()
assert token["token_type"] == "Bearer"
assert "access_token" in token
Expand Down
10 changes: 5 additions & 5 deletions {{cookiecutter.project_name}}/app/tests/test_users.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from httpx import AsyncClient
from httpx import AsyncClient, codes
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

Expand All @@ -15,7 +15,7 @@ async def test_read_current_user(client: AsyncClient, default_user_headers):
response = await client.get(
app.url_path_for("read_current_user"), headers=default_user_headers
)
assert response.status_code == 200
assert response.status_code == codes.OK
assert response.json() == {
"id": default_user_id,
"email": default_user_email,
Expand All @@ -28,7 +28,7 @@ async def test_delete_current_user(
response = await client.delete(
app.url_path_for("delete_current_user"), headers=default_user_headers
)
assert response.status_code == 204
assert response.status_code == codes.NO_CONTENT
result = await session.execute(select(User).where(User.id == default_user_id))
user = result.scalars().first()
assert user is None
Expand All @@ -42,7 +42,7 @@ async def test_reset_current_user_password(
headers=default_user_headers,
json={"password": "testxxxxxx"},
)
assert response.status_code == 200
assert response.status_code == codes.OK
result = await session.execute(select(User).where(User.id == default_user_id))
user = result.scalars().first()
assert user is not None
Expand All @@ -60,7 +60,7 @@ async def test_register_new_user(
"password": "asdasdasd",
},
)
assert response.status_code == 200
assert response.status_code == codes.OK
result = await session.execute(select(User).where(User.email == "[email protected]"))
user = result.scalars().first()
assert user is not None
Empty file modified {{cookiecutter.project_name}}/init.sh
100644 → 100755
Empty file.
Loading

0 comments on commit 3cf67c9

Please sign in to comment.