hyperflask 0.4.4__tar.gz → 0.5.1__tar.gz

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.
Files changed (122) hide show
  1. {hyperflask-0.4.4 → hyperflask-0.5.1}/PKG-INFO +3 -2
  2. {hyperflask-0.4.4 → hyperflask-0.5.1}/pyproject.toml +3 -2
  3. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/app.py +12 -3
  4. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/cli/runner.py +17 -12
  5. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/components/core.py +2 -2
  6. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/components/jsx.py +2 -2
  7. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/components/webcomponent.py +2 -2
  8. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/layouts/web.html +1 -1
  9. hyperflask-0.5.1/src/hyperflask/utils/image.py +26 -0
  10. {hyperflask-0.4.4 → hyperflask-0.5.1}/README.md +0 -0
  11. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/__init__.py +0 -0
  12. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/__main__.py +0 -0
  13. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/actors.py +0 -0
  14. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/cli/__init__.py +0 -0
  15. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/cli/reloader.py +0 -0
  16. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/cli/worker.py +0 -0
  17. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/components/__init__.py +0 -0
  18. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/components/alpine.py +0 -0
  19. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/factory.py +0 -0
  20. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/forms/__init__.py +0 -0
  21. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/forms/fields.py +0 -0
  22. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/forms/widgets.py +0 -0
  23. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/layouts/email.mjml +0 -0
  24. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/model.py +0 -0
  25. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/page_helpers.py +0 -0
  26. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/security.py +0 -0
  27. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/alpine-csp.js +0 -0
  28. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/alpine.js +0 -0
  29. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/app.css +0 -0
  30. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/app.js +0 -0
  31. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/htmx-exts.js +0 -0
  32. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/react.js +0 -0
  33. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/stimulus.js +0 -0
  34. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/static/translations.js +0 -0
  35. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Accordion.html +0 -0
  36. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/AccordionPanel.html +0 -0
  37. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Alert.html +0 -0
  38. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Avatar.html +0 -0
  39. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/AvatarGroup.html +0 -0
  40. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Badge.html +0 -0
  41. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Breadcrumbs.html +0 -0
  42. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/BreadcrumbsItem.html +0 -0
  43. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Button.html +0 -0
  44. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Card.html +0 -0
  45. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/CardActions.html +0 -0
  46. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/CardTitle.html +0 -0
  47. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/ChatBubble.html +0 -0
  48. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Checkbox.html +0 -0
  49. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/CollapsibleSubMenu.html +0 -0
  50. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Countdown.html +0 -0
  51. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Divider.html +0 -0
  52. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Drawer.html +0 -0
  53. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/DrawerContent.html +0 -0
  54. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/DrawerSide.html +0 -0
  55. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Dropdown.html +0 -0
  56. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/DropdownItem.html +0 -0
  57. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Fieldset.html +0 -0
  58. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/FieldsetLegend.html +0 -0
  59. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/FileInput.html +0 -0
  60. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Filter.html +0 -0
  61. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/FilterItem.html +0 -0
  62. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Footer.html +0 -0
  63. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/FooterLink.html +0 -0
  64. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/FooterNav.html +0 -0
  65. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Indicator.html +0 -0
  66. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Input.html +0 -0
  67. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/InputLabel.html +0 -0
  68. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Join.html +0 -0
  69. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Kbd.html +0 -0
  70. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Label.html +0 -0
  71. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/LabeledCheckbox.html +0 -0
  72. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/LabeledToggle.html +0 -0
  73. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Link.html +0 -0
  74. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/List.html +0 -0
  75. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/ListItem.html +0 -0
  76. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Loading.html +0 -0
  77. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Menu.html +0 -0
  78. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/MenuItem.html +0 -0
  79. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/MenuTitle.html +0 -0
  80. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Modal.html +0 -0
  81. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/ModalAction.html +0 -0
  82. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/ModalTitle.html +0 -0
  83. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Navbar.html +0 -0
  84. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Pagination.html +0 -0
  85. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/PaginationNext.html +0 -0
  86. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/PaginationPage.html +0 -0
  87. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/PaginationPrev.html +0 -0
  88. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Progress.html +0 -0
  89. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/README.md +0 -0
  90. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Radio.html +0 -0
  91. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Range.html +0 -0
  92. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Rating.html +0 -0
  93. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Select.html +0 -0
  94. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Stack.html +0 -0
  95. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Stat.html +0 -0
  96. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Stats.html +0 -0
  97. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Step.html +0 -0
  98. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Steps.html +0 -0
  99. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/SubMenu.html +0 -0
  100. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Swap.html +0 -0
  101. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Tab.html +0 -0
  102. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Table.html +0 -0
  103. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Tabs.html +0 -0
  104. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Textarea.html +0 -0
  105. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Toast.html +0 -0
  106. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Toggle.html +0 -0
  107. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/daisyui/Tooltip.html +0 -0
  108. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/flash.html +0 -0
  109. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/forms.html +0 -0
  110. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/icons.html +0 -0
  111. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/layout.html +0 -0
  112. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/modal.html +0 -0
  113. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/skeleton.html +0 -0
  114. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/ui/sse.html +0 -0
  115. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/__init__.py +0 -0
  116. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/freezer.py +0 -0
  117. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/html.py +0 -0
  118. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/htmx.py +0 -0
  119. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/markdown.py +0 -0
  120. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/metadata.py +0 -0
  121. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/page_actions.py +0 -0
  122. {hyperflask-0.4.4 → hyperflask-0.5.1}/src/hyperflask/utils/tokens.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperflask
3
- Version: 0.4.4
3
+ Version: 0.5.1
4
4
  Summary: Full stack web framework
5
5
  Author: Maxime Bouroumeau-Fuseau
6
6
  Author-email: Maxime Bouroumeau-Fuseau <maxime.bouroumeau@gmail.com>
7
7
  License-Expression: MIT
8
8
  Requires-Dist: flask>=3.0.0,<4.0.0
9
- Requires-Dist: flask-assets-pipeline~=0.7
9
+ Requires-Dist: flask-assets-pipeline~=0.8
10
10
  Requires-Dist: flask-babel-hyper~=5.1
11
11
  Requires-Dist: flask-collections~=0.3
12
12
  Requires-Dist: flask-configurator~=0.1
@@ -32,6 +32,7 @@ Requires-Dist: jinja-wtforms~=0.2
32
32
  Requires-Dist: periodiq~=0.13
33
33
  Requires-Dist: python-slugify~=8.0.4
34
34
  Requires-Dist: watchdog>=6.0.0
35
+ Requires-Dist: pillow>=11.3.0
35
36
  Requires-Python: >=3.10
36
37
  Project-URL: Repository, https://github.com/hyperflask/hyperflask
37
38
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyperflask"
3
- version = "0.4.4"
3
+ version = "0.5.1"
4
4
  description = "Full stack web framework"
5
5
  authors = [
6
6
  {"name" = "Maxime Bouroumeau-Fuseau", email = "maxime.bouroumeau@gmail.com"}
@@ -10,7 +10,7 @@ license = "MIT"
10
10
  requires-python = ">=3.10"
11
11
  dependencies = [
12
12
  "flask>=3.0.0,<4.0.0",
13
- "flask-assets-pipeline ~=0.7",
13
+ "flask-assets-pipeline ~=0.8",
14
14
  "flask-babel-hyper ~=5.1",
15
15
  "flask-collections ~=0.3",
16
16
  "flask-configurator ~=0.1",
@@ -37,6 +37,7 @@ dependencies = [
37
37
  "periodiq ~=0.13",
38
38
  "python-slugify ~=8.0.4",
39
39
  "watchdog>=6.0.0",
40
+ "pillow>=11.3.0",
40
41
  ]
41
42
 
42
43
  [tool.uv.sources]
@@ -31,6 +31,7 @@ from .utils.markdown import jinja_markdown, MarkdownExtension
31
31
  from .utils.html import sanitize_html, nl2br
32
32
  from .utils.metadata import metadata_tags
33
33
  from .utils.freezer import StaticMode, Freezer, freezer_url_generator
34
+ from .utils.image import image_tag
34
35
  from .components import register_components
35
36
  from .model import Model, File as SQLFileType, UndefinedDatabase
36
37
  from .actors import AppContextMiddleware, discover_broker, make_actor_decorator
@@ -95,7 +96,9 @@ class Hyperflask(Flask):
95
96
  "CSP_FRAME_ANCESTORS": True,
96
97
  "CSP_FRAME_ANCESTORS_SAFE_ENDPOINTS": [],
97
98
  "REFERRER_POLICY": "strict-origin-when-cross-origin",
98
- "HSTS_HEADER": False
99
+ "HSTS_HEADER": False,
100
+ "IMAGES_DEFAULT_LOADING": "lazy",
101
+ "IMAGES_DEFAULT_DECODING": "async",
99
102
  })
100
103
  if config:
101
104
  self.config.update(config)
@@ -126,8 +129,13 @@ class Hyperflask(Flask):
126
129
  self.jinja_env.add_extension(LayoutExtension)
127
130
  self.jinja_env.add_extension(WtformExtension)
128
131
  self.jinja_env.add_extension(MarkdownExtension)
129
- self.jinja_env.filters.update(markdown=jinja_markdown, sanitize=sanitize_html, nl2br=nl2br)
130
- self.jinja_env.globals.update(page_action_url=page_action_url, app=self, csp_nonce=csp_nonce, metadata_tags=metadata_tags)
132
+ self.jinja_env.filters.update(markdown=jinja_markdown,
133
+ sanitize=sanitize_html,
134
+ nl2br=nl2br)
135
+ self.jinja_env.globals.update(page_action_url=page_action_url,
136
+ app=self,
137
+ csp_nonce=csp_nonce,
138
+ metadata_tags=metadata_tags)
131
139
  self.jinja_env.form_base_cls = Form
132
140
  self.jinja_env.default_layout = self.config["LAYOUT"]
133
141
  self.forms = self.jinja_env.forms
@@ -197,6 +205,7 @@ class Hyperflask(Flask):
197
205
  if hasattr(file_routes, "loader"):
198
206
  self.forms.register_from_loader(file_routes.loader, "pages")
199
207
  self.macros.create_from_func(htmx_oob, "HtmxOob", receive_caller=True, caller_alias="html")
208
+ self.macros.create_from_func(image_tag, "Image")
200
209
 
201
210
  self.components_loader, _ = register_components(self)
202
211
  if self.components_loader:
@@ -12,9 +12,14 @@ from . import reloader # import hacky patch of werkzeug reloader
12
12
 
13
13
  @click.command("serve")
14
14
  @click.option('--gunicorn-opt', multiple=True)
15
+ @click.option("--init-db", is_flag=True)
15
16
  @pass_script_info
16
17
  @click.pass_context
17
- def serve_command(ctx, info, host, port, gunicorn_opt, **run_kwargs):
18
+ def serve_command(ctx, info, host, port, gunicorn_opt, init_db, **run_kwargs):
19
+ if init_db:
20
+ print("Initializing database...")
21
+ Popen([sys.argv[0], "db", "init"]).wait()
22
+
18
23
  if os.environ.get("FLASK_DEBUG") == "1":
19
24
  ctx.invoke(flask_run_command, host=host, port=port, **run_kwargs)
20
25
  else:
@@ -59,6 +64,10 @@ def run_command(processes, host, port, concurrency, extend_procfile, init_db, de
59
64
  procfile = None
60
65
  config = load_config()
61
66
 
67
+ if not dev and not config.get('SECRET_KEY'):
68
+ print("Critical: No SECRET_KEY set, cannot run in production mode.")
69
+ sys.exit(1)
70
+
62
71
  for filename in [f"Procfile.{config['ENV']}", "Procfile"]:
63
72
  if os.path.exists(filename):
64
73
  with open(filename) as f:
@@ -75,16 +84,6 @@ def run_command(processes, host, port, concurrency, extend_procfile, init_db, de
75
84
  _processes["worker"].extend(["-p", "1", "-t", "1"])
76
85
  else:
77
86
  _processes["mercurehub"] = [sys.executable, "-m", "flask_mercure_sse.server", "--port", "$PORT"]
78
- subscriber_secret_key = config.get("MERCURE_SUBSCRIBER_SECRET_KEY", config.get('SECRET_KEY'))
79
- if subscriber_secret_key:
80
- _processes["mercurehub"].extend(["--subscriber-secret", subscriber_secret_key])
81
- else:
82
- print("Warning: No MERCURE_SUBSCRIBER_SECRET_KEY or SECRET_KEY set, Mercure subscriber will not be authenticated.")
83
- publisher_secret_key = config.get("MERCURE_PUBLISHER_SECRET_KEY", config.get('SECRET_KEY'))
84
- if publisher_secret_key:
85
- _processes["mercurehub"].extend(["--publisher-secret", publisher_secret_key])
86
- else:
87
- print("Warning: No MERCURE_PUBLISHER_SECRET_KEY or SECRET_KEY set, cannot publish Mercure messages.")
88
87
 
89
88
  if procfile and extend_procfile:
90
89
  _processes.update(procfile)
@@ -93,13 +92,19 @@ def run_command(processes, host, port, concurrency, extend_procfile, init_db, de
93
92
 
94
93
  processes = {name: " ".join(_processes[name]) if isinstance(_processes[name], list) else _processes[name]
95
94
  for name in _processes if not processes or name in processes}
95
+ env = {}
96
+ if not dev:
97
+ env = {
98
+ "MERCURE_SUBSCRIBER_SECRET_KEY": config.get("MERCURE_SUBSCRIBER_SECRET_KEY", config['SECRET_KEY']),
99
+ "MERCURE_PUBLISHER_SECRET_KEY": config.get("MERCURE_PUBLISHER_SECRET_KEY", config['SECRET_KEY']),
100
+ }
96
101
 
97
102
  manager = ProcessManager(Printer(sys.stdout, colour=True))
98
-
99
103
  for p in environ.expand_processes(processes,
100
104
  concurrency=_parse_concurrency(concurrency),
101
105
  port=port):
102
106
  e = os.environ.copy()
107
+ e.update(env)
103
108
  e.update(p.env)
104
109
  manager.add_process(p.name, p.cmd, quiet=p.quiet, env=e)
105
110
 
@@ -7,7 +7,6 @@ from jinjapy import extract_frontmatter
7
7
  from ..utils.freezer import dynamic
8
8
  import importlib
9
9
  import re
10
- import os
11
10
 
12
11
 
13
12
  class BaseComponentAdapter:
@@ -71,8 +70,9 @@ class ComponentAdapter(BaseComponentAdapter):
71
70
  source, frontmatter = extract_frontmatter(f.read())
72
71
  if not self.template:
73
72
  frontmatter = source
73
+ if not frontmatter:
74
+ return []
74
75
  return [m.upper() for m in http_method_funcs if re.search(rf"^(def\s+{m}\()|{m}\s*=", frontmatter, re.MULTILINE)]
75
- return []
76
76
 
77
77
  def render(self, *args, **kwargs):
78
78
  caller = kwargs.pop('caller', None)
@@ -1,7 +1,7 @@
1
1
  from .core import BaseComponentAdapter
2
2
  from markupsafe import Markup
3
3
  from flask import current_app
4
- from flask_assets_pipeline import Entrypoint
4
+ from flask_assets_pipeline import BundleEntrypoint
5
5
  import json
6
6
  import html
7
7
 
@@ -13,7 +13,7 @@ class JsxComponentAdapter(BaseComponentAdapter):
13
13
  app.assets.state.bundles["@components"] = []
14
14
  app.assets.include("@components")
15
15
  app.assets.state.bundles["@components"].append(
16
- Entrypoint.create(self.template, from_package="jinja"))
16
+ BundleEntrypoint.create(self.template, from_package="jinja"))
17
17
  app.assets.include(self.include_js)
18
18
 
19
19
  def render(self, caller, *args, **kwargs):
@@ -1,6 +1,6 @@
1
1
  from .core import BaseComponentAdapter
2
2
  from jinja_super_macros import html_tag
3
- from flask_assets_pipeline import Entrypoint
3
+ from flask_assets_pipeline import BundleEntrypoint
4
4
  from markupsafe import Markup
5
5
  import os
6
6
 
@@ -17,7 +17,7 @@ class WebComponentAdapter(BaseComponentAdapter):
17
17
  app.assets.state.bundles["@components"] = []
18
18
  app.assets.include("@components")
19
19
  app.assets.state.bundles["@components"].append(
20
- Entrypoint.create(os.path.abspath(tpl.filename), self.template))
20
+ BundleEntrypoint.create(os.path.abspath(tpl.filename), self.template))
21
21
 
22
22
  def render(self, caller, *args, **kwargs):
23
23
  tag_name = self.name.replace("_", "-")
@@ -5,7 +5,7 @@
5
5
  {% block head_metas %}
6
6
  {{ metadata_tags(page.get('metadata', {})) }}
7
7
  {% endblock %}
8
- {% asset_tags nonce=csp_nonce %}
8
+ {% asset_tags(nonce=csp_nonce) %}
9
9
  {% block head_assets %}{% endblock %}
10
10
  {%- endblock %}
11
11
  </head>
@@ -0,0 +1,26 @@
1
+ from flask import current_app
2
+ from jinja_super_macros import html_tag
3
+ from flask_assets_pipeline import image_attrs
4
+
5
+
6
+ def image_tag(src, priority=False, preload=False, placeholder=True, loading=None, decoding=None, **attrs):
7
+ if not loading:
8
+ loading = current_app.config["IMAGES_DEFAULT_LOADING"]
9
+ if not decoding:
10
+ decoding = current_app.config["IMAGES_DEFAULT_DECODING"]
11
+ if priority:
12
+ preload = True
13
+ attrs.setdefault("fetchpriority", "high")
14
+ if preload:
15
+ current_app.assets.include([(src, {"modifier": "preload", "content_type": "image"})])
16
+ if loading == "lazy":
17
+ loading = "eager"
18
+ _attrs = image_attrs(src)
19
+ if not placeholder and "style" in _attrs:
20
+ del _attrs["style"]
21
+ if loading:
22
+ _attrs["loading"] = loading
23
+ if decoding:
24
+ _attrs["decoding"] = decoding
25
+ _attrs.update(attrs)
26
+ return html_tag("img", **_attrs)
File without changes