fresco 3.4.0__py3-none-any.whl → 3.6.0__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.
Potentially problematic release.
This version of fresco might be problematic. Click here for more details.
- fresco/__init__.py +55 -56
- fresco/core.py +36 -26
- fresco/decorators.py +6 -3
- fresco/defaults.py +1 -0
- fresco/middleware.py +45 -24
- fresco/multidict.py +35 -51
- fresco/options.py +182 -70
- fresco/py.typed +0 -0
- fresco/request.py +155 -34
- fresco/requestcontext.py +3 -0
- fresco/response.py +12 -9
- fresco/routeargs.py +23 -9
- fresco/routing.py +133 -71
- fresco/static.py +1 -1
- fresco/subrequests.py +3 -5
- fresco/tests/test_core.py +4 -4
- fresco/tests/test_multidict.py +2 -2
- fresco/tests/test_options.py +59 -15
- fresco/tests/test_request.py +21 -10
- fresco/tests/test_routing.py +86 -33
- fresco/tests/util/test_http.py +1 -3
- fresco/types.py +28 -2
- fresco/util/cache.py +2 -1
- fresco/util/http.py +66 -46
- fresco/util/urls.py +13 -11
- fresco/util/wsgi.py +15 -14
- {fresco-3.4.0.dist-info → fresco-3.6.0.dist-info}/METADATA +3 -2
- fresco-3.6.0.dist-info/RECORD +58 -0
- {fresco-3.4.0.dist-info → fresco-3.6.0.dist-info}/WHEEL +1 -1
- fresco/typing.py +0 -11
- fresco-3.4.0.dist-info/RECORD +0 -57
- {fresco-3.4.0.dist-info → fresco-3.6.0.dist-info/licenses}/LICENSE.txt +0 -0
- {fresco-3.4.0.dist-info → fresco-3.6.0.dist-info}/top_level.txt +0 -0
fresco/util/http.py
CHANGED
|
@@ -20,6 +20,8 @@ Utilities for working with data on the HTTP level
|
|
|
20
20
|
from binascii import hexlify
|
|
21
21
|
from collections import namedtuple
|
|
22
22
|
from collections import deque
|
|
23
|
+
from collections.abc import Collection
|
|
24
|
+
from collections.abc import Mapping
|
|
23
25
|
from email.header import Header
|
|
24
26
|
from email.message import Message
|
|
25
27
|
from email.parser import BytesFeedParser
|
|
@@ -43,6 +45,7 @@ from urllib.parse import unquote_plus
|
|
|
43
45
|
from shutil import copyfileobj
|
|
44
46
|
|
|
45
47
|
import fresco
|
|
48
|
+
from fresco.defaults import DEFAULT_CHARSET
|
|
46
49
|
from fresco.exceptions import RequestParseError
|
|
47
50
|
from fresco.util.io import io_iterator
|
|
48
51
|
from fresco.util.io import ByteIterator
|
|
@@ -90,23 +93,23 @@ def get_content_type_info(
|
|
|
90
93
|
|
|
91
94
|
|
|
92
95
|
class TooBig(RequestParseError):
|
|
93
|
-
"""
|
|
96
|
+
"""
|
|
94
97
|
Request body is too big
|
|
95
98
|
"""
|
|
96
99
|
|
|
97
100
|
def __init__(self, *args, **kwargs):
|
|
98
101
|
super(TooBig, self).__init__(*args, **kwargs)
|
|
99
|
-
self.response = fresco.
|
|
102
|
+
self.response = fresco.Response.payload_too_large()
|
|
100
103
|
|
|
101
104
|
|
|
102
105
|
class MissingContentLength(RequestParseError):
|
|
103
|
-
"""
|
|
106
|
+
"""
|
|
104
107
|
No ``Content-Length`` header given
|
|
105
108
|
"""
|
|
106
109
|
|
|
107
110
|
def __init__(self, *args, **kwargs):
|
|
108
111
|
super(MissingContentLength, self).__init__(*args, **kwargs)
|
|
109
|
-
self.response = fresco.
|
|
112
|
+
self.response = fresco.Response.length_required()
|
|
110
113
|
|
|
111
114
|
|
|
112
115
|
def parse_parameters(s, preserve_backslashes=False) -> Dict[str, str]:
|
|
@@ -212,7 +215,7 @@ def parse_querystring(
|
|
|
212
215
|
|
|
213
216
|
:param data: The query string to parse.
|
|
214
217
|
:param charset: Character encoding used to decode values. If not specified,
|
|
215
|
-
``fresco.DEFAULT_CHARSET`` will be used.
|
|
218
|
+
``fresco.defaults.DEFAULT_CHARSET`` will be used.
|
|
216
219
|
|
|
217
220
|
:param keep_blank_values: if True, keys without associated values will be
|
|
218
221
|
returned as empty strings. if False, no key,
|
|
@@ -223,7 +226,7 @@ def parse_querystring(
|
|
|
223
226
|
"""
|
|
224
227
|
|
|
225
228
|
if charset is None:
|
|
226
|
-
charset =
|
|
229
|
+
charset = DEFAULT_CHARSET
|
|
227
230
|
|
|
228
231
|
result: List[Tuple[str, str]] = []
|
|
229
232
|
append = result.append
|
|
@@ -275,7 +278,7 @@ def parse_post(
|
|
|
275
278
|
ct, charset, ct_params = get_content_type_info(
|
|
276
279
|
environ,
|
|
277
280
|
"application/x-www-form-urlencoded",
|
|
278
|
-
default_charset or
|
|
281
|
+
default_charset or DEFAULT_CHARSET,
|
|
279
282
|
)
|
|
280
283
|
|
|
281
284
|
try:
|
|
@@ -454,14 +457,15 @@ def parse_multipart(
|
|
|
454
457
|
f.close()
|
|
455
458
|
raise
|
|
456
459
|
|
|
457
|
-
close: Optional[Callable]
|
|
460
|
+
close: Optional[Callable] # type: ignore
|
|
458
461
|
if open_files:
|
|
459
462
|
|
|
460
463
|
def close():
|
|
461
464
|
for f in open_files:
|
|
462
465
|
f.close()
|
|
466
|
+
|
|
463
467
|
else:
|
|
464
|
-
close = None
|
|
468
|
+
close = None # type: ignore
|
|
465
469
|
|
|
466
470
|
return fields, close
|
|
467
471
|
|
|
@@ -554,7 +558,6 @@ def read_until(
|
|
|
554
558
|
return
|
|
555
559
|
|
|
556
560
|
def remainder():
|
|
557
|
-
nonlocal buf
|
|
558
561
|
if buf:
|
|
559
562
|
yield buf
|
|
560
563
|
yield from stream
|
|
@@ -591,7 +594,21 @@ class FileUpload(object):
|
|
|
591
594
|
copyfileobj(self.file, fileob)
|
|
592
595
|
|
|
593
596
|
|
|
594
|
-
def encode_multipart(
|
|
597
|
+
def encode_multipart(
|
|
598
|
+
data: Optional[
|
|
599
|
+
Union[
|
|
600
|
+
Mapping[str, str],
|
|
601
|
+
Collection[tuple[str, str]],
|
|
602
|
+
]
|
|
603
|
+
] = None,
|
|
604
|
+
files: Optional[
|
|
605
|
+
Collection[
|
|
606
|
+
tuple[str, str, str, Union[bytes, t.Iterable[bytes], t.BinaryIO]]
|
|
607
|
+
]
|
|
608
|
+
] = None,
|
|
609
|
+
charset="UTF-8",
|
|
610
|
+
**kwargs
|
|
611
|
+
) -> tuple[bytes, dict[str, str]]:
|
|
595
612
|
"""
|
|
596
613
|
Encode ``data`` using multipart/form-data encoding, returning a tuple
|
|
597
614
|
of ``(<encoded data>, <environ items>)``.
|
|
@@ -602,7 +619,7 @@ def encode_multipart(data=None, files=None, charset="UTF-8", **kwargs):
|
|
|
602
619
|
:param charset: Encoding used for any string values encountered in
|
|
603
620
|
``data``
|
|
604
621
|
|
|
605
|
-
:param files:
|
|
622
|
+
:param files: collection of ``(name, filename, content_type, data)`` tuples.
|
|
606
623
|
``data`` may be either a byte string, iterator or
|
|
607
624
|
file-like object.
|
|
608
625
|
|
|
@@ -614,45 +631,22 @@ def encode_multipart(data=None, files=None, charset="UTF-8", **kwargs):
|
|
|
614
631
|
dict.
|
|
615
632
|
"""
|
|
616
633
|
|
|
617
|
-
def header_block(name):
|
|
618
|
-
return [("Content-Disposition", 'form-data; name="%s"' % (name,))]
|
|
619
|
-
|
|
620
|
-
def file_header_block(name, filename, content_type):
|
|
621
|
-
return [
|
|
622
|
-
(
|
|
623
|
-
"Content-Disposition",
|
|
624
|
-
'form-data; name="%s"; filename="%s"' % (name, filename),
|
|
625
|
-
),
|
|
626
|
-
("Content-Type", content_type),
|
|
627
|
-
]
|
|
628
|
-
|
|
629
|
-
def write_payload(stream, data):
|
|
630
|
-
"Write ``data`` to ``stream``, encoding as required"
|
|
631
|
-
if hasattr(data, "read"):
|
|
632
|
-
copyfileobj(data, stream)
|
|
633
|
-
elif isinstance(data, bytes):
|
|
634
|
-
stream.write(data)
|
|
635
|
-
elif isinstance(data, str):
|
|
636
|
-
stream.write(data.encode(charset))
|
|
637
|
-
else:
|
|
638
|
-
raise ValueError(data)
|
|
639
|
-
|
|
640
|
-
if data is None:
|
|
641
|
-
data = {}
|
|
642
|
-
|
|
643
634
|
if files is None:
|
|
644
635
|
files = []
|
|
645
636
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
637
|
+
data_items: Iterable[tuple[str, str]]
|
|
638
|
+
if data is None:
|
|
639
|
+
data_items = []
|
|
640
|
+
elif isinstance(data, Mapping):
|
|
641
|
+
data_items = iter(data.items()) # type: ignore
|
|
642
|
+
else:
|
|
643
|
+
data_items = data
|
|
650
644
|
|
|
651
|
-
|
|
645
|
+
data_items = chain(data_items, kwargs.items())
|
|
652
646
|
|
|
653
647
|
boundary = b"-------" + hexlify(os.urandom(16))
|
|
654
648
|
alldata = chain(
|
|
655
|
-
((header_block(k), payload) for k, payload in
|
|
649
|
+
((header_block(k), payload) for k, payload in data_items),
|
|
656
650
|
((file_header_block(k, fn, ct), payload) for k, fn, ct, payload in files),
|
|
657
651
|
)
|
|
658
652
|
|
|
@@ -664,7 +658,7 @@ def encode_multipart(data=None, files=None, charset="UTF-8", **kwargs):
|
|
|
664
658
|
for name, value in headers:
|
|
665
659
|
post_data.write("{0}: {1}\r\n".format(name, value).encode("ascii"))
|
|
666
660
|
post_data.write(CRLF)
|
|
667
|
-
write_payload(post_data, payload)
|
|
661
|
+
write_payload(post_data, payload, charset)
|
|
668
662
|
post_data.write(b"\r\n--" + boundary)
|
|
669
663
|
post_data.write(b"--\r\n")
|
|
670
664
|
length = post_data.tell()
|
|
@@ -676,4 +670,30 @@ def encode_multipart(data=None, files=None, charset="UTF-8", **kwargs):
|
|
|
676
670
|
),
|
|
677
671
|
}
|
|
678
672
|
|
|
679
|
-
return (post_data, wsgienv)
|
|
673
|
+
return (post_data.getvalue(), wsgienv)
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
def header_block(name):
|
|
677
|
+
return [("Content-Disposition", 'form-data; name="%s"' % (name,))]
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def file_header_block(name, filename, content_type):
|
|
681
|
+
return [
|
|
682
|
+
(
|
|
683
|
+
"Content-Disposition",
|
|
684
|
+
'form-data; name="%s"; filename="%s"' % (name, filename),
|
|
685
|
+
),
|
|
686
|
+
("Content-Type", content_type),
|
|
687
|
+
]
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
def write_payload(stream, data, charset):
|
|
691
|
+
"Write ``data`` to ``stream``, encoding as required"
|
|
692
|
+
if hasattr(data, "read"):
|
|
693
|
+
copyfileobj(data, stream)
|
|
694
|
+
elif isinstance(data, bytes):
|
|
695
|
+
stream.write(data)
|
|
696
|
+
elif isinstance(data, str):
|
|
697
|
+
stream.write(data.encode(charset))
|
|
698
|
+
else:
|
|
699
|
+
raise ValueError(data)
|
fresco/util/urls.py
CHANGED
|
@@ -27,7 +27,7 @@ import posixpath
|
|
|
27
27
|
import re
|
|
28
28
|
import typing as t
|
|
29
29
|
|
|
30
|
-
import
|
|
30
|
+
from fresco.defaults import DEFAULT_CHARSET
|
|
31
31
|
from fresco.multidict import MultiDict
|
|
32
32
|
from fresco.types import QuerySpec
|
|
33
33
|
|
|
@@ -174,13 +174,13 @@ def make_query(
|
|
|
174
174
|
data: QuerySpec = [],
|
|
175
175
|
separator: str = "&",
|
|
176
176
|
charset: t.Optional[str] = None,
|
|
177
|
-
**kwargs,
|
|
177
|
+
**kwargs: t.Any,
|
|
178
178
|
) -> str:
|
|
179
179
|
"""
|
|
180
180
|
Return a query string formed from the given dictionary data.
|
|
181
181
|
|
|
182
182
|
If no encoding is given, unicode values are encoded using the character set
|
|
183
|
-
specified by ``fresco.DEFAULT_CHARSET``.
|
|
183
|
+
specified by ``fresco.defaults.DEFAULT_CHARSET``.
|
|
184
184
|
|
|
185
185
|
Basic usage::
|
|
186
186
|
|
|
@@ -210,46 +210,48 @@ def make_query(
|
|
|
210
210
|
:param charset: encoding to be used for unicode values
|
|
211
211
|
:rtype: str
|
|
212
212
|
"""
|
|
213
|
-
items: t.Iterable[
|
|
213
|
+
items: t.Iterable[tuple[str, t.Any]]
|
|
214
214
|
if isinstance(data, MultiDict):
|
|
215
215
|
items = data.allitems()
|
|
216
216
|
elif isinstance(data, Mapping):
|
|
217
|
-
items = data.items()
|
|
217
|
+
items = data.items() # type: ignore
|
|
218
218
|
else:
|
|
219
219
|
items = data
|
|
220
220
|
if kwargs:
|
|
221
221
|
items = chain(items, kwargs.items())
|
|
222
222
|
|
|
223
223
|
if charset is None:
|
|
224
|
-
charset =
|
|
224
|
+
charset = DEFAULT_CHARSET
|
|
225
225
|
|
|
226
|
-
pairs:
|
|
226
|
+
pairs: list[str] = []
|
|
227
227
|
append = pairs.append
|
|
228
228
|
for k, v in items:
|
|
229
229
|
if isinstance(v, (str, bytes)):
|
|
230
230
|
append(f"{quote_plus(k, charset)}={quote_plus(v, charset)}")
|
|
231
|
+
elif v is None:
|
|
232
|
+
pass
|
|
231
233
|
elif hasattr(v, "__iter__"):
|
|
232
234
|
for v in v:
|
|
233
235
|
append(f"{quote_plus(k, charset)}={quote_plus(str(v), charset)}")
|
|
234
|
-
|
|
236
|
+
else:
|
|
235
237
|
append(f"{quote_plus(k, charset)}={quote_plus(str(v), charset)}")
|
|
236
238
|
return separator.join(pairs)
|
|
237
239
|
|
|
238
240
|
|
|
239
241
|
def _qs_frag(key, value, charset=None):
|
|
240
|
-
"""
|
|
242
|
+
"""
|
|
241
243
|
Return a fragment of a query string in the format 'key=value'::
|
|
242
244
|
|
|
243
245
|
>>> _qs_frag('search-by', 'author, editor')
|
|
244
246
|
'search-by=author%2C+editor'
|
|
245
247
|
|
|
246
248
|
If no encoding is specified, unicode values are encoded using the character
|
|
247
|
-
set specified by ``fresco.DEFAULT_CHARSET``.
|
|
249
|
+
set specified by ``fresco.defaults.DEFAULT_CHARSET``.
|
|
248
250
|
|
|
249
251
|
:rtype: str
|
|
250
252
|
"""
|
|
251
253
|
if charset is None:
|
|
252
|
-
charset =
|
|
254
|
+
charset = DEFAULT_CHARSET
|
|
253
255
|
|
|
254
256
|
key = str(key).encode(charset)
|
|
255
257
|
value = str(value).encode(charset)
|
fresco/util/wsgi.py
CHANGED
|
@@ -22,15 +22,16 @@ from io import BytesIO
|
|
|
22
22
|
from urllib.parse import unquote
|
|
23
23
|
from urllib.parse import urlparse
|
|
24
24
|
from typing import List
|
|
25
|
-
|
|
26
|
-
from typing import Tuple
|
|
25
|
+
import typing as t
|
|
27
26
|
import sys
|
|
28
27
|
|
|
29
|
-
from fresco.
|
|
30
|
-
from fresco.
|
|
31
|
-
from fresco.
|
|
28
|
+
from fresco.types import WSGIApplication
|
|
29
|
+
from fresco.types import WriteCallable
|
|
30
|
+
from fresco.types import OptionalExcInfo
|
|
31
|
+
from fresco.types import HeaderList
|
|
32
32
|
|
|
33
33
|
logger = logging.getLogger(__name__)
|
|
34
|
+
T = t.TypeVar("T")
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
__all__ = [
|
|
@@ -102,7 +103,6 @@ REQUEST_HEADER_NAMES = {
|
|
|
102
103
|
"dnt": "DNT",
|
|
103
104
|
"x_forwarded_for": "X-Forwarded-For",
|
|
104
105
|
"x_forwarded_host": "X-Forwarded-Host",
|
|
105
|
-
"x_forwarded_host": "X-Forwarded-Host",
|
|
106
106
|
"x_forwarded_proto": "X-Forwarded-Proto",
|
|
107
107
|
"front_end_https": "Front-End-Https",
|
|
108
108
|
"x_http_method_override": "X-Http-Method-Override",
|
|
@@ -245,8 +245,8 @@ class StartResponseWrapper(object):
|
|
|
245
245
|
self.exc_info = None
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
class ClosingIterator(
|
|
249
|
-
"""
|
|
248
|
+
class ClosingIterator(t.Generic[T]):
|
|
249
|
+
"""
|
|
250
250
|
Wrap a WSGI iterator to allow additional close functions to be called on
|
|
251
251
|
application exit.
|
|
252
252
|
|
|
@@ -275,7 +275,7 @@ class ClosingIterator(object):
|
|
|
275
275
|
|
|
276
276
|
__slots__ = ("_iterable", "_next", "_close_funcs", "_closed")
|
|
277
277
|
|
|
278
|
-
def __init__(self, iterable, *close_funcs):
|
|
278
|
+
def __init__(self, iterable: t.Iterable[T], *close_funcs: t.Callable[[], None]):
|
|
279
279
|
"""
|
|
280
280
|
Initialize a ``ClosingIterator`` to wrap iterable ``iterable``, and
|
|
281
281
|
call any functions listed in ``*close_funcs`` on the instance's
|
|
@@ -406,19 +406,20 @@ def make_environ(url="/", environ=None, wsgi_input=b"", **kwargs):
|
|
|
406
406
|
|
|
407
407
|
|
|
408
408
|
def apply_request(
|
|
409
|
-
request, wsgicallable:
|
|
410
|
-
) ->
|
|
409
|
+
request, wsgicallable: WSGIApplication
|
|
410
|
+
) -> tuple[str, HeaderList, OptionalExcInfo, list[bytes]]:
|
|
411
411
|
"""
|
|
412
412
|
Execute ``wsgicallable`` with the given request, exhaust and close the
|
|
413
413
|
content iterator and return the result.
|
|
414
414
|
"""
|
|
415
415
|
|
|
416
|
-
_start_response_result:
|
|
416
|
+
_start_response_result: list[tuple[str, HeaderList, OptionalExcInfo]] = []
|
|
417
417
|
|
|
418
418
|
def start_response(
|
|
419
|
-
status: str, headers:
|
|
420
|
-
):
|
|
419
|
+
status: str, headers: HeaderList, exc_info: OptionalExcInfo = None
|
|
420
|
+
) -> WriteCallable:
|
|
421
421
|
_start_response_result.append((status, headers, exc_info))
|
|
422
|
+
return lambda s: None
|
|
422
423
|
|
|
423
424
|
contentiter = wsgicallable(request.environ, start_response)
|
|
424
425
|
assert len(_start_response_result) == 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: fresco
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.0
|
|
4
4
|
Summary: A Web/WSGI micro-framework
|
|
5
5
|
Author-email: Oliver Cope <oliver@redgecko.org>
|
|
6
6
|
License: Apache
|
|
@@ -16,6 +16,7 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
|
16
16
|
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
|
|
17
17
|
Description-Content-Type: text/x-rst
|
|
18
18
|
License-File: LICENSE.txt
|
|
19
|
+
Dynamic: license-file
|
|
19
20
|
|
|
20
21
|
Fresco, a web micro-framework for Python
|
|
21
22
|
========================================
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
fresco/__init__.py,sha256=02YPwizUXGa9L8OrpfoX9edVv6ISiCdIOyqR0LvYYWA,3537
|
|
2
|
+
fresco/cookie.py,sha256=Qnx8yOjU4LUJ1fqi7YvqbhAA01rCsclJGl_fxI68slw,7055
|
|
3
|
+
fresco/core.py,sha256=bqGDgm4OH46j6HqnC5nJyn9n1dQw-I1ntUY8dIpeO_M,26988
|
|
4
|
+
fresco/decorators.py,sha256=JL4MlsJz4RWRAuOCCB3fx3rtd-E1CvwO2MD7bf94yHM,3324
|
|
5
|
+
fresco/defaults.py,sha256=YStD4MPcCtq-fREFoupSaAS0SY8lH1oEnKDONlR86zs,26
|
|
6
|
+
fresco/exceptions.py,sha256=KE-LoYUGnho6KltzkU6cnm9vUiUhAiDIjPqn5ba-YCA,4410
|
|
7
|
+
fresco/middleware.py,sha256=TH1I5NthLDwnOdluOSFpP_9SQQYhYqh-8lGuAXT74dc,4811
|
|
8
|
+
fresco/multidict.py,sha256=lKRpSP1XNghLp2-i5cXPfPQxuoJclHpNkWk91F4GI1o,13152
|
|
9
|
+
fresco/options.py,sha256=X66xZV45vWIyQR2GwFTLgV2QGoXOfLhHURWQ_edoxmY,17024
|
|
10
|
+
fresco/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
fresco/request.py,sha256=XJ9SJAe9zILfWt-YB4zxjIrjECrLYzyxjZ9xk8h4tAw,30024
|
|
12
|
+
fresco/requestcontext.py,sha256=_AJ7DMT5vlIO4Uc-WlRsYJdRge4WRO7ygibKImOS0iM,3601
|
|
13
|
+
fresco/response.py,sha256=ilJ_Wbp7LVP1E6bXp0iAy1o6D0hboXtpLvm2ZCmUGmk,37277
|
|
14
|
+
fresco/routeargs.py,sha256=E-LQutqg6AojtagZojF7NeMjFBk9joRNMGo842IMTBk,10598
|
|
15
|
+
fresco/routing.py,sha256=r_vPD1xc7brOrbw1iO0X2IP7WX5wlIWlcXwcNndU1ZY,61259
|
|
16
|
+
fresco/static.py,sha256=rNQz_8-PVhSGup_w-HycqatLEbFes7VSlnNQ0rz24pU,2529
|
|
17
|
+
fresco/subrequests.py,sha256=fOG9Bd3w9Ova0S3qv5ssxQ_otrSxaFcKG7TOy6CxNCg,11068
|
|
18
|
+
fresco/types.py,sha256=PbXppEcckX4ohU8npteU1mCkHOuXQxrnqxk1RNEFXkE,797
|
|
19
|
+
fresco/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
fresco/tests/fixtures.py,sha256=eyo2zPivB3fItDkrJqWnOCvIS_A1q1JEhT4AutAB--o,1871
|
|
21
|
+
fresco/tests/test_cookie.py,sha256=HTLmNCjcPoZDeFnZAzY3lJPeduzgU4mi9C-74eSQCec,2171
|
|
22
|
+
fresco/tests/test_core.py,sha256=-eibrVd8UqPqTvcar54kt24m6_lX3mxXR8L7v-WDrWw,34003
|
|
23
|
+
fresco/tests/test_decorators.py,sha256=VFXHo1gm2jldQXeaEF3NNo5fnpdJ-LXc8-vNymPJKTQ,1480
|
|
24
|
+
fresco/tests/test_exceptions.py,sha256=R0Tn86m33iTKecZ69TgH4CqY9XSFP0FsLMH10O5Jth8,973
|
|
25
|
+
fresco/tests/test_middleware.py,sha256=D_sWfX-w3bhItOm54nB_cuYPGoWopISvZCFIuMX68cU,3137
|
|
26
|
+
fresco/tests/test_multidict.py,sha256=uIa1cu5DMAukX2nLOjTiB12oh0icBeSPfsUnqsu85m0,7577
|
|
27
|
+
fresco/tests/test_options.py,sha256=394MLLTyf4vmfkUyqQ8EGIiTTJsQh7P9M6eta2wgUbw,12764
|
|
28
|
+
fresco/tests/test_request.py,sha256=wGDwxCZMbzyGgQJwM2Nlsf0ogcGenXN3srO8dQEhE24,16777
|
|
29
|
+
fresco/tests/test_requestcontext.py,sha256=t8hm-lzIk85ryb3sdlpVoPQyLDWpCjB86dg8nVG1yRw,3115
|
|
30
|
+
fresco/tests/test_response.py,sha256=MrhHIDg81pJlTeEcn2rGtU-i59s1KzEccF81u4Up6xs,8934
|
|
31
|
+
fresco/tests/test_routeargs.py,sha256=VMWUbrXegTLN9Tx2AcrpbjAAEaxAANzkcy02SmpFOmY,8162
|
|
32
|
+
fresco/tests/test_routing.py,sha256=NBBJ6UcsdSoUAFNgUtCC0lEEeKB6JxS8XyrUeef25M8,40018
|
|
33
|
+
fresco/tests/test_static.py,sha256=y73dqzE2flpACQ_dvNhDzk_WlvNQfkhYF_8YY4MMGDo,4686
|
|
34
|
+
fresco/tests/test_subrequests.py,sha256=7rluJnw-elXRXfrzvAQvGBHRBU93zwnL827mTxBGd3Y,7909
|
|
35
|
+
fresco/tests/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
fresco/tests/util/form_data.py,sha256=TalOuv4BGM3JNrf14tE47o9wAwZ7jA1CvRDnGJFifno,10570
|
|
37
|
+
fresco/tests/util/test_common.py,sha256=NvKX8KIAUki7b2kDLILWqARbOQmR3XyInLlbcwFEhiU,1117
|
|
38
|
+
fresco/tests/util/test_http.py,sha256=mdHDc-4m9sMNkEgHToIsgFuSSXQzNUcYSehPehYvJYo,10748
|
|
39
|
+
fresco/tests/util/test_security.py,sha256=MtpDDKyDhAeRT766Lt3peOv4Jj55TM1lvJk1_5TKaes,1492
|
|
40
|
+
fresco/tests/util/test_urls.py,sha256=xKiE6oq0bB-9u8kNYlMQmeCwuAKr1KLQovB-i24wKVQ,7643
|
|
41
|
+
fresco/tests/util/test_wsgi.py,sha256=VsHUCo8yck_40nsYm-H-M0R8QYEE8JcboeGPbcrzsO0,3038
|
|
42
|
+
fresco/util/__init__.py,sha256=mJkaZzvYgBnxsBAGv8y_P1yzonHqWgw6VF2Zs4rmJEA,7
|
|
43
|
+
fresco/util/cache.py,sha256=0xINmBecCYo3h5-zU_yRyJeWmROygE3pO9w9Y3ZONcs,1661
|
|
44
|
+
fresco/util/common.py,sha256=8lvrjhELvYsUWxu7DZi1OJcUOFk2ILYndNsnaS0IqjM,1258
|
|
45
|
+
fresco/util/contentencodings.py,sha256=cCP-nSlXiBAZWoJdlnrQREi9jYRu8UY327bQdfBNlkg,5527
|
|
46
|
+
fresco/util/file.py,sha256=Vp7qJTo9RouUeHq25ExyBGkGTHuW-9Q7D_0GB54DFe8,1383
|
|
47
|
+
fresco/util/http.py,sha256=hxMKjF6FWvugDvToRqSscDhCD1KdVY1bmV4Unwd_Uhs,22672
|
|
48
|
+
fresco/util/io.py,sha256=xxwDNJOcewY8lAR4Ce3cmB_zlrys8JGsESgwGWE198Y,1289
|
|
49
|
+
fresco/util/object.py,sha256=FjYNfPHzvBqq1rn0Y6As-2AVZ_SZOjH-lrSy4EbYmHY,370
|
|
50
|
+
fresco/util/security.py,sha256=nXEdoCak_2c4OA1L1wGwhZygS22s2fzwR0Kp-DdwKZg,1058
|
|
51
|
+
fresco/util/textproc.py,sha256=e5jLTofKCqdm6_Fy8XOyR43AJr5APtL59Kd8cNA9PrQ,2309
|
|
52
|
+
fresco/util/urls.py,sha256=2vDbfmjBLtUVpZ0ZhoNWkzn2WVZxcZZQeBZjtcUDp3w,9276
|
|
53
|
+
fresco/util/wsgi.py,sha256=RYw4KeOUjzzPOL_HhEtgLyCngofjMdAT8BTLOSKU6KA,13021
|
|
54
|
+
fresco-3.6.0.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
55
|
+
fresco-3.6.0.dist-info/METADATA,sha256=zfjV8OUXV-2-dRpwNilk8cgduTx8ZUq8dw_IcClwnuQ,1571
|
|
56
|
+
fresco-3.6.0.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
|
|
57
|
+
fresco-3.6.0.dist-info/top_level.txt,sha256=p_1aMce5Shjq9fIfdbB-aN8wCDhjF_iYnn98bUebbII,7
|
|
58
|
+
fresco-3.6.0.dist-info/RECORD,,
|
fresco/typing.py
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from types import TracebackType
|
|
2
|
-
from typing import Any
|
|
3
|
-
from typing import Callable
|
|
4
|
-
from typing import Dict
|
|
5
|
-
from typing import Iterable
|
|
6
|
-
from typing import List
|
|
7
|
-
from typing import Tuple
|
|
8
|
-
|
|
9
|
-
WSGICallable = Callable[[Dict[str, Any], Callable], Iterable[bytes]]
|
|
10
|
-
ExcInfoTuple = Tuple[type, BaseException, TracebackType]
|
|
11
|
-
HeadersList = List[Tuple[str, str]]
|
fresco-3.4.0.dist-info/RECORD
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
fresco/__init__.py,sha256=rteQgLzbeRKgdSkiDL_0ey72k3neyI5FtDIG8LR9vxA,3520
|
|
2
|
-
fresco/cookie.py,sha256=Qnx8yOjU4LUJ1fqi7YvqbhAA01rCsclJGl_fxI68slw,7055
|
|
3
|
-
fresco/core.py,sha256=mwYR6UP0zRSjcFlNZf51-otX9EcmvgjEZ7GDVQoQexg,26615
|
|
4
|
-
fresco/decorators.py,sha256=84NUpRJ-M7GK6wDl42bmCRSvgoWzCsy1huyvGnSAPPw,3232
|
|
5
|
-
fresco/exceptions.py,sha256=KE-LoYUGnho6KltzkU6cnm9vUiUhAiDIjPqn5ba-YCA,4410
|
|
6
|
-
fresco/middleware.py,sha256=uCAuOtBnvaVBJGrQa8ecvLkSZ6aSKmWaJqxB8Rv4SsQ,4173
|
|
7
|
-
fresco/multidict.py,sha256=0CaNNIcFnZ1hLk3NExhNvjc_BtK4zVB26L9gP_7MeNM,13362
|
|
8
|
-
fresco/options.py,sha256=Z1EZPRoEAqYHm2hg7gRmLtMWMKWjNgGVehPtCU66mBE,14068
|
|
9
|
-
fresco/request.py,sha256=dC7pMg-4Kxa6PcqaaWFL4JviANQotuBjoKwlxZYywRY,27048
|
|
10
|
-
fresco/requestcontext.py,sha256=P-SkKJkKLYVqNiR2zwooRROnSnE2VMj2P2-eD5DW5Qg,3504
|
|
11
|
-
fresco/response.py,sha256=ADKHbtAGyhwtaUJxB7m_1nqVdZRKUryebmG4FDUjZVY,37072
|
|
12
|
-
fresco/routeargs.py,sha256=dxNlqbQ1FrgIY6OCFzcEMdZ0OVyjlMQdQGLmUJgdPYU,10176
|
|
13
|
-
fresco/routing.py,sha256=S33ysM6BJEKxWZh7mdPO6-Eep2t1s0Q_qlrev84iNIY,58977
|
|
14
|
-
fresco/static.py,sha256=9SKQ3P1YFTP45Qiic-ycvkpKRvqIURp1XSzPazTmYLI,2513
|
|
15
|
-
fresco/subrequests.py,sha256=wFJWLuhVAcei5imYc5NBSCBaHBEm-X4_XswPtK3O4Zw,11081
|
|
16
|
-
fresco/types.py,sha256=UHITRMDoS90s2zV2wNpqLFhRWESfaBAMuQnL4c21mqY,106
|
|
17
|
-
fresco/typing.py,sha256=jQ1r_wme54J08XZUdmuuW4M8ve-gEhm1Wriwctls3r8,347
|
|
18
|
-
fresco/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
fresco/tests/fixtures.py,sha256=eyo2zPivB3fItDkrJqWnOCvIS_A1q1JEhT4AutAB--o,1871
|
|
20
|
-
fresco/tests/test_cookie.py,sha256=HTLmNCjcPoZDeFnZAzY3lJPeduzgU4mi9C-74eSQCec,2171
|
|
21
|
-
fresco/tests/test_core.py,sha256=lniN-UslszeRAuWlbBU536LDGTo8Hp2nb8kLebXvim0,34019
|
|
22
|
-
fresco/tests/test_decorators.py,sha256=VFXHo1gm2jldQXeaEF3NNo5fnpdJ-LXc8-vNymPJKTQ,1480
|
|
23
|
-
fresco/tests/test_exceptions.py,sha256=R0Tn86m33iTKecZ69TgH4CqY9XSFP0FsLMH10O5Jth8,973
|
|
24
|
-
fresco/tests/test_middleware.py,sha256=D_sWfX-w3bhItOm54nB_cuYPGoWopISvZCFIuMX68cU,3137
|
|
25
|
-
fresco/tests/test_multidict.py,sha256=uDwDYII0dvVxaEyDO85zRTWlIWw3LO3StzYemJVm0E0,7565
|
|
26
|
-
fresco/tests/test_options.py,sha256=Zx1tLVLeok8tO3dWua2PyTPZgeWbXFMXtN3FnorBmC8,10998
|
|
27
|
-
fresco/tests/test_request.py,sha256=hoANrergrohlAeTbQufDMfIbvYURsPyPjCxOVKz7bVo,16389
|
|
28
|
-
fresco/tests/test_requestcontext.py,sha256=t8hm-lzIk85ryb3sdlpVoPQyLDWpCjB86dg8nVG1yRw,3115
|
|
29
|
-
fresco/tests/test_response.py,sha256=MrhHIDg81pJlTeEcn2rGtU-i59s1KzEccF81u4Up6xs,8934
|
|
30
|
-
fresco/tests/test_routeargs.py,sha256=VMWUbrXegTLN9Tx2AcrpbjAAEaxAANzkcy02SmpFOmY,8162
|
|
31
|
-
fresco/tests/test_routing.py,sha256=nOg3daHL8UigPEykHzgLKmlTOYtD4n_VjoBVfMsQcYo,38565
|
|
32
|
-
fresco/tests/test_static.py,sha256=y73dqzE2flpACQ_dvNhDzk_WlvNQfkhYF_8YY4MMGDo,4686
|
|
33
|
-
fresco/tests/test_subrequests.py,sha256=7rluJnw-elXRXfrzvAQvGBHRBU93zwnL827mTxBGd3Y,7909
|
|
34
|
-
fresco/tests/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
fresco/tests/util/form_data.py,sha256=TalOuv4BGM3JNrf14tE47o9wAwZ7jA1CvRDnGJFifno,10570
|
|
36
|
-
fresco/tests/util/test_common.py,sha256=NvKX8KIAUki7b2kDLILWqARbOQmR3XyInLlbcwFEhiU,1117
|
|
37
|
-
fresco/tests/util/test_http.py,sha256=VYcrxKisRhI19AvuZWLuJGdpZo-IN19y4gDUKwuFy0I,10803
|
|
38
|
-
fresco/tests/util/test_security.py,sha256=MtpDDKyDhAeRT766Lt3peOv4Jj55TM1lvJk1_5TKaes,1492
|
|
39
|
-
fresco/tests/util/test_urls.py,sha256=xKiE6oq0bB-9u8kNYlMQmeCwuAKr1KLQovB-i24wKVQ,7643
|
|
40
|
-
fresco/tests/util/test_wsgi.py,sha256=VsHUCo8yck_40nsYm-H-M0R8QYEE8JcboeGPbcrzsO0,3038
|
|
41
|
-
fresco/util/__init__.py,sha256=mJkaZzvYgBnxsBAGv8y_P1yzonHqWgw6VF2Zs4rmJEA,7
|
|
42
|
-
fresco/util/cache.py,sha256=EjzF9EzzDw4U4coOykkJEgh_8HMDpwhEbYKBo_TeOZQ,1609
|
|
43
|
-
fresco/util/common.py,sha256=8lvrjhELvYsUWxu7DZi1OJcUOFk2ILYndNsnaS0IqjM,1258
|
|
44
|
-
fresco/util/contentencodings.py,sha256=cCP-nSlXiBAZWoJdlnrQREi9jYRu8UY327bQdfBNlkg,5527
|
|
45
|
-
fresco/util/file.py,sha256=Vp7qJTo9RouUeHq25ExyBGkGTHuW-9Q7D_0GB54DFe8,1383
|
|
46
|
-
fresco/util/http.py,sha256=6LSzCxr8avha3rRwsU8kUrkHWnQTuOw49mfi1PSBEgo,22199
|
|
47
|
-
fresco/util/io.py,sha256=xxwDNJOcewY8lAR4Ce3cmB_zlrys8JGsESgwGWE198Y,1289
|
|
48
|
-
fresco/util/object.py,sha256=FjYNfPHzvBqq1rn0Y6As-2AVZ_SZOjH-lrSy4EbYmHY,370
|
|
49
|
-
fresco/util/security.py,sha256=nXEdoCak_2c4OA1L1wGwhZygS22s2fzwR0Kp-DdwKZg,1058
|
|
50
|
-
fresco/util/textproc.py,sha256=e5jLTofKCqdm6_Fy8XOyR43AJr5APtL59Kd8cNA9PrQ,2309
|
|
51
|
-
fresco/util/urls.py,sha256=aaVovLyXNlVoGviiLN94ImqXf-LTQs_xooEIyi3LBc4,9195
|
|
52
|
-
fresco/util/wsgi.py,sha256=2cr2b92RpvPSgS_P46X2mlYepoFg9Qji-V-fzxpSNzw,12971
|
|
53
|
-
fresco-3.4.0.dist-info/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
54
|
-
fresco-3.4.0.dist-info/METADATA,sha256=Kk7LvAhriUF3HHAIb0ZFoTyADsgD_Czx3arDrYQCVoU,1549
|
|
55
|
-
fresco-3.4.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
56
|
-
fresco-3.4.0.dist-info/top_level.txt,sha256=p_1aMce5Shjq9fIfdbB-aN8wCDhjF_iYnn98bUebbII,7
|
|
57
|
-
fresco-3.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|