yhttp 7.3.2__tar.gz → 7.4.0__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 (57) hide show
  1. {yhttp-7.3.2/yhttp.egg-info → yhttp-7.4.0}/PKG-INFO +2 -2
  2. {yhttp-7.3.2 → yhttp-7.4.0}/setup.py +1 -1
  3. yhttp-7.4.0/tests/test_builtincli_yhttp_version.py +12 -0
  4. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_guard_body.py +51 -0
  5. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/guard.py +38 -0
  6. yhttp-7.4.0/yhttp/core/version.py +1 -0
  7. {yhttp-7.3.2 → yhttp-7.4.0/yhttp.egg-info}/PKG-INFO +2 -2
  8. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp.egg-info/SOURCES.txt +1 -0
  9. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp.egg-info/requires.txt +1 -1
  10. yhttp-7.3.2/yhttp/core/version.py +0 -1
  11. {yhttp-7.3.2 → yhttp-7.4.0}/LICENSE +0 -0
  12. {yhttp-7.3.2 → yhttp-7.4.0}/README.md +0 -0
  13. {yhttp-7.3.2 → yhttp-7.4.0}/setup.cfg +0 -0
  14. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_application.py +0 -0
  15. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_applicationcli.py +0 -0
  16. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_builtincli_serve.py +0 -0
  17. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_builtincli_version.py +0 -0
  18. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_cookie.py +0 -0
  19. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_exceptions.py +0 -0
  20. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_extension.py +0 -0
  21. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_form.py +0 -0
  22. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_form_json.py +0 -0
  23. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_form_multipart.py +0 -0
  24. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_form_urlencoded.py +0 -0
  25. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_guard.py +0 -0
  26. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_guard_query.py +0 -0
  27. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_headerset.py +0 -0
  28. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_httpstatus.py +0 -0
  29. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_jsonencoding.py +0 -0
  30. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_lazyattribute.py +0 -0
  31. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_multidict.py +0 -0
  32. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_multipart.py +0 -0
  33. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_querystring.py +0 -0
  34. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_request.py +0 -0
  35. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_responseheaders.py +0 -0
  36. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_rewrite.py +0 -0
  37. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_rewritecli.py +0 -0
  38. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_routing.py +0 -0
  39. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_static.py +0 -0
  40. {yhttp-7.3.2 → yhttp-7.4.0}/tests/test_statuscode.py +0 -0
  41. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/__init__.py +0 -0
  42. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/application.py +0 -0
  43. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/cli.py +0 -0
  44. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/contenttypes.py +0 -0
  45. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/headerset.py +0 -0
  46. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/lazyattribute.py +0 -0
  47. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/main.py +0 -0
  48. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/multidict.py +0 -0
  49. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/multipart.py +0 -0
  50. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/request.py +0 -0
  51. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/response.py +0 -0
  52. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/rewrite.py +0 -0
  53. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/static.py +0 -0
  54. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp/core/statuses.py +0 -0
  55. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp.egg-info/dependency_links.txt +0 -0
  56. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp.egg-info/entry_points.txt +0 -0
  57. {yhttp-7.3.2 → yhttp-7.4.0}/yhttp.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yhttp
3
- Version: 7.3.2
3
+ Version: 7.4.0
4
4
  Summary: A very micro http framework.
5
5
  Home-page: http://github.com/yhttp/yhttp
6
6
  Author: Vahid Mardani
@@ -23,7 +23,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: pymlconf<4,>=3.0.1
26
- Requires-Dist: easycli<2,>=1.9.5
26
+ Requires-Dist: easycli<2,>=1.9.6
27
27
  Requires-Dist: ujson
28
28
  Dynamic: author
29
29
  Dynamic: author-email
@@ -16,7 +16,7 @@ with open(
16
16
 
17
17
  dependencies = [
18
18
  'pymlconf >= 3.0.1, < 4',
19
- 'easycli >= 1.9.5, < 2',
19
+ 'easycli >= 1.9.6, < 2',
20
20
  'ujson',
21
21
  ]
22
22
 
@@ -0,0 +1,12 @@
1
+ from bddcli import Application as CLIApplication, Given, stderr, stdout, status
2
+
3
+ from yhttp.core import __version__
4
+
5
+
6
+ def test_yhttp_version_cli():
7
+ cliapp = CLIApplication('yhttp', 'yhttp.core.main:app.climain')
8
+
9
+ with Given(cliapp, '--version'):
10
+ assert status == 0
11
+ assert stdout.strip() == __version__
12
+ assert stderr == ''
@@ -1,6 +1,9 @@
1
+ import io
2
+
1
3
  from bddrest import status, given, when, response
2
4
 
3
5
  from yhttp.core import statuses, guard as g, json
6
+ from yhttp.core.multidict import MultiDict
4
7
 
5
8
 
6
9
  def test_bodyguard_strict(app, Given):
@@ -99,3 +102,51 @@ def test_bodyguard_integer(app, Given):
99
102
 
100
103
  when(form=given | dict(bar=0))
101
104
  assert status == '400 bar: Zero Not Allowed'
105
+
106
+
107
+ def test_bodyguard_multipart(app, Given):
108
+ app.settings.debug = False
109
+ bazfile = g.File('baz')
110
+
111
+ @app.route()
112
+ @app.bodyguard(fields=(
113
+ g.String('foo'),
114
+ g.Integer('bar'),
115
+ bazfile,
116
+ ))
117
+ def post(req):
118
+ assert req.contenttype.startswith('multipart/form')
119
+ assert req.files is not None
120
+ assert isinstance(req.files, MultiDict)
121
+ assert req.form['foo'] == 'FOO'
122
+ assert req.form['bar'] == 73
123
+ assert req.files['baz']
124
+
125
+ @app.route()
126
+ @app.bodyguard(fields=(
127
+ g.String('foo'),
128
+ g.Integer('bar'),
129
+ bazfile(optional=True),
130
+ ))
131
+ def put(req):
132
+ assert req.contenttype.startswith('multipart/form')
133
+ assert req.files is not None
134
+ assert isinstance(req.files, MultiDict)
135
+ assert req.form['foo'] == 'FOO'
136
+ assert req.form['bar'] == 73
137
+ if 'baz' in req.files:
138
+ assert req.files['baz']
139
+
140
+ form = dict(
141
+ foo='FOO',
142
+ bar='73',
143
+ baz=io.BytesIO(b'foobarbaz'),
144
+ )
145
+ with Given(verb='post', multipart=form):
146
+ assert status == 200
147
+
148
+ when(multipart=given - 'baz')
149
+ assert status == 400
150
+
151
+ when(verb='PUT', multipart=given - 'baz')
152
+ assert status == 200
@@ -225,6 +225,44 @@ class Boolean(Field):
225
225
  super().validate(req, values)
226
226
 
227
227
 
228
+ class File(Field):
229
+ """Represent the guard for multipart file field.
230
+
231
+ It just checks the field with that name is exists in the request.
232
+
233
+ :param name: str, the field name.
234
+
235
+ .. versionadded: 7.4
236
+ """
237
+
238
+ def __init__(self, name, length=None, pattern=None, **kwargs):
239
+ if length:
240
+ raise NotImplementedError('length argument is not supported')
241
+
242
+ if pattern:
243
+ raise NotImplementedError('pattern argument is not supported')
244
+
245
+ super().__init__(name, **kwargs)
246
+
247
+ def __call__(self, *, length=None, pattern=None, **kwargs):
248
+ if length:
249
+ raise NotImplementedError('length argument is not supported')
250
+
251
+ if pattern:
252
+ raise NotImplementedError('pattern argument is not supported')
253
+ return super().__call__(**kwargs)
254
+
255
+ def validate(self, req, values):
256
+ if self.optional:
257
+ return
258
+
259
+ if self.name not in req.getfiles():
260
+ raise statuses.status(
261
+ self.statuscode_missing,
262
+ f'{self.name}: Required'
263
+ )
264
+
265
+
228
266
  class Guard:
229
267
  """The :class:`.guard.Guard` class is used to validate the HTTP requests.
230
268
 
@@ -0,0 +1 @@
1
+ __version__ = '7.4.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yhttp
3
- Version: 7.3.2
3
+ Version: 7.4.0
4
4
  Summary: A very micro http framework.
5
5
  Home-page: http://github.com/yhttp/yhttp
6
6
  Author: Vahid Mardani
@@ -23,7 +23,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: pymlconf<4,>=3.0.1
26
- Requires-Dist: easycli<2,>=1.9.5
26
+ Requires-Dist: easycli<2,>=1.9.6
27
27
  Requires-Dist: ujson
28
28
  Dynamic: author
29
29
  Dynamic: author-email
@@ -5,6 +5,7 @@ tests/test_application.py
5
5
  tests/test_applicationcli.py
6
6
  tests/test_builtincli_serve.py
7
7
  tests/test_builtincli_version.py
8
+ tests/test_builtincli_yhttp_version.py
8
9
  tests/test_cookie.py
9
10
  tests/test_exceptions.py
10
11
  tests/test_extension.py
@@ -1,3 +1,3 @@
1
1
  pymlconf<4,>=3.0.1
2
- easycli<2,>=1.9.5
2
+ easycli<2,>=1.9.6
3
3
  ujson
@@ -1 +0,0 @@
1
- __version__ = '7.3.2'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes