WhakerPy 2.0__py3-none-any.whl → 2.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.
whakerpy/__init__.py CHANGED
@@ -25,6 +25,6 @@ from .httpd import *
25
25
  from .messages import error
26
26
  from .webapp import *
27
27
 
28
- __version__ = "2.0"
28
+ __version__ = "2.2"
29
29
  ___author__ = "Brigitte Bigi"
30
30
  __copyright__ = "Copyright (C) 2023-2026 Brigitte Bigi, CNRS, Laboratoire Parole et Langage, Aix-en-Provence, France"
whakerpy/httpd/handler.py CHANGED
@@ -182,7 +182,9 @@ class HTTPDHandler(http.server.BaseHTTPRequestHandler):
182
182
  - extracts the query string (before path normalization),
183
183
  - applies blacklist (if enabled),
184
184
  - applies signed URL verification (if enabled),
185
- - serves static files or generated HTML pages.
185
+ - serves static files or generated HTML pages, with the query
186
+ string parsed into events exactly like a POST request body
187
+ (e.g. for a plain HTML form using method="get").
186
188
 
187
189
  """
188
190
  logging.debug(" ---- DO GET -- requested: {}".format(self.path))
@@ -214,7 +216,8 @@ class HTTPDHandler(http.server.BaseHTTPRequestHandler):
214
216
 
215
217
  # Dynamic HTML page generated by the server.
216
218
  elif mime_type == "text/html":
217
- content, status = self._bakery(handler_utils, dict(), mime_type)
219
+ events = HTTPDHandlerUtils.parse_query_string(query_string)
220
+ content, status = self._bakery(handler_utils, events, mime_type)
218
221
 
219
222
  # Unknown mime type: try to get a static file anyway.
220
223
  else:
whakerpy/httpd/hutils.py CHANGED
@@ -190,16 +190,36 @@ class HTTPDHandlerUtils:
190
190
  # STATIC METHODS
191
191
  # -----------------------------------------------------------------------
192
192
 
193
+ @staticmethod
194
+ def parse_query_string(query_string: str) -> dict:
195
+ """Parse a URL query string into a dictionary of events.
196
+
197
+ Allows a GET request to carry data the very same way a POST does,
198
+ e.g. for a plain HTML form using method="get".
199
+
200
+ :param query_string: (str) The query string of the request (without the leading '?').
201
+ :return: (dict) key=parameter name, value=parameter value
202
+
203
+ """
204
+ if query_string is None or len(query_string) == 0:
205
+ return dict()
206
+
207
+ return dict(parse_qsl(
208
+ query_string,
209
+ keep_blank_values=True,
210
+ strict_parsing=False # errors are silently ignored
211
+ ))
212
+
193
213
  @staticmethod
194
214
  def blacklisted_page_answer() -> tuple:
195
- """Create the response with 418 status code.
215
+ """Create the response with 418 (forbidden) status code.
196
216
 
197
217
  :return: (tuple) Response content and status to send back to the client
198
218
 
199
219
  """
200
220
  status = HTTPDStatus(418)
201
221
  content = status.to_html(encode=True,
202
- msg_error="I'm a teapot. If you are not a robot, "
222
+ msg_error="I'm a Teapot. If you are not a robot, "
203
223
  "send an e-mail to the administrator.")
204
224
  return content, status
205
225
 
@@ -303,7 +323,8 @@ class HTTPDHandlerUtils:
303
323
  :param pages: (dict) A dictionary with key=page_name and value=ResponseRecipe
304
324
  :param page_name: (str) The current page name
305
325
  :param headers: (dict) The headers of the http request
306
- :param events: (dict) The events extract from the request (only for POST request, send empty dict for GET)
326
+ :param events: (dict) The events extracted from the request: the POST body,
327
+ or the GET query string, parsed the same way
307
328
  :param has_to_return_data: (bool) False by default, Boolean to know if we have to return the html page or data
308
329
  :return: (tuple[bytes, HTTPDStatus]) The content to answer to the client and the status of the response
309
330
 
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: WhakerPy
3
- Version: 2.0
3
+ Version: 2.2
4
4
  Summary: Web HTML maker in Python - a light web application framework
5
5
  Author-email: Brigitte Bigi <contact@sppas.org>
6
- Project-URL: Homepage, https://sourceforge.net/projects/whakerpy/
7
- Project-URL: Documentation, https://whakerpy.sourceforge.io
6
+ Project-URL: Repo, https://github.com/brigitte-bigi/WhakerPy
7
+ Project-URL: Doc, https://brigitte-bigi.github.io/WhakerPy/
8
8
  Project-URL: Pypi, https://pypi.org/project/whakerpy/
9
- Project-URL: Repository, https://git.code.sf.net/p/whakerpy/code
10
9
  Keywords: python,html,httpd,dynamic,web,app,ui
11
10
  Classifier: Programming Language :: Python :: 3
12
11
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
@@ -23,10 +22,9 @@ License-File: AUTHORS.md
23
22
  Provides-Extra: docs
24
23
  Requires-Dist: pygments; extra == "docs"
25
24
  Requires-Dist: markdown2; extra == "docs"
26
- Requires-Dist: ClammingPy>=1.9; extra == "docs"
25
+ Requires-Dist: ClammingPy>=2.2; extra == "docs"
27
26
  Provides-Extra: tests
28
27
  Requires-Dist: coverage~=7.3.0; extra == "tests"
29
- Requires-Dist: selenium~=4.18.1; extra == "tests"
30
28
  Requires-Dist: python-dotenv~=1.0.0; extra == "tests"
31
29
  Dynamic: license-file
32
30
 
@@ -213,7 +211,7 @@ Other projects:
213
211
 
214
212
  - the website <https://auto-cuedspeech.org>
215
213
  - the website <https://sppas.org>
216
- - the 'setup' application of SPPAS
214
+ - the web appis of SPPAS
217
215
  - the intranet of the Laboratoire Parole et Langage
218
216
  - *contact the author if your project is based on WhakerPy*
219
217
 
@@ -315,4 +313,4 @@ or products, in accordance with the best practices of the AGPL license.
315
313
  Use the following reference to cite WhakerPy:
316
314
 
317
315
  > Brigitte Bigi. WhakerPy, a Python library to create dynamic HTML content and
318
- > web applications. Version 1.5. 2024. <https://hal.science/hal-04743687>
316
+ > web applications. Version 1.x. 202x. <https://hal.science/hal-04743687>
@@ -1,6 +1,6 @@
1
1
  sample/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  sample/response.py,sha256=_jAaWLrHuGBYy0Y0aywxGrSDX365MSfASqWTISIotqw,12532
3
- whakerpy/__init__.py,sha256=EfSSUbTb8WVMCd-Ul9KCeF1YC6hocq4XIj6NjKgJFT0,1827
3
+ whakerpy/__init__.py,sha256=DA3YMbr2kjiqkDY-v5PFzQu-OWWw3PAUtzgSkdXVJDQ,1827
4
4
  whakerpy/messages.py,sha256=NSnQYFfarU16T59Zryuy2g2x7UwA8xgY_UDwRLQqPm4,2385
5
5
  whakerpy/htmlmaker/__init__.py,sha256=zCHYhW37cyK68u90w2tFBLJx59ApGvqgNkxiIzuVtTM,3333
6
6
  whakerpy/htmlmaker/hconsts.py,sha256=6I0Mmp72ZBzePGw-nH4qjD7TvENxXUPAT-qTeljwGe8,12115
@@ -18,23 +18,23 @@ whakerpy/htmlmaker/htmnodes/__init__.py,sha256=hOrs9nhL2aMCvukuPoOxRdinPAK_QFpWB
18
18
  whakerpy/htmlmaker/htmnodes/htmelts.py,sha256=CTLX6hQWpulJuwW5F75gLTbKiiERkAkRLZ0LiHz9_lE,5398
19
19
  whakerpy/htmlmaker/htmnodes/htmnode.py,sha256=gM3c-9dj9kBO_8JGHOqca1ZDIOWdEgNy1_BIwcUtDqI,11603
20
20
  whakerpy/httpd/__init__.py,sha256=A4_Y6oN-8PY3TmGssX6DGKlUsE0wAGsNc5N1oo8HDK8,2031
21
- whakerpy/httpd/handler.py,sha256=nqJqzED2Gbei73a6e-L0anh0JvY_vPANWHPe7BgmYt4,10785
21
+ whakerpy/httpd/handler.py,sha256=EecczKlv8HMTWthJgXJLRLGlgTELnYnUmoTa1LkGR14,11007
22
22
  whakerpy/httpd/hblacklist.py,sha256=H9-hhLGx9StYGo7ThBs23dVuqNRTveGvkt_SftH_oIc,6605
23
23
  whakerpy/httpd/hpolicy.py,sha256=LZBY3eSz9xrpPUlV-ymQxdx34LN33acX9SBsqaNVrm0,9827
24
24
  whakerpy/httpd/hresponse.py,sha256=bjv-PS0xQ3RR7z9XvzOptxWkSdmlutRuFWqgdUqmDVI,9412
25
25
  whakerpy/httpd/hserver.py,sha256=1X8lGKIZNBFyoNHcLHtQPkOkEORvZ19HLGahOeE8uiY,6302
26
26
  whakerpy/httpd/hsignedurl.py,sha256=ZLGENB3-Y1jOANaMP0E71s3xqFmdbBb8hgJf7IODG1g,13295
27
27
  whakerpy/httpd/hstatus.py,sha256=rrWDvPXTyAh8l4IJY0xBDkZxeKC7t3_5-XlVHtUDSo8,7998
28
- whakerpy/httpd/hutils.py,sha256=O4qv2XXy1HBA7HxXdXNSRkc2gdqGeocHWyt4HZy1TQ0,27872
28
+ whakerpy/httpd/hutils.py,sha256=C7gkMka-dEpK_Bt6RhCSDdrSjZO1sgZkuAMIWTPSZSk,28631
29
29
  whakerpy/httpd/permissions.py,sha256=PNl2XQwYtpJVzXaPgWVT-2TqnN8jsr-b6ZhZasFbono,8463
30
30
  whakerpy/webapp/__init__.py,sha256=FCeq1HYEqFhGyquWajWVhWJbAsOYihBedtdUwpnQvis,276
31
31
  whakerpy/webapp/webconfig.py,sha256=8JAWncQip-uAeLQaIWzcmZIczRWlaKRbR5ZJAdEPoWs,11222
32
32
  whakerpy/webapp/weblocalserver.py,sha256=XjtVkUQPeFsVvX4ARLc_2_9eqc2KBmuQHMlxbr7DMUE,3180
33
33
  whakerpy/webapp/webresponse.py,sha256=q4p12QHRFmq52K0lLkdqPJfexkG2SqZLluYF7Zg406g,4430
34
34
  whakerpy/webapp/webwsgi.py,sha256=wmdN5MemNqFqrOhQVlpvp0-XSCGGdQ3SF8H4_qJMNG4,11554
35
- whakerpy-2.0.dist-info/licenses/AUTHORS.md,sha256=VrCusdQ56bvNDiq7w_MA5mZoZXuP_JOG-ybTwpRT_u4,805
36
- whakerpy-2.0.dist-info/licenses/LICENSE.md,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
37
- whakerpy-2.0.dist-info/METADATA,sha256=jpxJ9P9R4qh7w5fljLcRxaTl7eGaPCOmuvCiSqQVV44,12185
38
- whakerpy-2.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
39
- whakerpy-2.0.dist-info/top_level.txt,sha256=ZqGTnE-rI2S_jcI0kxnNeKd0z25TBv8Vkbe2iJ74-E0,16
40
- whakerpy-2.0.dist-info/RECORD,,
35
+ whakerpy-2.2.dist-info/licenses/AUTHORS.md,sha256=VrCusdQ56bvNDiq7w_MA5mZoZXuP_JOG-ybTwpRT_u4,805
36
+ whakerpy-2.2.dist-info/licenses/LICENSE.md,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
37
+ whakerpy-2.2.dist-info/METADATA,sha256=9UQr1f52WX1jijHmnoYZ9HNca3CVU9OPA74smalza_I,12055
38
+ whakerpy-2.2.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
39
+ whakerpy-2.2.dist-info/top_level.txt,sha256=ZqGTnE-rI2S_jcI0kxnNeKd0z25TBv8Vkbe2iJ74-E0,16
40
+ whakerpy-2.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.0)
2
+ Generator: setuptools (83.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5