fresco 3.7.0__py3-none-any.whl → 3.8.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 +1 -1
- fresco/core.py +3 -1
- fresco/options.py +6 -2
- fresco/response.py +40 -32
- fresco/routing.py +4 -3
- {fresco-3.7.0.dist-info → fresco-3.8.0.dist-info}/METADATA +2 -3
- {fresco-3.7.0.dist-info → fresco-3.8.0.dist-info}/RECORD +10 -10
- {fresco-3.7.0.dist-info → fresco-3.8.0.dist-info}/WHEEL +1 -1
- {fresco-3.7.0.dist-info → fresco-3.8.0.dist-info}/licenses/LICENSE.txt +0 -0
- {fresco-3.7.0.dist-info → fresco-3.8.0.dist-info}/top_level.txt +0 -0
fresco/__init__.py
CHANGED
fresco/core.py
CHANGED
|
@@ -280,7 +280,9 @@ class FrescoApp(RouteCollection):
|
|
|
280
280
|
except ResponseException as e:
|
|
281
281
|
response = e.response
|
|
282
282
|
else:
|
|
283
|
-
response = self.get_response(
|
|
283
|
+
response = self.get_response(
|
|
284
|
+
request, path, request.environ["REQUEST_METHOD"]
|
|
285
|
+
)
|
|
284
286
|
|
|
285
287
|
for f in self.process_response_handlers:
|
|
286
288
|
try:
|
fresco/options.py
CHANGED
|
@@ -285,11 +285,15 @@ class Options(dict):
|
|
|
285
285
|
)
|
|
286
286
|
)
|
|
287
287
|
|
|
288
|
-
if
|
|
289
|
-
|
|
288
|
+
if existing_keys and set(self.keys()) != existing_keys:
|
|
289
|
+
error_msg = (
|
|
290
290
|
f"settings file {path} created undefined options: "
|
|
291
291
|
f"{set(self.keys()) - existing_keys}"
|
|
292
292
|
)
|
|
293
|
+
if strict:
|
|
294
|
+
raise AssertionError(error_msg)
|
|
295
|
+
else:
|
|
296
|
+
logger.warning(error_msg)
|
|
293
297
|
|
|
294
298
|
if use_environ:
|
|
295
299
|
self |= {
|
fresco/response.py
CHANGED
|
@@ -277,7 +277,7 @@ def encoder(stream, charset):
|
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
def make_header_name(name):
|
|
280
|
-
"""
|
|
280
|
+
"""
|
|
281
281
|
Return a formatted header name from a python idenfier.
|
|
282
282
|
|
|
283
283
|
Example usage::
|
|
@@ -677,8 +677,10 @@ class Response(object):
|
|
|
677
677
|
newheaders.append((k, v))
|
|
678
678
|
return self.replace(headers=newheaders + [("Vary", ", ".join(_vary_on))])
|
|
679
679
|
|
|
680
|
-
def replace(
|
|
681
|
-
|
|
680
|
+
def replace(
|
|
681
|
+
self, content=None, status=None, headers=None, **kwheaders
|
|
682
|
+
) -> "Response":
|
|
683
|
+
"""
|
|
682
684
|
Return a new response object with any of content, status or headers
|
|
683
685
|
changed.
|
|
684
686
|
|
|
@@ -758,7 +760,7 @@ class Response(object):
|
|
|
758
760
|
return default_charset
|
|
759
761
|
|
|
760
762
|
@classmethod
|
|
761
|
-
def not_found(cls, request=None):
|
|
763
|
+
def not_found(cls, request=None) -> "Response":
|
|
762
764
|
"""
|
|
763
765
|
Return an HTTP not found response (404).
|
|
764
766
|
|
|
@@ -781,7 +783,7 @@ class Response(object):
|
|
|
781
783
|
)
|
|
782
784
|
|
|
783
785
|
@classmethod
|
|
784
|
-
def error(cls, message="500 Internal Server Error"):
|
|
786
|
+
def error(cls, message="500 Internal Server Error") -> "Response":
|
|
785
787
|
"""
|
|
786
788
|
Return an HTTP server error response (500).
|
|
787
789
|
|
|
@@ -803,7 +805,7 @@ class Response(object):
|
|
|
803
805
|
)
|
|
804
806
|
|
|
805
807
|
@classmethod
|
|
806
|
-
def unauthorized(cls, authenticate):
|
|
808
|
+
def unauthorized(cls, authenticate) -> "Response":
|
|
807
809
|
"""
|
|
808
810
|
Return an HTTP unauthorized response (401)
|
|
809
811
|
"""
|
|
@@ -818,7 +820,7 @@ class Response(object):
|
|
|
818
820
|
)
|
|
819
821
|
|
|
820
822
|
@classmethod
|
|
821
|
-
def unauthorized_basic(cls, realm):
|
|
823
|
+
def unauthorized_basic(cls, realm) -> "Response":
|
|
822
824
|
"""
|
|
823
825
|
Return an HTTP unauthorized response (401) with a WWW-Authenticate
|
|
824
826
|
header set for HTTP Basic authentication..
|
|
@@ -826,7 +828,7 @@ class Response(object):
|
|
|
826
828
|
return cls.unauthorized(authenticate=f'Basic realm="{realm}"')
|
|
827
829
|
|
|
828
830
|
@classmethod
|
|
829
|
-
def forbidden(cls, message="Sorry, access is denied"):
|
|
831
|
+
def forbidden(cls, message="Sorry, access is denied") -> "Response":
|
|
830
832
|
"""
|
|
831
833
|
Return an HTTP forbidden response (403).
|
|
832
834
|
|
|
@@ -842,7 +844,9 @@ class Response(object):
|
|
|
842
844
|
)
|
|
843
845
|
|
|
844
846
|
@classmethod
|
|
845
|
-
def bad_request(
|
|
847
|
+
def bad_request(
|
|
848
|
+
cls, message="The server could not understand your request", request=None
|
|
849
|
+
) -> "Response":
|
|
846
850
|
"""
|
|
847
851
|
Return an HTTP bad request response.
|
|
848
852
|
|
|
@@ -856,16 +860,17 @@ class Response(object):
|
|
|
856
860
|
return cls(
|
|
857
861
|
status=STATUS_BAD_REQUEST,
|
|
858
862
|
content=[
|
|
859
|
-
"<html>"
|
|
860
|
-
"<body>"
|
|
861
|
-
"<h1>
|
|
862
|
-
"</
|
|
863
|
-
"</
|
|
863
|
+
f"<html>"
|
|
864
|
+
f"<body>"
|
|
865
|
+
f"<h1>Bad request</h1>"
|
|
866
|
+
f"<p>{message}</p>"
|
|
867
|
+
f"</body>"
|
|
868
|
+
f"</html>"
|
|
864
869
|
],
|
|
865
870
|
)
|
|
866
871
|
|
|
867
872
|
@classmethod
|
|
868
|
-
def length_required(cls, request=None):
|
|
873
|
+
def length_required(cls, request=None) -> "Response":
|
|
869
874
|
"""
|
|
870
875
|
Return an HTTP Length Required response (411).
|
|
871
876
|
|
|
@@ -888,7 +893,7 @@ class Response(object):
|
|
|
888
893
|
)
|
|
889
894
|
|
|
890
895
|
@classmethod
|
|
891
|
-
def payload_too_large(cls, request=None):
|
|
896
|
+
def payload_too_large(cls, request=None) -> "Response":
|
|
892
897
|
"""
|
|
893
898
|
Return an HTTP Payload Too Large response (413)::
|
|
894
899
|
|
|
@@ -903,7 +908,7 @@ class Response(object):
|
|
|
903
908
|
request_entity_too_large = payload_too_large
|
|
904
909
|
|
|
905
910
|
@classmethod
|
|
906
|
-
def method_not_allowed(cls, valid_methods):
|
|
911
|
+
def method_not_allowed(cls, valid_methods) -> "Response":
|
|
907
912
|
"""
|
|
908
913
|
Return an HTTP method not allowed response (405)::
|
|
909
914
|
|
|
@@ -925,7 +930,7 @@ class Response(object):
|
|
|
925
930
|
)
|
|
926
931
|
|
|
927
932
|
@classmethod
|
|
928
|
-
def internal_server_error(cls):
|
|
933
|
+
def internal_server_error(cls) -> "Response":
|
|
929
934
|
"""
|
|
930
935
|
Return an HTTP internal server error response (500).
|
|
931
936
|
|
|
@@ -946,7 +951,7 @@ class Response(object):
|
|
|
946
951
|
@classmethod
|
|
947
952
|
def unrestricted_redirect(
|
|
948
953
|
cls, location, request=None, status=STATUS_FOUND, **kwargs
|
|
949
|
-
):
|
|
954
|
+
) -> "Response":
|
|
950
955
|
"""
|
|
951
956
|
Return an HTTP redirect reponse (30x).
|
|
952
957
|
|
|
@@ -1004,7 +1009,7 @@ class Response(object):
|
|
|
1004
1009
|
request = fresco.context.request
|
|
1005
1010
|
location = request.resolve_url(location)
|
|
1006
1011
|
|
|
1007
|
-
return
|
|
1012
|
+
return cls(
|
|
1008
1013
|
"<html><head></head><body>\n"
|
|
1009
1014
|
"<h1>Page has moved</h1>\n"
|
|
1010
1015
|
"<p><a href='%s'>%s</a></p>\n"
|
|
@@ -1014,8 +1019,8 @@ class Response(object):
|
|
|
1014
1019
|
)
|
|
1015
1020
|
|
|
1016
1021
|
@classmethod
|
|
1017
|
-
def unrestricted_redirect_permanent(cls, *args, **kwargs):
|
|
1018
|
-
"""
|
|
1022
|
+
def unrestricted_redirect_permanent(cls, *args, **kwargs) -> "Response":
|
|
1023
|
+
"""
|
|
1019
1024
|
Return an HTTP permanent redirect reponse.
|
|
1020
1025
|
|
|
1021
1026
|
:param location: the URI of the new location. If relative this will be
|
|
@@ -1027,8 +1032,8 @@ class Response(object):
|
|
|
1027
1032
|
return cls.unrestricted_redirect(*args, **kwargs)
|
|
1028
1033
|
|
|
1029
1034
|
@classmethod
|
|
1030
|
-
def unrestricted_redirect_temporary(cls, *args, **kwargs):
|
|
1031
|
-
"""
|
|
1035
|
+
def unrestricted_redirect_temporary(cls, *args, **kwargs) -> "Response":
|
|
1036
|
+
"""
|
|
1032
1037
|
Return an HTTP permanent redirect reponse.
|
|
1033
1038
|
|
|
1034
1039
|
:param location: the URI of the new location. If relative this will be
|
|
@@ -1048,7 +1053,7 @@ class Response(object):
|
|
|
1048
1053
|
_is_safe_url=is_safe_url,
|
|
1049
1054
|
allowed_hosts=frozenset(),
|
|
1050
1055
|
**kwargs,
|
|
1051
|
-
):
|
|
1056
|
+
) -> "Response":
|
|
1052
1057
|
"""
|
|
1053
1058
|
Return an HTTP redirect reponse (30x). Will only redirect to the
|
|
1054
1059
|
current host or hosts in the ``allowed_hosts`` list. A ``ValueError``
|
|
@@ -1075,19 +1080,22 @@ class Response(object):
|
|
|
1075
1080
|
"""
|
|
1076
1081
|
# Create the fallback redirect response always so that
|
|
1077
1082
|
# changes to route names don't result in latent bugs
|
|
1083
|
+
fallback_response = None
|
|
1078
1084
|
if fallback:
|
|
1079
|
-
|
|
1085
|
+
fallback_response = cls.unrestricted_redirect(
|
|
1086
|
+
fallback, status=status, **kwargs
|
|
1087
|
+
)
|
|
1080
1088
|
if callable(url) or "//" not in url:
|
|
1081
1089
|
return cls.unrestricted_redirect(url, status=status, **kwargs)
|
|
1082
1090
|
|
|
1083
1091
|
if url and _is_safe_url(url, allowed_hosts):
|
|
1084
1092
|
return cls.unrestricted_redirect(url, status=status, **kwargs)
|
|
1085
|
-
if
|
|
1086
|
-
return
|
|
1093
|
+
if fallback_response:
|
|
1094
|
+
return fallback_response
|
|
1087
1095
|
raise ValueError("Unsafe URL")
|
|
1088
1096
|
|
|
1089
1097
|
@classmethod
|
|
1090
|
-
def redirect_permanent(cls, *args, **kwargs):
|
|
1098
|
+
def redirect_permanent(cls, *args, **kwargs) -> "Response":
|
|
1091
1099
|
"""
|
|
1092
1100
|
Return an HTTP permanent redirect reponse.
|
|
1093
1101
|
|
|
@@ -1100,7 +1108,7 @@ class Response(object):
|
|
|
1100
1108
|
return cls.redirect(*args, **kwargs)
|
|
1101
1109
|
|
|
1102
1110
|
@classmethod
|
|
1103
|
-
def redirect_temporary(cls, *args, **kwargs):
|
|
1111
|
+
def redirect_temporary(cls, *args, **kwargs) -> "Response":
|
|
1104
1112
|
"""
|
|
1105
1113
|
Return an HTTP permanent redirect reponse.
|
|
1106
1114
|
|
|
@@ -1113,7 +1121,7 @@ class Response(object):
|
|
|
1113
1121
|
return cls.redirect(*args, **kwargs)
|
|
1114
1122
|
|
|
1115
1123
|
@classmethod
|
|
1116
|
-
def meta_refresh(cls, location, delay=1, request=None):
|
|
1124
|
+
def meta_refresh(cls, location, delay=1, request=None) -> "Response":
|
|
1117
1125
|
"""
|
|
1118
1126
|
Return an HTML page containing a <meta http-equiv="refresh"> tag,
|
|
1119
1127
|
causing the browser to redirect to the given location after ``delay``
|
|
@@ -1152,7 +1160,7 @@ class Response(object):
|
|
|
1152
1160
|
headers=None,
|
|
1153
1161
|
dumps=stdlib_json.dumps,
|
|
1154
1162
|
**kwargs,
|
|
1155
|
-
):
|
|
1163
|
+
) -> "Response":
|
|
1156
1164
|
"""
|
|
1157
1165
|
Return an ``application/json`` response with the given data
|
|
1158
1166
|
JSON serialized
|
fresco/routing.py
CHANGED
|
@@ -21,6 +21,7 @@ from collections import defaultdict
|
|
|
21
21
|
from collections import namedtuple
|
|
22
22
|
from collections.abc import Collection
|
|
23
23
|
from collections.abc import MutableSequence
|
|
24
|
+
from collections.abc import Sequence
|
|
24
25
|
from importlib import import_module
|
|
25
26
|
from functools import partial
|
|
26
27
|
from typing import Any
|
|
@@ -732,11 +733,11 @@ class Route(object):
|
|
|
732
733
|
view: Optional[Union[ViewCallable, "RouteCollection", str]] = None,
|
|
733
734
|
kwargs: Optional[dict[str, Any]] = None,
|
|
734
735
|
args=None,
|
|
735
|
-
name=None,
|
|
736
|
+
name: Optional[str] = None,
|
|
736
737
|
predicate=None,
|
|
737
738
|
decorators=None,
|
|
738
739
|
filters=None,
|
|
739
|
-
fallthrough_on=None,
|
|
740
|
+
fallthrough_on: Optional[Sequence[int]] = None,
|
|
740
741
|
provide_request: Optional[bool] = None,
|
|
741
742
|
**_kwargs: ViewCallable,
|
|
742
743
|
):
|
|
@@ -885,7 +886,7 @@ class Route(object):
|
|
|
885
886
|
args or _kwargs.pop("view_args", tuple()) # type: ignore
|
|
886
887
|
)
|
|
887
888
|
self.view_kwargs: dict[str, Any] = dict(
|
|
888
|
-
kwargs or _kwargs.pop("view_kwargs", {}), **_kwargs
|
|
889
|
+
kwargs or _kwargs.pop("view_kwargs", {}), **_kwargs # type: ignore
|
|
889
890
|
)
|
|
890
891
|
|
|
891
892
|
for arg in self.view_args:
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fresco
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8.0
|
|
4
4
|
Summary: A Web/WSGI micro-framework
|
|
5
5
|
Author-email: Oliver Cope <oliver@redgecko.org>
|
|
6
|
-
License: Apache
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://ollycope.com/software/fresco/latest/
|
|
8
8
|
Keywords: wsgi,web,www,framework
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Environment :: Web Environment
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
12
|
Classifier: Operating System :: OS Independent
|
|
14
13
|
Classifier: Programming Language :: Python :: 3
|
|
15
14
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
fresco/__init__.py,sha256=
|
|
1
|
+
fresco/__init__.py,sha256=Fcc15anYF2j6dR-bTWaWikvOzUJmSlrfrFXf-6ugdvc,3537
|
|
2
2
|
fresco/cookie.py,sha256=Qnx8yOjU4LUJ1fqi7YvqbhAA01rCsclJGl_fxI68slw,7055
|
|
3
|
-
fresco/core.py,sha256=
|
|
3
|
+
fresco/core.py,sha256=5sV6dTOhtEgEpMH_4sjoI0ewZYLvAPnRjyTfNkm490Q,27037
|
|
4
4
|
fresco/decorators.py,sha256=JL4MlsJz4RWRAuOCCB3fx3rtd-E1CvwO2MD7bf94yHM,3324
|
|
5
5
|
fresco/defaults.py,sha256=YStD4MPcCtq-fREFoupSaAS0SY8lH1oEnKDONlR86zs,26
|
|
6
6
|
fresco/exceptions.py,sha256=KE-LoYUGnho6KltzkU6cnm9vUiUhAiDIjPqn5ba-YCA,4410
|
|
7
7
|
fresco/middleware.py,sha256=TH1I5NthLDwnOdluOSFpP_9SQQYhYqh-8lGuAXT74dc,4811
|
|
8
8
|
fresco/multidict.py,sha256=lKRpSP1XNghLp2-i5cXPfPQxuoJclHpNkWk91F4GI1o,13152
|
|
9
|
-
fresco/options.py,sha256=
|
|
9
|
+
fresco/options.py,sha256=xMh23WS6HB7P9ka_S0X3DoGSSvb8ESl1m8Pqb52Mork,17152
|
|
10
10
|
fresco/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
fresco/request.py,sha256=XJ9SJAe9zILfWt-YB4zxjIrjECrLYzyxjZ9xk8h4tAw,30024
|
|
12
12
|
fresco/requestcontext.py,sha256=_AJ7DMT5vlIO4Uc-WlRsYJdRge4WRO7ygibKImOS0iM,3601
|
|
13
|
-
fresco/response.py,sha256=
|
|
13
|
+
fresco/response.py,sha256=63zHJSZy2aFB9yImwJmHZ1GwYRdvA_U1mE3yQpscrKE,37711
|
|
14
14
|
fresco/routeargs.py,sha256=E-LQutqg6AojtagZojF7NeMjFBk9joRNMGo842IMTBk,10598
|
|
15
|
-
fresco/routing.py,sha256=
|
|
15
|
+
fresco/routing.py,sha256=k7kRPYYYg6x_b_z5J77PnDJnPfZoVhLRoIfgBxlDLxA,61339
|
|
16
16
|
fresco/static.py,sha256=rNQz_8-PVhSGup_w-HycqatLEbFes7VSlnNQ0rz24pU,2529
|
|
17
17
|
fresco/subrequests.py,sha256=fOG9Bd3w9Ova0S3qv5ssxQ_otrSxaFcKG7TOy6CxNCg,11068
|
|
18
18
|
fresco/types.py,sha256=PbXppEcckX4ohU8npteU1mCkHOuXQxrnqxk1RNEFXkE,797
|
|
@@ -51,8 +51,8 @@ fresco/util/security.py,sha256=nXEdoCak_2c4OA1L1wGwhZygS22s2fzwR0Kp-DdwKZg,1058
|
|
|
51
51
|
fresco/util/textproc.py,sha256=e5jLTofKCqdm6_Fy8XOyR43AJr5APtL59Kd8cNA9PrQ,2309
|
|
52
52
|
fresco/util/urls.py,sha256=V6-s2WgeARkEcuzpwqtiM8ebOXe5-mNUKOJ8N9LNBHA,10051
|
|
53
53
|
fresco/util/wsgi.py,sha256=RYw4KeOUjzzPOL_HhEtgLyCngofjMdAT8BTLOSKU6KA,13021
|
|
54
|
-
fresco-3.
|
|
55
|
-
fresco-3.
|
|
56
|
-
fresco-3.
|
|
57
|
-
fresco-3.
|
|
58
|
-
fresco-3.
|
|
54
|
+
fresco-3.8.0.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
55
|
+
fresco-3.8.0.dist-info/METADATA,sha256=_EHQUpLmItoT9bDqEuuzfXbofdMjSQfnivFCrGjNlF4,1523
|
|
56
|
+
fresco-3.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
57
|
+
fresco-3.8.0.dist-info/top_level.txt,sha256=p_1aMce5Shjq9fIfdbB-aN8wCDhjF_iYnn98bUebbII,7
|
|
58
|
+
fresco-3.8.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|