Skip to content

Commit 38a04b1

Browse files
committed
Merge branch 'release/5.0.0'
2 parents 8b1b5f1 + 4f06fdd commit 38a04b1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1032
-764
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ jobs:
4040
git config --global user.name "fastapi_template"
4141
git config --global user.email "[email protected]"
4242
- name: Run tests
43-
run: poetry run pytest -vv --exitfirst -n auto
43+
run: poetry run pytest -vv

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.9.17-alpine
1+
FROM python:3.11.4-slim-bullseye
22

33
RUN apk add --no-cache \
44
curl \
@@ -11,7 +11,8 @@ RUN apk add --no-cache \
1111
# For psycopg \
1212
postgresql-dev \
1313
# For mysql deps \
14-
mariadb-connector-c-dev \
14+
default-libmysqlclient-dev \
15+
pkg-config \
1516
# For UI \
1617
ncurses \
1718
bash

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ docker run --rm -it -v "$(pwd):/projects" s3rius/fastapi_template
4545
One of the coolest features is that this project is extremely configurable.
4646
You can choose between different databases and even ORMs, or
4747
you can even generate a project without a database!
48-
Currently SQLAlchemy1.4, TortoiseORM, Piccolo and Ormar are supported.
48+
Currently SQLAlchemy 2.0, TortoiseORM, Piccolo and Ormar are supported.
4949

5050
This project can run as TUI or CLI and has excellent code documentation.
5151

5252
Generator features:
53+
- Pydantic V2 (Where it's possible. Some libs doesn't have support);
5354
- You can choose between GraphQL and REST api;
55+
- Uvicorn and gunicorn;
5456
- Different databases support;
5557
- Different ORMs support;
5658
- Optional migrations for each ORM except raw drivers;
@@ -101,5 +103,6 @@ Options:
101103
--opentelemetry Add opentelemetry integration
102104
--traefik Adds traefik labels to docker container
103105
--kafka Add Kafka support
106+
--gunicorn Add gunicorn server
104107
--help Show this message and exit.
105108
```

fastapi_template/__main__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22

3-
from cookiecutter.exceptions import FailedHookException, OutputDirExistsException
3+
from cookiecutter.exceptions import (FailedHookException,
4+
OutputDirExistsException)
45
from cookiecutter.main import cookiecutter
56
from termcolor import cprint
67

fastapi_template/cli.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1+
import re
12
import shutil
2-
from fastapi_template.input_model import (
3-
BuilderContext,
4-
MenuEntry,
5-
SingularMenuModel,
6-
MultiselectMenuModel,
7-
BaseMenuModel,
8-
Database,
9-
SKIP_ENTRY,
10-
)
113
from importlib.metadata import version
12-
from typing import Callable, List, Optional
13-
from click import Command, Option
14-
import re
4+
from typing import Any, Callable, List, Optional
155

6+
from click import Command, Option
167
from prompt_toolkit import prompt
178
from prompt_toolkit.document import Document
189
from prompt_toolkit.validation import ValidationError, Validator
19-
from typing import Any
2010
from termcolor import colored
2111

12+
from fastapi_template.input_model import (
13+
SKIP_ENTRY,
14+
BaseMenuModel,
15+
BuilderContext,
16+
Database,
17+
MenuEntry,
18+
MultiselectMenuModel,
19+
SingularMenuModel,
20+
)
21+
2222

2323
class SnakeCaseValidator(Validator):
2424
def validate(self, document: Document):
@@ -81,6 +81,7 @@ def checker(ctx: BuilderContext) -> bool:
8181
MenuEntry(
8282
code="graphql",
8383
user_view="GrapQL API",
84+
pydantic_v1=True,
8485
description=(
8586
"Choose this option if you want to create a service with {name}.\n"
8687
"It's more suitable for services with {reason} and deep nesting.".format(
@@ -245,6 +246,7 @@ def checker(ctx: BuilderContext) -> bool:
245246
MenuEntry(
246247
code="ormar",
247248
user_view="Ormar",
249+
pydantic_v1=True,
248250
description=(
249251
"{what} is a great {feature} ORM.\n"
250252
"It's compatible with pydantic models and alembic migrator.".format(
@@ -290,6 +292,7 @@ def checker(ctx: BuilderContext) -> bool:
290292
MenuEntry(
291293
code="piccolo",
292294
user_view="Piccolo",
295+
pydantic_v1=True,
293296
is_hidden=check_db(["postgresql", "sqlite"]),
294297
description=(
295298
"{what} is a great ORM for Postgresql and SQLite.\n"
@@ -382,6 +385,7 @@ def checker(ctx: BuilderContext) -> bool:
382385
code="add_dummy",
383386
cli_name="dummy",
384387
user_view="Add dummy model",
388+
is_hidden=lambda ctx: ctx.orm == "none",
385389
description=(
386390
"This option creates {what} as an example of how to use chosen ORM.\n"
387391
"Also this option will generate you an example of {dao}.".format(
@@ -510,6 +514,17 @@ def checker(ctx: BuilderContext) -> bool:
510514
)
511515
),
512516
),
517+
MenuEntry(
518+
code="gunicorn",
519+
cli_name="gunicorn",
520+
user_view="Add gunicorn server",
521+
description=(
522+
"This option adds {what} server for running application.\n"
523+
"It's more performant than uvicorn, and recommended for production.".format(
524+
what=colored("gunicorn", color="green")
525+
)
526+
),
527+
),
513528
],
514529
)
515530

fastapi_template/input_model.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import abc
12
import enum
2-
from typing import List, Optional, Callable, Any
3+
from collections import UserDict
4+
from typing import Any, Callable, List, Optional
35

4-
from pydantic import BaseModel
56
import click
6-
import abc
7-
from collections import UserDict
87
from prompt_toolkit.shortcuts import checkboxlist_dialog, radiolist_dialog
8+
from pydantic import BaseModel
99

1010
try:
1111
from simple_term_menu import TerminalMenu
@@ -15,20 +15,21 @@
1515

1616
class Database(BaseModel):
1717
name: str
18-
image: Optional[str]
19-
driver: Optional[str]
20-
async_driver: Optional[str]
21-
port: Optional[int]
22-
driver_short: Optional[str]
18+
image: Optional[str] = None
19+
driver: Optional[str] = None
20+
async_driver: Optional[str] = None
21+
port: Optional[int] = None
22+
driver_short: Optional[str] = None
2323

2424

2525
class MenuEntry(BaseModel):
2626
code: str
27-
cli_name: Optional[str]
27+
cli_name: Optional[str] = None
2828
user_view: str
2929
description: str
30-
is_hidden: Optional[Callable[["BuilderContext"], bool]]
31-
additional_info: Any
30+
is_hidden: Optional[Callable[["BuilderContext"], bool]] = None
31+
additional_info: Any = None
32+
pydantic_v1: bool = False
3233

3334
@property
3435
def generated_name(self) -> str:
@@ -83,13 +84,13 @@ def after_ask(self, context: "BuilderContext") -> "BuilderContext":
8384

8485
class SingularMenuModel(BaseMenuModel):
8586
code: str
86-
cli_name: Optional[str]
87+
cli_name: Optional[str] = None
8788
description: str
88-
before_ask_fun: Optional[Callable[["BuilderContext"], Optional[MenuEntry]]]
89+
before_ask_fun: Optional[Callable[["BuilderContext"], Optional[MenuEntry]]] = None
8990
after_ask_fun: Optional[
9091
Callable[["BuilderContext", "SingularMenuModel"], "BuilderContext"]
91-
]
92-
parser: Optional[Callable[[str], Any]]
92+
] = None
93+
parser: Optional[Callable[[str], Any]] = None
9394

9495
def get_cli_options(self) -> List[click.Option]:
9596
cli_name = self.code
@@ -158,6 +159,8 @@ def ask(self, context: "BuilderContext") -> Optional["BuilderContext"]:
158159
return
159160

160161
setattr(context, self.code, chosen_entry.code)
162+
if chosen_entry.pydantic_v1:
163+
context.pydanticv1 = True
161164

162165
return context
163166

@@ -236,6 +239,10 @@ def ask(self, context: "BuilderContext") -> Optional["BuilderContext"]:
236239

237240
for entry in chosen_entries:
238241
setattr(context, entry.code, True)
242+
243+
for ch_entry in chosen_entries:
244+
if ch_entry.pydantic_v1:
245+
context.pydanticv1 = True
239246

240247
return context
241248

fastapi_template/template/cookiecutter.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
"otlp_enabled": {
6060
"type": "bool"
6161
},
62+
"pydanticv1": {
63+
"type": "bool"
64+
},
65+
"gunicorn": {
66+
"type": "bool"
67+
},
6268
"_extensions": [
6369
"cookiecutter.extensions.RandomStringExtension"
6470
],

fastapi_template/template/{{cookiecutter.project_name}}/.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ ignore =
7070
WPS407,
7171
; Found too many empty lines in `def`
7272
WPS473,
73+
; too many no-cover comments.
74+
WPS403,
7375

7476
per-file-ignores =
7577
; all tests

fastapi_template/template/{{cookiecutter.project_name}}/.pre-commit-config.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ repos:
2626

2727
- repo: local
2828
hooks:
29-
- id: black
30-
name: Format with Black
31-
entry: poetry run black
32-
language: system
33-
types: [python]
34-
3529
- id: autoflake
3630
name: autoflake
3731
entry: poetry run autoflake
3832
language: system
3933
types: [python]
4034
args: [--in-place, --remove-all-unused-imports, --remove-duplicate-keys]
4135

36+
- id: black
37+
name: Format with Black
38+
entry: poetry run black
39+
language: system
40+
types: [python]
41+
4242
- id: isort
4343
name: isort
4444
entry: poetry run isort

fastapi_template/template/{{cookiecutter.project_name}}/conditional_files.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,11 @@
215215
"resources": [
216216
"{{cookiecutter.project_name}}/tkq.py"
217217
]
218+
},
219+
"Gunicorn support":{
220+
"enabled": "{{cookiecutter.gunicorn}}",
221+
"resources": [
222+
"{{cookiecutter.project_name}}/gunicorn_runner.py"
223+
]
218224
}
219225
}

0 commit comments

Comments
 (0)