Skip to content

Commit b58bf59

Browse files
committed
Merge tag '3.3.8' into develop
3.3.8
2 parents 406ed84 + bcf1389 commit b58bf59

41 files changed

Lines changed: 644 additions & 233 deletions

Some content is hidden

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

fastapi_template/cli.py

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ def parse_args():
9494
default=None,
9595
dest="enable_rmq",
9696
)
97+
parser.add_argument(
98+
"--kafka",
99+
help="Add Kafka support",
100+
action="store_true",
101+
default=None,
102+
dest="enable_kafka",
103+
)
97104
parser.add_argument(
98105
"--migrations",
99106
help="Add migrations support",
@@ -184,62 +191,31 @@ def parse_args():
184191

185192

186193
def ask_features(current_context: BuilderContext) -> BuilderContext:
194+
# List of features and associated cookiecutter values.
187195
features = {
188-
"Redis support": {
189-
"name": "enable_redis",
190-
"value": current_context.enable_redis,
191-
},
192-
"Kubernetes config (deprecated)": {
193-
"name": "enable_kube",
194-
"value": current_context.enable_kube,
195-
},
196-
"Demo routers": {
197-
"name": "enable_routers",
198-
"value": current_context.enable_routers,
199-
},
200-
"Self-hosted swagger": {
201-
"name": "self_hosted_swagger",
202-
"value": current_context.self_hosted_swagger,
203-
},
204-
"RabbitMQ integration": {
205-
"name": "enable_rmq",
206-
"value": current_context.enable_rmq,
207-
},
208-
"Prometheus integration": {
209-
"name": "prometheus_enabled",
210-
"value": current_context.prometheus_enabled,
211-
},
212-
"Sentry integration": {
213-
"name": "sentry_enabled",
214-
"value": current_context.sentry_enabled,
215-
},
216-
"Opentelemetry integration": {
217-
"name": "otlp_enabled",
218-
"value": current_context.otlp_enabled,
219-
},
220-
"Loguru logger": {
221-
"name": "enable_loguru",
222-
"value": current_context.enable_loguru,
223-
},
224-
"Traefik labels for docker": {
225-
"name": "traefik_labels",
226-
"value": current_context.traefik_labels,
227-
},
196+
"Redis support": "enable_redis",
197+
"Kubernetes config (deprecated)": "enable_kube",
198+
"Demo routers": "enable_routers",
199+
"Self-hosted swagger": "self_hosted_swagger",
200+
"RabbitMQ integration": "enable_rmq",
201+
"Kafka integration": "enable_kafka",
202+
"Prometheus integration": "prometheus_enabled",
203+
"Sentry integration": "sentry_enabled",
204+
"Opentelemetry integration": "otlp_enabled",
205+
"Loguru logger": "enable_loguru",
206+
"Traefik labels for docker": "traefik_labels",
228207
}
229208
if current_context.db != DatabaseType.none:
230-
features["Migrations support"] = {
231-
"name": "enable_migrations",
232-
"value": current_context.enable_migrations,
233-
}
234-
features["Add dummy model"] = {
235-
"name": "add_dummy",
236-
"value": current_context.add_dummy,
237-
}
209+
features.update({
210+
"Migrations support": "enable_migrations",
211+
"Add dummy model": "add_dummy"
212+
})
238213
checkbox_values = []
239-
for feature_name, feature in features.items():
240-
if feature["value"] is None:
241-
setattr(current_context, feature["name"], False)
242-
checkbox_values.append((feature["name"], feature_name))
214+
for feature_display_name, feature_key in features.items():
215+
value = getattr(current_context, feature_key, None)
216+
if value is None:
217+
setattr(current_context, feature_key, False)
218+
checkbox_values.append((feature_key, feature_display_name))
243219
if checkbox_values and not current_context.quite:
244220
results = checkboxlist_dialog(
245221
title="Features",
@@ -248,8 +224,8 @@ def ask_features(current_context: BuilderContext) -> BuilderContext:
248224
).run()
249225
if results is None:
250226
raise KeyboardInterrupt()
251-
for feature in results:
252-
setattr(current_context, feature, True)
227+
for feature_key in results:
228+
setattr(current_context, feature_key, True)
253229
return current_context
254230

255231

fastapi_template/input_model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class BuilderContext(BaseModel):
123123
enable_rmq: Optional[bool]
124124
enable_loguru: Optional[bool]
125125
traefik_labels: Optional[bool]
126+
enable_kafka: Optional[bool]
126127
force: bool = False
127128
quite: bool = False
128129

fastapi_template/template/cookiecutter.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
"enable_routers": {
3333
"type": "bool"
3434
},
35+
"enable_kafka": {
36+
"type": "bool"
37+
},
3538
"enable_loguru": {
3639
"type": "bool"
3740
},

fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/tests.yml

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ jobs:
4848
pytest:
4949
runs-on: ubuntu-latest
5050
{%- if ((cookiecutter.db_info.name != "none" and cookiecutter.db_info.name != "sqlite") or
51-
(cookiecutter.enable_rmq == "True")) %}
51+
(cookiecutter.enable_rmq == "True") or
52+
(cookiecutter.enable_kafka == "True")) %}
5253
services:
5354
{%- if cookiecutter.db_info.name != "none" and cookiecutter.db_info.name != "sqlite" %}
55+
5456
{{cookiecutter.project_name}}-db:
5557
image: {{ cookiecutter.db_info.image }}
5658
env:
@@ -66,24 +68,66 @@ jobs:
6668
ALLOW_EMPTY_PASSWORD: yes
6769
{%- endif %}
6870
{%- if cookiecutter.db_info.name == "mysql" %}
69-
options: --health-cmd="mysqladmin ping -u root" --health-interval=15s --health-timeout=5s --health-retries=5
71+
options: >-
72+
--health-cmd="mysqladmin ping -u root"
73+
--health-interval=15s
74+
--health-timeout=5s
75+
--health-retries=5
7076
{%- endif %}
7177
{%- if cookiecutter.db_info.name == "postgresql" %}
72-
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=5
78+
options: >-
79+
--health-cmd="pg_isready"
80+
--health-interval=10s
81+
--health-timeout=5s
82+
--health-retries=5
7383
{%- endif %}
7484
ports:
75-
- {{ cookiecutter.db_info.port }}
85+
- {{ cookiecutter.db_info.port }}:{{ cookiecutter.db_info.port }}
7686
{%- endif %}
7787
{%- if cookiecutter.enable_rmq == "True" %}
88+
7889
{{cookiecutter.project_name}}-rmq:
7990
image: rabbitmq:3.9.16-alpine
8091
env:
8192
RABBITMQ_DEFAULT_USER: "guest"
8293
RABBITMQ_DEFAULT_PASS: "guest"
8394
RABBITMQ_DEFAULT_VHOST: "/"
84-
options: --health-cmd="rabbitmq-diagnostics check_running -q" --health-interval=10s --health-timeout=5s --health-retries=8
95+
options: >-
96+
--health-cmd="rabbitmq-diagnostics check_running -q"
97+
--health-interval=10s
98+
--health-timeout=5s
99+
--health-retries=8
100+
ports:
101+
- 5672:5672
102+
{%- endif %}
103+
{%- if cookiecutter.enable_kafka == "True" %}
104+
105+
{{cookiecutter.project_name}}-zookeeper:
106+
image: "bitnami/zookeeper:3.7.1"
107+
env:
108+
ALLOW_ANONYMOUS_LOGIN: "yes"
109+
ZOO_LOG_LEVEL: "ERROR"
110+
options: >-
111+
--health-cmd="zkServer.sh status"
112+
--health-interval=10s
113+
--health-timeout=5s
114+
--health-retries=8
115+
116+
{{cookiecutter.project_name}}-kafka:
117+
image: bitnami/kafka:3.2.0
118+
env:
119+
KAFKA_BROKER_ID: "1"
120+
ALLOW_PLAINTEXT_LISTENER: "yes"
121+
KAFKA_CFG_LISTENERS: "PLAINTEXT://0.0.0.0:9092"
122+
KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://localhost:9092"
123+
KAFKA_CFG_ZOOKEEPER_CONNECT: "{{cookiecutter.project_name}}-zookeeper:2181"
124+
options: >-
125+
--health-cmd="kafka-topics.sh --list --bootstrap-server localhost:9092"
126+
--health-interval=10s
127+
--health-timeout=5s
128+
--health-retries=8
85129
ports:
86-
- 5672
130+
- 9092:9092
87131
{%- endif %}
88132
{%- endif %}
89133
steps:
@@ -103,10 +147,12 @@ jobs:
103147
{%- if cookiecutter.db_info.name != "none" %}
104148
{%- if cookiecutter.db_info.name != "sqlite" %}
105149
{{ cookiecutter.project_name | upper }}_DB_HOST: localhost
106-
{{ cookiecutter.project_name | upper }}_DB_PORT: {{'${{'}}job.services.{{cookiecutter.project_name}}-db.ports['{{cookiecutter.db_info.port}}']{{'}}'}}
107150
{%- endif %}
108151
{%- endif %}
109152
{%- if cookiecutter.enable_rmq == "True" %}
110153
{{ cookiecutter.project_name | upper }}_RABBIT_HOST: localhost
111-
{{ cookiecutter.project_name | upper }}_RABBIT_PORT: {{'${{'}}job.services.{{cookiecutter.project_name}}-rmq.ports['5672']{{'}}'}}
112154
{%- endif %}
155+
{%- if cookiecutter.enable_kafka == "True" %}
156+
{{ cookiecutter.project_name | upper }}_KAFKA_BOOTSTRAP_SERVERS: '["localhost:9092"]'
157+
{%- endif %}
158+

fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ pytest:
3636
extends:
3737
- .test-template
3838
{%- if ((cookiecutter.db_info.name != "none" and cookiecutter.db_info.name != "sqlite") or
39-
(cookiecutter.enable_rmq == "True")) %}
39+
(cookiecutter.enable_rmq == "True") or
40+
(cookiecutter.enable_kafka == "True")) %}
4041
services:
4142
{%- if cookiecutter.db_info.name != "none" and cookiecutter.db_info.name != "sqlite" %}
4243
- name: {{ cookiecutter.db_info.image }}
@@ -46,26 +47,49 @@ pytest:
4647
- name: rabbitmq:3.9.16-alpine
4748
alias: rmq
4849
{%- endif %}
50+
{%- if cookiecutter.enable_kafka == "True" %}
51+
- name: bitnami/kafka:3.2.0
52+
alias: kafka
53+
{%- endif %}
4954
variables:
5055
{%- if cookiecutter.db_info.name == "postgresql" %}
56+
57+
# Postgresql variables
5158
{{ cookiecutter.project_name | upper }}_DB_HOST: database
5259
POSTGRES_PASSWORD: {{ cookiecutter.project_name }}
5360
POSTGRES_USER: {{ cookiecutter.project_name }}
5461
POSTGRES_DB: {{ cookiecutter.project_name }}
5562
{%- endif %}
5663
{%- if cookiecutter.db_info.name == "mysql" %}
64+
65+
# MySQL variables
5766
{{ cookiecutter.project_name | upper }}_DB_HOST: database
5867
MYSQL_PASSWORD: {{ cookiecutter.project_name }}
5968
MYSQL_USER: {{ cookiecutter.project_name }}
6069
MYSQL_DATABASE: {{ cookiecutter.project_name }}
6170
ALLOW_EMPTY_PASSWORD: yes
6271
{%- endif %}
6372
{%- if cookiecutter.enable_rmq == "True" %}
73+
74+
# Rabbitmq variables
6475
RABBITMQ_DEFAULT_USER: "guest"
6576
RABBITMQ_DEFAULT_PASS: "guest"
6677
RABBITMQ_DEFAULT_VHOST: "/"
6778
{{ cookiecutter.project_name | upper }}_RABBIT_HOST: rmq
6879
{%- endif %}
80+
{%- if cookiecutter.enable_kafka == "True" %}
81+
82+
# Kafka variables
83+
KAFKA_BROKER_ID: "1"
84+
KAFKA_ENABLE_KRAFT: "yes"
85+
ALLOW_PLAINTEXT_LISTENER: "yes"
86+
KAFKA_CFG_PROCESS_ROLES: "broker,controller"
87+
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
88+
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
89+
KAFKA_CFG_LISTENERS: "PLAINTEXT://:9092,CONTROLLER://:9093"
90+
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@127.0.0.1:9093"
91+
{{ cookiecutter.project_name | upper }}_KAFKA_BOOTSTRAP_SERVERS: '["kafka:9092"]'
92+
{%- endif %}
6993
{%- endif %}
7094
script:
7195
{%- if cookiecutter.db_info.name != "none" %}

fastapi_template/template/{{cookiecutter.project_name}}/aerich.ini

Lines changed: 0 additions & 4 deletions
This file was deleted.

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"{{cookiecutter.project_name}}/web/api/rabbit",
1212
"{{cookiecutter.project_name}}/web/api/dummy",
1313
"{{cookiecutter.project_name}}/web/api/echo",
14-
"{{cookiecutter.project_name}}/web/api/redis"
14+
"{{cookiecutter.project_name}}/web/api/redis",
15+
"{{cookiecutter.project_name}}/web/api/kafka"
1516
]
1617
},
1718
"Redis": {
@@ -34,6 +35,15 @@
3435
"deploy/kube/redis.yml"
3536
]
3637
},
38+
"Kafka support": {
39+
"enabled": "{{cookiecutter.enable_kafka}}",
40+
"resources": [
41+
"{{cookiecutter.project_name}}/web/api/kafka",
42+
"{{cookiecutter.project_name}}/web/gql/kafka",
43+
"{{cookiecutter.project_name}}/services/kafka",
44+
"{{cookiecutter.project_name}}/tests/test_kafka.py"
45+
]
46+
},
3747
"Kubernetes": {
3848
"enabled": "{{cookiecutter.enable_kube}}",
3949
"resources": [
@@ -43,7 +53,6 @@
4353
"Database support": {
4454
"enabled": "{{cookiecutter.db_info.name != 'none'}}",
4555
"resources": [
46-
"aerich.ini",
4756
"alembic.ini",
4857
"{{cookiecutter.project_name}}/web/api/dummy",
4958
"{{cookiecutter.project_name}}/web/gql/dummy",
@@ -61,7 +70,6 @@
6170
"Migrations": {
6271
"enabled": "{{cookiecutter.enable_migrations}}",
6372
"resources": [
64-
"aerich.ini",
6573
"alembic.ini",
6674
"{{cookiecutter.project_name}}/db_sa/migrations",
6775
"{{cookiecutter.project_name}}/db_ormar/migrations",
@@ -102,9 +110,14 @@
102110
"{{cookiecutter.project_name}}/web/gql/dummy",
103111
"{{cookiecutter.project_name}}/web/api/redis",
104112
"{{cookiecutter.project_name}}/web/gql/redis",
113+
"{{cookiecutter.project_name}}/web/api/kafka",
114+
"{{cookiecutter.project_name}}/web/gql/kafka",
115+
"{{cookiecutter.project_name}}/web/api/rabbit",
116+
"{{cookiecutter.project_name}}/web/gql/rabbit",
105117
"{{cookiecutter.project_name}}/tests/test_echo.py",
106118
"{{cookiecutter.project_name}}/tests/test_dummy.py",
107-
"{{cookiecutter.project_name}}/tests/test_redis.py"
119+
"{{cookiecutter.project_name}}/tests/test_redis.py",
120+
"{{cookiecutter.project_name}}/tests/test_rabbit.py"
108121
]
109122
},
110123
"Dummy model": {
@@ -147,7 +160,6 @@
147160
"Tortoise ORM": {
148161
"enabled": "{{cookiecutter.orm == 'tortoise'}}",
149162
"resources": [
150-
"aerich.ini",
151163
"{{cookiecutter.project_name}}/db_tortoise"
152164
]
153165
},

0 commit comments

Comments
 (0)