Skip to content

Commit

Permalink
Merge branch 'release/3.3.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
s3rius committed Jul 8, 2022
2 parents 1568837 + b696933 commit d9a19a2
Show file tree
Hide file tree
Showing 26 changed files with 357 additions and 90 deletions.
51 changes: 31 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![](https://img.shields.io/pypi/dm/fastapi_template?style=for-the-badge)](https://pypi.org/project/fastapi-template/)
<div align="center">
<img src="https://raw.githubusercontent.com/s3rius/FastAPI-template/master/images/logo.png" width=700>
<div><i>Flexible and Lightweight general-purpose template for FastAPI.</i></div>
<div><i>Flexible general-purpose template for FastAPI.</i></div>
</div>

## Usage
Expand All @@ -11,6 +11,12 @@

Poetry version must be greater or equal than 1.1.8. Otherwise it won't be able to install SQLAlchemy.

<div align="center">
<img src="https://user-images.githubusercontent.com/18153319/137182689-ce714440-7576-46a0-8f96-862a8469a28c.gif"/>
<p>Templator in action</p>
</div>

You can install it directly from pypi with pip.
```bash
python3 -m pip install fastapi_template
python3 -m fastapi_template
Expand All @@ -22,7 +28,7 @@ docker-compose -f deploy/docker-compose.yml --project-directory . build
docker-compose -f deploy/docker-compose.yml --project-directory . up --build
```

If you want to install in from sources then try this:
If you want to install it from sources, try this:
```shell
python3 -m pip install poetry
python3 -m pip install .
Expand All @@ -34,33 +40,33 @@ Also you can use it with docker.
docker run --rm -it -v "$(pwd):/projects" s3rius/fastapi_template
```

<div align="center">
<img src="https://user-images.githubusercontent.com/18153319/137182689-ce714440-7576-46a0-8f96-862a8469a28c.gif"/>
<p>Templator in action</p>
</div>


## Features

One of the coolest features is that this project is extremely small and handy.
You can choose between different databases and even ORMs.
Currently SQLAlchemy1.4, TortoiseORM and Ormar are supported.
One of the coolest features is that this project is extremely configurable.
You can choose between different databases and even ORMs, or
you can even generate a project without a database!
Currently SQLAlchemy1.4, TortoiseORM, Piccolo and Ormar are supported.

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

Generator features:
- You can choose between GraphQL and REST api;
- Different databases support;
- Different ORMs support;
- Optional migrations for each ORM except raw drivers;
- redis support;
- rabbitmq support;
- Optional redis support;
- Optional rabbitmq support;
- different CI\CD;
- Kubernetes config generation;
- Demo routers and models;
- Pre-commit integrations;
- Generated tests;
- Tests for the generator itself.
- Optional Kubernetes config generation;
- Optional Demo routers and models (This helps you to see how project is structured);
- Pre-commit integration;
- Generated tests with almost 90% coverage;
- Tests for the generator itself;
- Optional Prometheus integration;
- Optional Sentry integration;
- Optional Loguru logger;
- Optional Opentelemetry integration.


This project can handle arguments passed through command line.

Expand All @@ -74,7 +80,8 @@ usage: FastAPI template [-h] [--version] [--name PROJECT_NAME]
[--orm {ormar,sqlalchemy,tortoise,psycopg,piccolo}]
[--ci {none,gitlab_ci,github}] [--redis] [--rabbit]
[--migrations] [--kube] [--dummy] [--routers]
[--swagger] [--force] [--quite]
[--swagger] [--prometheus] [--sentry] [--loguru]
[--opentelemetry] [--force] [--quite]

optional arguments:
-h, --help show this help message and exit
Expand All @@ -98,6 +105,10 @@ optional arguments:
Add dummy model
--routers Add example routers
--swagger Enable self-hosted Swagger
--prometheus Add prometheus integration
--sentry Add sentry integration
--loguru Add loguru logger
--opentelemetry Add opentelemetry integration
--force Owerrite directory if it exists
--quite Do not ask for features during generation
```
11 changes: 11 additions & 0 deletions fastapi_template/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ def parse_args():
default=None,
dest="sentry_enabled",
)
parser.add_argument(
"--loguru",
help="Add loguru logger",
action="store_true",
default=None,
dest="enable_loguru",
)
parser.add_argument(
"--opentelemetry",
help="Add opentelemetry integration",
Expand Down Expand Up @@ -203,6 +210,10 @@ def ask_features(current_context: BuilderContext) -> BuilderContext:
"name": "otlp_enabled",
"value": current_context.otlp_enabled,
},
"Loguru logger": {
"name": "enable_loguru",
"value": current_context.enable_loguru,
},
}
if current_context.db != DatabaseType.none:
features["Migrations support"] = {
Expand Down
1 change: 1 addition & 0 deletions fastapi_template/input_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class BuilderContext(BaseModel):
sentry_enabled: Optional[bool]
otlp_enabled: Optional[bool]
enable_rmq: Optional[bool]
enable_loguru: Optional[bool]
force: bool = False
quite: bool = False

Expand Down
3 changes: 3 additions & 0 deletions fastapi_template/template/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
"enable_routers": {
"type": "bool"
},
"enable_loguru": {
"type": "bool"
},
"add_dummy": {
"type": "bool"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,3 @@ repos:
pass_filenames: false
args:
- "{{cookiecutter.project_name}}"

- id: yesqa
name: Remove usless noqa
entry: poetry run yesqa
language: system
types: [python]
62 changes: 43 additions & 19 deletions fastapi_template/template/{{cookiecutter.project_name}}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,28 @@ But you have to rebuild image every time you modify `poetry.lock` or `pyproject.
docker-compose -f deploy/docker-compose.yml --project-directory . build
```

{%- if cookiecutter.otlp_enabled == "True" %}
## Opentelemetry

If you want to start your project with opentelemetry collector
you can add `-f ./deploy/docker-compose.otlp.yml` to your docker command.

Like this:
## Project structure

```bash
docker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.otlp.yml --project-directory . up
```

This command will start opentelemetry collector and jaeger.
After sending a requests you can see traces in jaeger's UI
at http://localhost:16686/.

This docker configuration is not supposed to be used in production.
It's only for demo purpose.

You can read more about opentelemetry here: https://opentelemetry.io/
$ tree "{{cookiecutter.project_name}}"
{{cookiecutter.project_name}}
├── conftest.py # Fixtures for all tests.
{%- if cookiecutter.db_info.name != "none" %}
├── db # module contains db configurations
│   ├── dao # Data Access Objects. Contains different classes to inteact with database.
│   └── models # Package contains different models for ORMs.
{%- endif %}
├── __main__.py # Startup script. Starts uvicorn.
├── services # Package for different external services such as rabbit or redis etc.
├── settings.py # Main configuration settings for project.
├── static # Static content.
├── tests # Tests for project.
└── web # Package contains web server. Handlers, startup config.
├── api # Package with all handlers.
│   └── router.py # Main router.
├── application.py # FastAPI application configuration.
└── lifetime.py # Contains actions to perform on startup and shutdown.
```
## Configuration
Expand All @@ -76,7 +77,8 @@ All environment variabels should start with "{{cookiecutter.project_name | upper
For example if you see in your "{{cookiecutter.project_name}}/settings.py" a variable named like
`random_parameter`, you should provide the "{{cookiecutter.project_name | upper}}_RANDOM_PARAMETER"
variable to configure the value.
variable to configure the value. This behaviour can be changed by overriding `env_prefix` property
in `{{cookiecutter.project_name}}.settings.Settings.Config`.
An exmaple of .env file:
```bash
Expand All @@ -87,6 +89,28 @@ An exmaple of .env file:
You can read more about BaseSettings class here: https://pydantic-docs.helpmanual.io/usage/settings/
{%- if cookiecutter.otlp_enabled == "True" %}
## Opentelemetry
If you want to start your project with opentelemetry collector
you can add `-f ./deploy/docker-compose.otlp.yml` to your docker command.
Like this:
```bash
docker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.otlp.yml --project-directory . up
```
This command will start opentelemetry collector and jaeger.
After sending a requests you can see traces in jaeger's UI
at http://localhost:16686/.
This docker configuration is not supposed to be used in production.
It's only for demo purpose.
You can read more about opentelemetry here: https://opentelemetry.io/
{%- endif %}
## Pre-commit
To install pre-commit simply run inside the shell:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
".github"
]
},
"Loguru": {
"enabled": "{{cookiecutter.enable_loguru}}",
"resources": [
"{{cookiecutter.project_name}}/logging.py"
]
},
"Routers": {
"enabled": "{{cookiecutter.enable_routers}}",
"resources": [
Expand Down Expand Up @@ -192,4 +198,4 @@
"{{cookiecutter.project_name}}/db_tortoise/migrations/models/1_20210928165300_init_dummy_sqlite.sql"
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ version: '3.9'
services:
api:
ports:
# Exposes application port.
- "8000:8000"
volumes:
# Adds current directory as volume.
- .:/app/src/
environment:
# Enables autoreload.
{{cookiecutter.project_name | upper}}_RELOAD: "True"
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
services:
api:
environment:
# Adds opentelemetry endpoint.
{{cookiecutter.project_name | upper}}_OPENTELEMETRY_ENDPOINT: "http://otel-collector:4317"

otel-collector:
image: otel/opentelemetry-collector-contrib:0.53.0
volumes:
# Adds config for opentelemetry.
- ./deploy/otel-collector-config.yml:/config.yml
command: --config config.yml
ports:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# Receives all info with OpenTelemetry protocol.
receivers:
otlp:
protocols:
grpc:
http:

# Batch all spans.
processors:
batch:

exporters:
# Exports spans to log.
logging:
logLevel: info

# Exports spans to jaeger.
jaeger:
endpoint: "jaeger:14250"
tls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ httptools = "^0.3.0"
strawberry-graphql = { version = "^0.114.2", extras = ["fastapi"] }
{%- endif %}
{%- if cookiecutter.enable_rmq == "True" %}
aio-pika = "^8.0.3"
aio-pika = "^7.2.0"
{%- endif %}
{%- if cookiecutter.prometheus_enabled == "True" %}
prometheus-client = "^0.14.1"
Expand All @@ -92,28 +92,35 @@ prometheus-fastapi-instrumentator = "5.8.1"
sentry-sdk = "^1.5.12"
{%- endif %}
{%- if cookiecutter.otlp_enabled == "True" %}
protobuf = "~3.20.0"
opentelemetry-api = {version = "^1.12.0rc1", allow-prereleases = true}
opentelemetry-sdk = {version = "^1.12.0rc1", allow-prereleases = true}
opentelemetry-exporter-otlp = {version = "^1.12.0rc1", allow-prereleases = true}
opentelemetry-instrumentation = "^0.31b0"
opentelemetry-instrumentation-logging = "^0.31b0"
opentelemetry-instrumentation-fastapi = "^0.31b0"
opentelemetry-api = {version = "^1.12.0rc2", allow-prereleases = true}
opentelemetry-sdk = {version = "^1.12.0rc2", allow-prereleases = true}
opentelemetry-exporter-otlp = {version = "^1.12.0rc2", allow-prereleases = true}
opentelemetry-instrumentation = "^0.32b0"
opentelemetry-instrumentation-fastapi = "^0.32b0"
{%- if cookiecutter.enable_loguru != "True" %}
opentelemetry-instrumentation-logging = "^0.32b0"
{%- endif %}
{%- if cookiecutter.enable_redis == "True" %}
opentelemetry-instrumentation-redis = "^0.31b0"
opentelemetry-instrumentation-redis = "^0.32b0"
{%- endif %}
{%- if cookiecutter.db_info.name == "postgresql" and cookiecutter.orm in ["ormar", "tortoise"] %}
opentelemetry-instrumentation-asyncpg = "^0.31b0"
opentelemetry-instrumentation-asyncpg = "^0.32b0"
{%- endif %}
{%- if cookiecutter.orm == "sqlalchemy" %}
opentelemetry-instrumentation-sqlalchemy = "^0.31b0"
opentelemetry-instrumentation-sqlalchemy = "^0.32b0"
{%- endif %}
{%- if cookiecutter.enable_rmq == "True" %}
opentelemetry-instrumentation-aio-pika = "^0.32b0"
{%- endif %}
{%- endif %}
{%- if cookiecutter.enable_loguru == "True" %}
loguru = "^0.6.0"
{%- endif %}

[tool.poetry.dev-dependencies]
pytest = "^7.0"
flake8 = "^4.0.1"
mypy = "^0.910"
mypy = "^0.961"
isort = "^5.10.1"
yesqa = "^1.3.0"
pre-commit = "^2.19.0"
Expand All @@ -134,10 +141,6 @@ asynctest = "^0.13.0"
nest-asyncio = "^1.5.5"
{%- endif %}
httpx = "^0.22.0"
{%- if cookiecutter.enable_redis == "True" %}
types-redis = "^4.2.6"
{%- endif %}


[tool.isort]
profile = "black"
Expand All @@ -155,10 +158,23 @@ implicit_reexport = true
allow_untyped_decorators = true
warn_unused_ignores = false
warn_return_any = false
namespace_packages = true
{%- if cookiecutter.orm == "sqlalchemy" %}
plugins = ["sqlalchemy.ext.mypy.plugin"]
{%- endif %}

{%- if cookiecutter.enable_redis == "True" %}

# Remove this and add `types-redis`
# when the issue https://github.com/python/typeshed/issues/8242 is resolved.
[[tool.mypy.overrides]]
module = [
'redis.asyncio'
]
ignore_missing_imports = true

{%- endif %}

[tool.pytest.ini_options]
filterwarnings = [
"error",
Expand Down
Loading

0 comments on commit d9a19a2

Please sign in to comment.