instant-python 0.8.1__py3-none-any.whl → 0.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ class JinjaEnvironment:
9
9
  loader=PackageLoader(package_name, template_directory),
10
10
  trim_blocks=True,
11
11
  lstrip_blocks=True,
12
+ autoescape=True,
12
13
  )
13
14
  self._env.filters["is_in"] = is_in
14
15
  self._env.filters["compute_base_path"] = compute_base_path
@@ -3,17 +3,23 @@
3
3
  from fastapi import FastAPI, Request
4
4
  from fastapi.responses import JSONResponse
5
5
 
6
+ {% if ["async_alembic"] | is_in(template.built_in_features) %}
6
7
  {% if template.name == template_types.STANDARD %}
7
8
  from {{ general.source_name }}.api.lifespan import lifespan
8
9
  {% else %}
9
10
  from {{ general.source_name }}.delivery.api.lifespan import lifespan
10
11
  {% endif %}
12
+ {% endif %}
11
13
  from {{ general.source_name }}.{{ template_infra_import }}.http.http_response import HttpResponse
12
14
  from {{ general.source_name }}.{{ template_infra_import }}.http.status_code import StatusCode
13
15
  from {{ general.source_name }}.{{ template_domain_import }}.exceptions.domain_error import DomainError
14
16
 
15
- app = FastAPI(lifespan=lifespan)
16
17
 
18
+ {% if ["async_alembic"] | is_in(template.built_in_features) %}
19
+ app = FastAPI(lifespan=lifespan)
20
+ {% else %}
21
+ app = FastAPI()
22
+ {% endif %}
17
23
 
18
24
  @app.exception_handler(Exception)
19
25
  async def unexpected_exception_handler(_: Request, exc: Exception) -> JSONResponse:
@@ -6,6 +6,7 @@ from {{ general.source_name }}.{{ template_domain_import }}.exceptions.domain_er
6
6
  from {{ general.source_name }}.{{ template_infra_import }}.http.status_code import StatusCode
7
7
  from {{ general.source_name }}.{{ template_infra_import }}.log.logger import create_logger
8
8
 
9
+ {% if ["logger"] | is_in(template.built_in_features) %}
9
10
  logger = create_logger("logger")
10
11
 
11
12
 
@@ -42,4 +43,25 @@ class HttpResponse:
42
43
 
43
44
  @staticmethod
44
45
  def ok(content: dict) -> JSONResponse:
45
- return JSONResponse(content=content, status_code=StatusCode.OK)
46
+ return JSONResponse(content=content, status_code=StatusCode.OK)
47
+ {% else %}
48
+ class HttpResponse:
49
+ @staticmethod
50
+ def domain_error(error: DomainError, status_code: StatusCode) -> JSONResponse:
51
+ return JSONResponse(content={"error": error.to_primitives()}, status_code=status_code)
52
+
53
+ @staticmethod
54
+ def internal_error(error: Exception) -> JSONResponse:
55
+ return JSONResponse(
56
+ content={"error": "Internal server error"},
57
+ status_code=StatusCode.INTERNAL_SERVER_ERROR,
58
+ )
59
+
60
+ @staticmethod
61
+ def created(resource: str) -> JSONResponse:
62
+ return JSONResponse(content={"resource": resource}, status_code=StatusCode.CREATED)
63
+
64
+ @staticmethod
65
+ def ok(content: dict) -> JSONResponse:
66
+ return JSONResponse(content=content, status_code=StatusCode.OK)
67
+ {% endif %}
@@ -1,3 +1,5 @@
1
+ from collections.abc import Sequence
2
+
1
3
  {% set template_infra_import = "shared.infra"|compute_base_path(template.name) %}
2
4
  import logging
3
5
  from datetime import date
@@ -8,7 +10,7 @@ from {{ general.source_name }}.{{ template_infra_import }}.log.json_formatter im
8
10
 
9
11
 
10
12
  def create_file_handler(file_name: str, level: int) -> TimedRotatingFileHandler:
11
- root_project_path = Path(__file__).parents[4]
13
+ root_project_path = _find_project_root(markers=["pyproject.toml"])
12
14
  log_folder = root_project_path / "logs"
13
15
  log_folder.mkdir(parents=True, exist_ok=True)
14
16
 
@@ -36,4 +38,11 @@ def create_logger(logger_name: str) -> logging.Logger:
36
38
  logger.addHandler(production_handler)
37
39
  logger.addHandler(develop_handler)
38
40
 
39
- return logger
41
+ return logger
42
+
43
+ def _find_project_root(markers: Sequence[str]) -> Path:
44
+ start = Path(__file__).resolve()
45
+ for parent in (start, *start.parents):
46
+ if any((parent / marker).exists() for marker in markers):
47
+ return parent
48
+ raise FileNotFoundError(f"Could not find project root (markers: {markers}).")
@@ -39,13 +39,13 @@
39
39
  {% if "event_bus" in template.built_in_features %}
40
40
  {{ macros.include_and_indent("project_structure/event_bus_infra.yml.j2", 8) }}
41
41
  {% endif %}
42
- {% if ["logger", "fastapi_application"] | is_in(template.built_in_features) %}
42
+ {% if ["logger"] | is_in(template.built_in_features) %}
43
43
  {{ macros.include_and_indent("project_structure/logger.yml.j2", 8) }}
44
44
  {% endif %}
45
45
  {% if "async_sqlalchemy" in template.built_in_features %}
46
46
  {{ macros.include_and_indent("project_structure/async_sqlalchemy.yml.j2", 8) }}
47
47
  {% endif %}
48
- {% if ["async_alembic", "fastapi_application"] | is_in(template.built_in_features) %}
48
+ {% if ["async_alembic"] | is_in(template.built_in_features) %}
49
49
  {{ macros.include_and_indent("project_structure/alembic_migrator.yml.j2", 8) }}
50
50
  {% endif %}
51
51
  {% if "fastapi_application" in template.built_in_features %}
@@ -41,13 +41,13 @@
41
41
  {% if "event_bus" in template.built_in_features %}
42
42
  {{ macros.include_and_indent("project_structure/event_bus_infra.yml.j2", 12) }}
43
43
  {% endif %}
44
- {% if ["logger", "fastapi_application"] | is_in(template.built_in_features) %}
44
+ {% if ["logger"] | is_in(template.built_in_features) %}
45
45
  {{ macros.include_and_indent("project_structure/logger.yml.j2", 12) }}
46
46
  {% endif %}
47
47
  {% if "async_sqlalchemy" in template.built_in_features %}
48
48
  {{ macros.include_and_indent("project_structure/async_sqlalchemy.yml.j2", 12) }}
49
49
  {% endif %}
50
- {% if ["async_alembic", "fastapi_application"] | is_in(template.built_in_features) %}
50
+ {% if ["async_alembic"] | is_in(template.built_in_features) %}
51
51
  {{ macros.include_and_indent("project_structure/alembic_migrator.yml.j2", 12) }}
52
52
  {% endif %}
53
53
  {% if "fastapi_application" in template.built_in_features %}
@@ -5,6 +5,8 @@
5
5
  - name: fastapi/application
6
6
  type: boilerplate_file
7
7
  extension: .py
8
+ {% if "async_alembic" in template.built_in_features %}
8
9
  - name: fastapi/lifespan
9
10
  type: boilerplate_file
10
- extension: .py
11
+ extension: .py
12
+ {% endif %}
@@ -14,13 +14,13 @@
14
14
  {% if "synchronous_sqlalchemy" in template.built_in_features %}
15
15
  {{ macros.include_and_indent("project_structure/synchronous_sqlalchemy.yml.j2", 4) }}
16
16
  {% endif %}
17
- {% if ["logger", "fastapi_application"] | is_in(template.built_in_features) %}
17
+ {% if ["logger"] | is_in(template.built_in_features) %}
18
18
  {{ macros.include_and_indent("project_structure/logger.yml.j2", 4) }}
19
19
  {% endif %}
20
20
  {% if "async_sqlalchemy" in template.built_in_features %}
21
21
  {{ macros.include_and_indent("project_structure/async_sqlalchemy.yml.j2", 4) }}
22
22
  {% endif %}
23
- {% if ["async_alembic", "fastapi_application"] | is_in(template.built_in_features) %}
23
+ {% if ["async_alembic"] | is_in(template.built_in_features) %}
24
24
  {{ macros.include_and_indent("project_structure/alembic_migrator.yml.j2", 4) }}
25
25
  {% endif %}
26
26
  {% if "fastapi_application" in template.built_in_features %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: instant-python
3
- Version: 0.8.1
3
+ Version: 0.8.2
4
4
  Summary: Instant boilerplate generation for Python projects
5
5
  Project-URL: documentation, https://dimanu-py.github.io/instant-python/
6
6
  Project-URL: repository, https://github.com/dimanu-py/instant-python/
@@ -219,7 +219,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
219
219
  Classifier: Topic :: System :: Installation/Setup
220
220
  Classifier: Topic :: System :: Shells
221
221
  Requires-Python: >=3.9
222
- Requires-Dist: jinja2>=3.1.5
222
+ Requires-Dist: jinja2>=3.1.6
223
223
  Requires-Dist: pyyaml>=6.0.2
224
224
  Requires-Dist: questionary>=2.1.0
225
225
  Requires-Dist: typer>=0.15.1
@@ -65,7 +65,7 @@ instant_python/project_creator/unknown_node_typer_error.py,sha256=Qli80wAkFVT6ef
65
65
  instant_python/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  instant_python/render/custom_project_renderer.py,sha256=_vbrb_ec4HatvyiipaCXidmz6DUdlsZp45Fgyh5a7qE,720
67
67
  instant_python/render/jinja_custom_filters.py,sha256=hbyh-lUOZyCvKdsXCaJO4gaa9xJGQh2oXAJD02itq3E,865
68
- instant_python/render/jinja_environment.py,sha256=bKQV0cxiNCgDz551Ju9zyfb_Ymhg_WJMBNnoQITzasQ,1038
68
+ instant_python/render/jinja_environment.py,sha256=FYDSdBUetBLHH-XQg1S53xKTRpY6fQsuph5qbngtfRA,1067
69
69
  instant_python/render/jinja_project_renderer.py,sha256=RTNuMn9o2Mk3yafi5zgNdOQ1cg5Hp8ygjphQWP3-BDk,1391
70
70
  instant_python/render/template_file_not_found_error.py,sha256=o-10W2yp1z-C9yqqCyftLDBhN16qS20vkGpjCgxtPPc,411
71
71
  instant_python/render/unknown_template_error.py,sha256=ma-nO-LKDnsWgZleBNeMMs_mCv6uVcGV_Oc4wdHjFZ8,367
@@ -110,8 +110,8 @@ instant_python/templates/boilerplate/exceptions/invalid_negative_value_error.py,
110
110
  instant_python/templates/boilerplate/exceptions/rabbit_mq_connection_not_established_error.py,sha256=LrHE5VrQHWD2QnwMb3WvhiJ0dNhI-PPxXaBvp_tPO7E,436
111
111
  instant_python/templates/boilerplate/exceptions/required_value_error.py,sha256=9-djvzVvntsnMnCQBioxPUdznUV-5KWc9k_vaVGPaIY,428
112
112
  instant_python/templates/boilerplate/fastapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- instant_python/templates/boilerplate/fastapi/application.py,sha256=nEECvo6IETqWLF8DGORWcoiaPYcnls0ZvdDAEDtV8A0,1130
114
- instant_python/templates/boilerplate/fastapi/http_response.py,sha256=xbxY3erNh8lYd52RnpDwWEJXa_mEaNt_w5SBQ3hBJIM,1576
113
+ instant_python/templates/boilerplate/fastapi/application.py,sha256=98DEDIUPlb0Rsuay0CdHM4CAluRui_rjlAiYO6omJg0,1307
114
+ instant_python/templates/boilerplate/fastapi/http_response.py,sha256=iuzauAiIIU18TK7MLuQkyqhanUfesMXoMPgqjITbatU,2322
115
115
  instant_python/templates/boilerplate/fastapi/lifespan.py,sha256=zbsmwtC_9PWJnGlO__5yOqLdEBklnl6f_FUOumy80oE,444
116
116
  instant_python/templates/boilerplate/fastapi/status_code.py,sha256=bXHig0TFnfwGb_DmvQX3ovwWPWdI03mDmVb2Y-Oi7so,143
117
117
  instant_python/templates/boilerplate/github/action.yml,sha256=52HH17dcMu2NOBUbydPP7nOkV2DZxzu7gX4IwYwjYts,668
@@ -119,7 +119,7 @@ instant_python/templates/boilerplate/github/lint.yml,sha256=liaEzb_S4NKXgOtnwenp
119
119
  instant_python/templates/boilerplate/github/test.yml,sha256=jlPPZQra5EQH05HHqov8fBZ_inBg4BP6lwNFn0-zvWY,580
120
120
  instant_python/templates/boilerplate/logger/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
121
  instant_python/templates/boilerplate/logger/json_formatter.py,sha256=8usKxcT3-dZ7CeRExOES7NVq13pXmJnGVZyw129CDJ0,383
122
- instant_python/templates/boilerplate/logger/logger.py,sha256=6UrnlWzSepJvKmK_39cXKEHDFB6Os5s5uV4c-cjYTjc,1210
122
+ instant_python/templates/boilerplate/logger/logger.py,sha256=sjTUA1Fs8RjVnPhoWttWSywY_oLMRGkglcP0SDAgi0U,1557
123
123
  instant_python/templates/boilerplate/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
124
124
  instant_python/templates/boilerplate/persistence/alembic_migrator.py,sha256=JyS9xYe0Rv0hVLGInrY03-o3k0BpLsW12OZU_HpupCE,757
125
125
  instant_python/templates/boilerplate/persistence/base.py,sha256=AmKqS3E-iJCwkuO3GAoRBzCan0--CeFykadTHJoMz7s,77
@@ -156,7 +156,7 @@ instant_python/templates/project_structure/async_alembic.yml.j2,sha256=7OdjRGXHF
156
156
  instant_python/templates/project_structure/async_sqlalchemy.yml.j2,sha256=XaOKwRBZOyR1JOtY53KB8WizzESF5VmaTPfk36vft1s,459
157
157
  instant_python/templates/project_structure/event_bus_domain.yml.j2,sha256=kqnY9EZaZ2O3HWaQb16jISpR287tBAKxyiq6IaPt1PA,769
158
158
  instant_python/templates/project_structure/event_bus_infra.yml.j2,sha256=pCKtjiIfi6VSBdM7n1QL7lQgM-lRqm2_7eOXYOstwaQ,971
159
- instant_python/templates/project_structure/fastapi_app.yml.j2,sha256=e3n1OXSea7LkOPlRCIbKwzyT6n-Y_YhSXwF1-TWX34Y,217
159
+ instant_python/templates/project_structure/fastapi_app.yml.j2,sha256=mdDhcQHdPltJ0bGylGHOd-P3GrIQOsbdR1KLDt65gp0,292
160
160
  instant_python/templates/project_structure/fastapi_domain.yml.j2,sha256=21fFqN6Ncm_9pQ5eUH2mwZe73B8d3YGf7q4cSebBQfw,149
161
161
  instant_python/templates/project_structure/fastapi_infra.yml.j2,sha256=VJg6fLYL20iYugnE-Q4QpZg7TfM62zKdkuAxE_gWWmI,223
162
162
  instant_python/templates/project_structure/github_action.yml.j2,sha256=rMEddCYNUWE3kda2LhBu85FpxEWHZqQrOPBTm8mekkk,513
@@ -174,17 +174,17 @@ instant_python/templates/project_structure/readme.yml.j2,sha256=Km1zSVKfGwx7GHn0
174
174
  instant_python/templates/project_structure/synchronous_sqlalchemy.yml.j2,sha256=mC7WBchO0bzHcGkTw0k4woDstUvoQaJKlrCW82A96o8,467
175
175
  instant_python/templates/project_structure/value_objects.yml.j2,sha256=X5AyyZoRllCYdvRUaXSYlcZk_EQg2OyfdCS8pejjFpc,963
176
176
  instant_python/templates/project_structure/clean_architecture/main_structure.yml.j2,sha256=hh4bYTAmrOPWugWqDXX3qPrRJiTUG8iUNPKSo2RBwfQ,1395
177
- instant_python/templates/project_structure/clean_architecture/source.yml.j2,sha256=EOlKRnuYigc49LqLFhCKlCrfrdW673doyGryWnQhHhU,2505
177
+ instant_python/templates/project_structure/clean_architecture/source.yml.j2,sha256=dwMKp9C5U_KIIoH6FeM3jsHBlscmIbijGRCbXG5yt_M,2459
178
178
  instant_python/templates/project_structure/clean_architecture/test.yml.j2,sha256=q2Yqa4SXgEkg_xErGgESkObhRhPluA1fzKJgPMNIEOk,580
179
179
  instant_python/templates/project_structure/domain_driven_design/bounded_context.yml.j2,sha256=BTuT5fQBdw4o3Ev-iN8THAr2-bLlLG8mgLpbQOcL0x4,471
180
180
  instant_python/templates/project_structure/domain_driven_design/main_structure.yml.j2,sha256=NxA5Nw84DvJvfnag6-9jssZbe416fHXBzq4u1WeiDEY,1399
181
- instant_python/templates/project_structure/domain_driven_design/source.yml.j2,sha256=L5N-C5EAQI8Nn4Nx6zEgTeaDbxHEm-zLKGEoFIcsdqA,2997
181
+ instant_python/templates/project_structure/domain_driven_design/source.yml.j2,sha256=YawrDcKYGcMIPsjEuCz2O2hXAOn_i1R4cxPXzvpC09o,2951
182
182
  instant_python/templates/project_structure/domain_driven_design/test.yml.j2,sha256=sUVO0jWeDEoShMXIDSTBw-14vStjoHCcTm5DuuI9V2A,841
183
183
  instant_python/templates/project_structure/standard_project/main_structure.yml.j2,sha256=Gy11qNOtTDzGgIbhDPmAUkipmjwJPHa33-_WL_xlR3U,1381
184
- instant_python/templates/project_structure/standard_project/source.yml.j2,sha256=8QdB1AY22BzHRCidNdEJ9a6PRzq9ZWRPKIpqyoD6tmE,1748
184
+ instant_python/templates/project_structure/standard_project/source.yml.j2,sha256=THNSxD_6mMd-oCzaGYkrHlTiRWzkN6X3X6cYi2cbyMk,1702
185
185
  instant_python/templates/project_structure/standard_project/test.yml.j2,sha256=NxzsDeBKYzNaR3t8BY2VOuyhzwlp3Pa49OQNDF78gas,381
186
- instant_python-0.8.1.dist-info/METADATA,sha256=jT6iuf8_jJ4N0EEa0D_F97Aiidm-O7Br12A1wJSQ5NY,17627
187
- instant_python-0.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
188
- instant_python-0.8.1.dist-info/entry_points.txt,sha256=EdBTj3b3N9Pa4oNzPLPivE_AnMcQIFsmRC3RsSkoLLA,47
189
- instant_python-0.8.1.dist-info/licenses/LICENSE,sha256=kf7wA-1IsqXkzXjlsG95sdQJtsqUON_lNXombfPlklo,11353
190
- instant_python-0.8.1.dist-info/RECORD,,
186
+ instant_python-0.8.2.dist-info/METADATA,sha256=S2kopLLkcD5KPbNHzGWAXM-pMPSEpJwOisBHBq-Pdyo,17627
187
+ instant_python-0.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
188
+ instant_python-0.8.2.dist-info/entry_points.txt,sha256=EdBTj3b3N9Pa4oNzPLPivE_AnMcQIFsmRC3RsSkoLLA,47
189
+ instant_python-0.8.2.dist-info/licenses/LICENSE,sha256=kf7wA-1IsqXkzXjlsG95sdQJtsqUON_lNXombfPlklo,11353
190
+ instant_python-0.8.2.dist-info/RECORD,,