diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-03-12 10:37:13 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-03-12 10:37:13 +0000 |
commit | b27c447af8bffc727382c0dc75272e261cbb4ac4 (patch) | |
tree | e0f6199fec84ae26bb5ea26566fa1daa12693e3b /contrib/python | |
parent | cb56e1cde2824ff3b64be1de4794bff3cab0db61 (diff) | |
parent | d06e9749bd6f0a561ee4fe296cdb3e03a24d1f82 (diff) | |
download | ydb-b27c447af8bffc727382c0dc75272e261cbb4ac4.tar.gz |
Merge pull request #15611 from ydb-platform/merge-libs-250312-0708
Diffstat (limited to 'contrib/python')
-rw-r--r-- | contrib/python/Flask-Cors/py3/.dist-info/METADATA | 156 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/LICENSE | 7 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/README.rst | 18 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/flask_cors/__init__.py | 12 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/flask_cors/core.py | 234 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/flask_cors/decorator.py | 26 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/flask_cors/extension.py | 65 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/flask_cors/version.py | 2 | ||||
-rw-r--r-- | contrib/python/Flask-Cors/py3/ya.make | 3 |
9 files changed, 180 insertions, 343 deletions
diff --git a/contrib/python/Flask-Cors/py3/.dist-info/METADATA b/contrib/python/Flask-Cors/py3/.dist-info/METADATA index 99902fe9d6..39f042019a 100644 --- a/contrib/python/Flask-Cors/py3/.dist-info/METADATA +++ b/contrib/python/Flask-Cors/py3/.dist-info/METADATA @@ -1,148 +1,22 @@ -Metadata-Version: 2.1 -Name: Flask-Cors -Version: 5.0.0 -Summary: A Flask extension adding a decorator for CORS support -Home-page: https://github.com/corydolphin/flask-cors -Author: Cory Dolphin -Author-email: corydolphin@gmail.com -License: MIT -Platform: any -Classifier: Environment :: Web Environment +Metadata-Version: 2.2 +Name: flask-cors +Version: 5.0.1 +Summary: A Flask extension simplifying CORS support +Author-email: Cory Dolphin <corydolphin@gmail.com> +Project-URL: Homepage, https://corydolphin.github.io/flask-cors/ +Project-URL: Repository, https://github.com/corydolphin/flask-cors +Project-URL: Documentation, https://corydolphin.github.io/flask-cors/ +Keywords: python Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Programming Language :: Python :: 3.13 Classifier: Topic :: Software Development :: Libraries :: Python Modules -License-File: LICENSE -Requires-Dist: Flask >=0.9 - -Flask-CORS -========== - -|Build Status| |Latest Version| |Supported Python versions| -|License| - -A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible. - -This package has a simple philosophy: when you want to enable CORS, you wish to enable it for all use cases on a domain. -This means no mucking around with different allowed headers, methods, etc. - -By default, submission of cookies across domains is disabled due to the security implications. -Please see the documentation for how to enable credential'ed requests, and please make sure you add some sort of `CSRF <http://en.wikipedia.org/wiki/Cross-site_request_forgery>`__ protection before doing so! - -Installation ------------- - -Install the extension with using pip, or easy\_install. - -.. code:: bash - - $ pip install -U flask-cors - -Usage ------ - -This package exposes a Flask extension which by default enables CORS support on all routes, for all origins and methods. -It allows parameterization of all CORS headers on a per-resource level. -The package also contains a decorator, for those who prefer this approach. - -Simple Usage -~~~~~~~~~~~~ - -In the simplest case, initialize the Flask-Cors extension with default arguments in order to allow CORS for all domains on all routes. -See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__. - -.. code:: python - - - from flask import Flask - from flask_cors import CORS - - app = Flask(__name__) - CORS(app) - - @app.route("/") - def helloWorld(): - return "Hello, cross-origin-world!" - -Resource specific CORS -^^^^^^^^^^^^^^^^^^^^^^ - -Alternatively, you can specify CORS options on a resource and origin level of granularity by passing a dictionary as the `resources` option, mapping paths to a set of options. -See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__. - -.. code:: python - - app = Flask(__name__) - cors = CORS(app, resources={r"/api/*": {"origins": "*"}}) - - @app.route("/api/v1/users") - def list_users(): - return "user example" - -Route specific CORS via decorator -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This extension also exposes a simple decorator to decorate flask routes with. -Simply add ``@cross_origin()`` below a call to Flask's ``@app.route(..)`` to allow CORS on a given route. -See the full list of options in the `decorator documentation <https://flask-cors.corydolphin.com/en/latest/api.html#decorator>`__. - -.. code:: python - - @app.route("/") - @cross_origin() - def helloWorld(): - return "Hello, cross-origin-world!" - -Documentation -------------- - -For a full list of options, please see the full `documentation <https://flask-cors.corydolphin.com/en/latest/api.html>`__ - -Troubleshooting ---------------- - -If things aren't working as you expect, enable logging to help understand what is going on under the hood, and why. - -.. code:: python - - logging.getLogger('flask_cors').level = logging.DEBUG - - -Tests ------ - -A simple set of tests is included in ``test/``. -To run, install nose, and simply invoke ``nosetests`` or ``python setup.py test`` to exercise the tests. - -If nosetests does not work for you, due to it no longer working with newer python versions. -You can use pytest to run the tests instead. - -Contributing ------------- - -Questions, comments or improvements? -Please create an issue on `Github <https://github.com/corydolphin/flask-cors>`__, tweet at `@corydolphin <https://twitter.com/corydolphin>`__ or send me an email. -I do my best to include every contribution proposed in any way that I can. - -Credits -------- - -This Flask extension is based upon the `Decorator for the HTTP Access Control <https://web.archive.org/web/20190128010149/http://flask.pocoo.org/snippets/56/>`__ written by Armin Ronacher. - -.. |Build Status| image:: https://github.com/corydolphin/flask-cors/actions/workflows/unittests.yaml/badge.svg - :target: https://travis-ci.org/corydolphin/flask-cors -.. |Latest Version| image:: https://img.shields.io/pypi/v/Flask-Cors.svg - :target: https://pypi.python.org/pypi/Flask-Cors/ -.. |Supported Python versions| image:: https://img.shields.io/pypi/pyversions/Flask-Cors.svg - :target: https://img.shields.io/pypi/pyversions/Flask-Cors.svg -.. |License| image:: http://img.shields.io/:license-mit-blue.svg - :target: https://pypi.python.org/pypi/Flask-Cors/ +Requires-Python: <4.0,>=3.9 +Description-Content-Type: text/markdown +Requires-Dist: flask>=0.9 +Requires-Dist: Werkzeug>=0.7 diff --git a/contrib/python/Flask-Cors/py3/LICENSE b/contrib/python/Flask-Cors/py3/LICENSE deleted file mode 100644 index 46d932f8d8..0000000000 --- a/contrib/python/Flask-Cors/py3/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (C) 2016 Cory Dolphin, Olin College - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/contrib/python/Flask-Cors/py3/README.rst b/contrib/python/Flask-Cors/py3/README.rst index 091ef4cf61..d685f54d4d 100644 --- a/contrib/python/Flask-Cors/py3/README.rst +++ b/contrib/python/Flask-Cors/py3/README.rst @@ -32,7 +32,7 @@ Simple Usage ~~~~~~~~~~~~ In the simplest case, initialize the Flask-Cors extension with default arguments in order to allow CORS for all domains on all routes. -See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__. +See the full list of options in the `documentation <https://flask-cors.readthedocs.io/en/latest/api.html#extension>`__. .. code:: python @@ -51,7 +51,7 @@ Resource specific CORS ^^^^^^^^^^^^^^^^^^^^^^ Alternatively, you can specify CORS options on a resource and origin level of granularity by passing a dictionary as the `resources` option, mapping paths to a set of options. -See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__. +See the full list of options in the `documentation <https://flask-cors.readthedocs.io/en/latest/api.html#extension>`__. .. code:: python @@ -67,7 +67,7 @@ Route specific CORS via decorator This extension also exposes a simple decorator to decorate flask routes with. Simply add ``@cross_origin()`` below a call to Flask's ``@app.route(..)`` to allow CORS on a given route. -See the full list of options in the `decorator documentation <https://flask-cors.corydolphin.com/en/latest/api.html#decorator>`__. +See the full list of options in the `decorator documentation <https://flask-cors.readthedocs.io/en/latest/api.html#decorator>`__. .. code:: python @@ -79,7 +79,7 @@ See the full list of options in the `decorator documentation <https://flask-cors Documentation ------------- -For a full list of options, please see the full `documentation <https://flask-cors.corydolphin.com/en/latest/api.html>`__ +For a full list of options, please see the full `documentation <https://flask-cors.readthedocs.io/en/latest/api.html>`__ Troubleshooting --------------- @@ -91,14 +91,12 @@ If things aren't working as you expect, enable logging to help understand what i logging.getLogger('flask_cors').level = logging.DEBUG -Tests ------ -A simple set of tests is included in ``test/``. -To run, install nose, and simply invoke ``nosetests`` or ``python setup.py test`` to exercise the tests. +Set Up Your Development Environment +--- +The development environment uses `uv` for Python version management as well as dependency management. +There are helpful Makefile targets to do everything you need. Use `make test` to get started! -If nosetests does not work for you, due to it no longer working with newer python versions. -You can use pytest to run the tests instead. Contributing ------------ diff --git a/contrib/python/Flask-Cors/py3/flask_cors/__init__.py b/contrib/python/Flask-Cors/py3/flask_cors/__init__.py index 458150efbb..732d401fe8 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/__init__.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/__init__.py @@ -1,18 +1,8 @@ -# -*- coding: utf-8 -*- -""" - flask_cors - ~~~~ - Flask-CORS is a simple extension to Flask allowing you to support cross - origin resource sharing (CORS) using a simple decorator. - - :copyright: (c) 2016 by Cory Dolphin. - :license: MIT, see LICENSE for more details. -""" from .decorator import cross_origin from .extension import CORS from .version import __version__ -__all__ = ['CORS', 'cross_origin'] +__all__ = ["CORS", "__version__", "cross_origin"] # Set default logging handler to avoid "No handler found" warnings. import logging diff --git a/contrib/python/Flask-Cors/py3/flask_cors/core.py b/contrib/python/Flask-Cors/py3/flask_cors/core.py index 3fcc4d346d..0ad0d1da62 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/core.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/core.py @@ -1,63 +1,66 @@ -# -*- coding: utf-8 -*- -""" - core - ~~~~ - Core functionality shared between the extension and the decorator. - - :copyright: (c) 2016 by Cory Dolphin. - :license: MIT, see LICENSE for more details. -""" -import re import logging +import re from collections.abc import Iterable from datetime import timedelta -from flask import request, current_app + +from flask import current_app, request from werkzeug.datastructures import Headers, MultiDict LOG = logging.getLogger(__name__) # Response Headers -ACL_ORIGIN = 'Access-Control-Allow-Origin' -ACL_METHODS = 'Access-Control-Allow-Methods' -ACL_ALLOW_HEADERS = 'Access-Control-Allow-Headers' -ACL_EXPOSE_HEADERS = 'Access-Control-Expose-Headers' -ACL_CREDENTIALS = 'Access-Control-Allow-Credentials' -ACL_MAX_AGE = 'Access-Control-Max-Age' -ACL_RESPONSE_PRIVATE_NETWORK = 'Access-Control-Allow-Private-Network' +ACL_ORIGIN = "Access-Control-Allow-Origin" +ACL_METHODS = "Access-Control-Allow-Methods" +ACL_ALLOW_HEADERS = "Access-Control-Allow-Headers" +ACL_EXPOSE_HEADERS = "Access-Control-Expose-Headers" +ACL_CREDENTIALS = "Access-Control-Allow-Credentials" +ACL_MAX_AGE = "Access-Control-Max-Age" +ACL_RESPONSE_PRIVATE_NETWORK = "Access-Control-Allow-Private-Network" # Request Header -ACL_REQUEST_METHOD = 'Access-Control-Request-Method' -ACL_REQUEST_HEADERS = 'Access-Control-Request-Headers' -ACL_REQUEST_HEADER_PRIVATE_NETWORK = 'Access-Control-Request-Private-Network' - -ALL_METHODS = ['GET', 'HEAD', 'POST', 'OPTIONS', 'PUT', 'PATCH', 'DELETE'] -CONFIG_OPTIONS = ['CORS_ORIGINS', 'CORS_METHODS', 'CORS_ALLOW_HEADERS', - 'CORS_EXPOSE_HEADERS', 'CORS_SUPPORTS_CREDENTIALS', - 'CORS_MAX_AGE', 'CORS_SEND_WILDCARD', - 'CORS_AUTOMATIC_OPTIONS', 'CORS_VARY_HEADER', - 'CORS_RESOURCES', 'CORS_INTERCEPT_EXCEPTIONS', - 'CORS_ALWAYS_SEND', 'CORS_ALLOW_PRIVATE_NETWORK'] +ACL_REQUEST_METHOD = "Access-Control-Request-Method" +ACL_REQUEST_HEADERS = "Access-Control-Request-Headers" +ACL_REQUEST_HEADER_PRIVATE_NETWORK = "Access-Control-Request-Private-Network" + +ALL_METHODS = ["GET", "HEAD", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"] +CONFIG_OPTIONS = [ + "CORS_ORIGINS", + "CORS_METHODS", + "CORS_ALLOW_HEADERS", + "CORS_EXPOSE_HEADERS", + "CORS_SUPPORTS_CREDENTIALS", + "CORS_MAX_AGE", + "CORS_SEND_WILDCARD", + "CORS_AUTOMATIC_OPTIONS", + "CORS_VARY_HEADER", + "CORS_RESOURCES", + "CORS_INTERCEPT_EXCEPTIONS", + "CORS_ALWAYS_SEND", + "CORS_ALLOW_PRIVATE_NETWORK", +] # Attribute added to request object by decorator to indicate that CORS # was evaluated, in case the decorator and extension are both applied # to a view. -FLASK_CORS_EVALUATED = '_FLASK_CORS_EVALUATED' +FLASK_CORS_EVALUATED = "_FLASK_CORS_EVALUATED" # Strange, but this gets the type of a compiled regex, which is otherwise not # exposed in a public API. -RegexObject = type(re.compile('')) -DEFAULT_OPTIONS = dict(origins='*', - methods=ALL_METHODS, - allow_headers='*', - expose_headers=None, - supports_credentials=False, - max_age=None, - send_wildcard=False, - automatic_options=True, - vary_header=True, - resources=r'/*', - intercept_exceptions=True, - always_send=True, - allow_private_network=False) +RegexObject = type(re.compile("")) +DEFAULT_OPTIONS = dict( + origins="*", + methods=ALL_METHODS, + allow_headers="*", + expose_headers=None, + supports_credentials=False, + max_age=None, + send_wildcard=False, + automatic_options=True, + vary_header=True, + resources=r"/*", + intercept_exceptions=True, + always_send=True, + allow_private_network=False, +) def parse_resources(resources): @@ -73,9 +76,7 @@ def parse_resources(resources): maybe_regex, _ = pair return len(get_regexp_pattern(maybe_regex)) - return sorted(resources, - key=pattern_length, - reverse=True) + return sorted(resources, key=pattern_length, reverse=True) elif isinstance(resources, str): return [(re_fix(resources), {})] @@ -85,7 +86,7 @@ def parse_resources(resources): # Type of compiled regex is not part of the public API. Test for this # at runtime. - elif isinstance(resources, RegexObject): + elif isinstance(resources, RegexObject): return [(re_fix(resources), {})] else: @@ -108,8 +109,8 @@ def get_regexp_pattern(regexp): def get_cors_origins(options, request_origin): - origins = options.get('origins') - wildcard = r'.*' in origins + origins = options.get("origins") + wildcard = r".*" in origins # If the Origin header is not present terminate this set of steps. # The request is outside the scope of this specification.-- W3Spec @@ -117,13 +118,15 @@ def get_cors_origins(options, request_origin): LOG.debug("CORS request received with 'Origin' %s", request_origin) # If the allowed origins is an asterisk or 'wildcard', always match - if wildcard and options.get('send_wildcard'): + if wildcard and options.get("send_wildcard"): LOG.debug("Allowed origins are set to '*'. Sending wildcard CORS header.") - return ['*'] + return ["*"] # If the value of the Origin header is a case-sensitive match # for any of the values in list of origins elif try_match_any(request_origin, origins): - LOG.debug("The request's Origin header matches. Sending CORS headers.", ) + LOG.debug( + "The request's Origin header matches. Sending CORS headers.", + ) # Add a single Access-Control-Allow-Origin header, with either # the value of the Origin header or the string "*" as value. # -- W3Spec @@ -132,46 +135,44 @@ def get_cors_origins(options, request_origin): LOG.debug("The request's Origin header does not match any of allowed origins.") return None - - elif options.get('always_send'): + elif options.get("always_send"): if wildcard: # If wildcard is in the origins, even if 'send_wildcard' is False, # simply send the wildcard. Unless supports_credentials is True, - # since that is forbidded by the spec.. + # since that is forbidden by the spec.. # It is the most-likely to be correct thing to do (the only other # option is to return nothing, which almost certainly not what # the developer wants if the '*' origin was specified. - if options.get('supports_credentials'): + if options.get("supports_credentials"): return None else: - return ['*'] + return ["*"] else: # Return all origins that are not regexes. return sorted([o for o in origins if not probably_regex(o)]) # Terminate these steps, return the original request untouched. else: - LOG.debug("The request did not contain an 'Origin' header. This means the browser or client did not request CORS, ensure the Origin Header is set.") + LOG.debug( + "The request did not contain an 'Origin' header. This means the browser or client did not request CORS, ensure the Origin Header is set." + ) return None def get_allow_headers(options, acl_request_headers): if acl_request_headers: - request_headers = [h.strip() for h in acl_request_headers.split(',')] + request_headers = [h.strip() for h in acl_request_headers.split(",")] # any header that matches in the allow_headers - matching_headers = filter( - lambda h: try_match_any(h, options.get('allow_headers')), - request_headers - ) + matching_headers = filter(lambda h: try_match_any(h, options.get("allow_headers")), request_headers) - return ', '.join(sorted(matching_headers)) + return ", ".join(sorted(matching_headers)) return None def get_cors_headers(options, request_headers, request_method): - origins_to_set = get_cors_origins(options, request_headers.get('Origin')) + origins_to_set = get_cors_origins(options, request_headers.get("Origin")) headers = MultiDict() if not origins_to_set: # CORS is not enabled for this route @@ -180,45 +181,50 @@ def get_cors_headers(options, request_headers, request_method): for origin in origins_to_set: headers.add(ACL_ORIGIN, origin) - headers[ACL_EXPOSE_HEADERS] = options.get('expose_headers') + headers[ACL_EXPOSE_HEADERS] = options.get("expose_headers") - if options.get('supports_credentials'): - headers[ACL_CREDENTIALS] = 'true' # case sensitive + if options.get("supports_credentials"): + headers[ACL_CREDENTIALS] = "true" # case sensitive - if ACL_REQUEST_HEADER_PRIVATE_NETWORK in request_headers \ - and request_headers.get(ACL_REQUEST_HEADER_PRIVATE_NETWORK) == 'true': - allow_private_network = 'true' if options.get('allow_private_network') else 'false' + if ( + ACL_REQUEST_HEADER_PRIVATE_NETWORK in request_headers + and request_headers.get(ACL_REQUEST_HEADER_PRIVATE_NETWORK) == "true" + ): + allow_private_network = "true" if options.get("allow_private_network") else "false" headers[ACL_RESPONSE_PRIVATE_NETWORK] = allow_private_network # This is a preflight request # http://www.w3.org/TR/cors/#resource-preflight-requests - if request_method == 'OPTIONS': - acl_request_method = request_headers.get(ACL_REQUEST_METHOD, '').upper() + if request_method == "OPTIONS": + acl_request_method = request_headers.get(ACL_REQUEST_METHOD, "").upper() # If there is no Access-Control-Request-Method header or if parsing # failed, do not set any additional headers - if acl_request_method and acl_request_method in options.get('methods'): - + if acl_request_method and acl_request_method in options.get("methods"): # If method is not a case-sensitive match for any of the values in # list of methods do not set any additional headers and terminate # this set of steps. headers[ACL_ALLOW_HEADERS] = get_allow_headers(options, request_headers.get(ACL_REQUEST_HEADERS)) - headers[ACL_MAX_AGE] = options.get('max_age') - headers[ACL_METHODS] = options.get('methods') + headers[ACL_MAX_AGE] = options.get("max_age") + headers[ACL_METHODS] = options.get("methods") else: - LOG.info("The request's Access-Control-Request-Method header does not match allowed methods. CORS headers will not be applied.") + LOG.info( + "The request's Access-Control-Request-Method header does not match allowed methods. CORS headers will not be applied." + ) # http://www.w3.org/TR/cors/#resource-implementation - if options.get('vary_header'): + if options.get("vary_header"): # Only set header if the origin returned will vary dynamically, # i.e. if we are not returning an asterisk, and there are multiple # origins that can be matched. - if headers[ACL_ORIGIN] == '*': + if headers[ACL_ORIGIN] == "*": pass - elif (len(options.get('origins')) > 1 or - len(origins_to_set) > 1 or - any(map(probably_regex, options.get('origins')))): - headers.add('Vary', 'Origin') + elif ( + len(options.get("origins")) > 1 + or len(origins_to_set) > 1 + or any(map(probably_regex, options.get("origins"))) + ): + headers.add("Vary", "Origin") return MultiDict((k, v) for k, v in headers.items() if v) @@ -234,40 +240,41 @@ def set_cors_headers(resp, options): # If CORS has already been evaluated via the decorator, skip if hasattr(resp, FLASK_CORS_EVALUATED): - LOG.debug('CORS have been already evaluated, skipping') + LOG.debug("CORS have been already evaluated, skipping") return resp # Some libraries, like OAuthlib, set resp.headers to non Multidict # objects (Werkzeug Headers work as well). This is a problem because # headers allow repeated values. - if (not isinstance(resp.headers, Headers) - and not isinstance(resp.headers, MultiDict)): + if not isinstance(resp.headers, Headers) and not isinstance(resp.headers, MultiDict): resp.headers = MultiDict(resp.headers) headers_to_set = get_cors_headers(options, request.headers, request.method) - LOG.debug('Settings CORS headers: %s', str(headers_to_set)) + LOG.debug("Settings CORS headers: %s", str(headers_to_set)) for k, v in headers_to_set.items(): resp.headers.add(k, v) return resp + def probably_regex(maybe_regex): if isinstance(maybe_regex, RegexObject): return True else: - common_regex_chars = ['*', '\\', ']', '?', '$', '^', '[', ']', '(', ')'] + common_regex_chars = ["*", "\\", "]", "?", "$", "^", "[", "]", "(", ")"] # Use common characters used in regular expressions as a proxy # for if this string is in fact a regex. - return any((c in maybe_regex for c in common_regex_chars)) + return any(c in maybe_regex for c in common_regex_chars) + def re_fix(reg): """ - Replace the invalid regex r'*' with the valid, wildcard regex r'/.*' to - enable the CORS app extension to have a more user friendly api. + Replace the invalid regex r'*' with the valid, wildcard regex r'/.*' to + enable the CORS app extension to have a more user friendly api. """ - return r'.*' if reg == r'*' else reg + return r".*" if reg == r"*" else reg def try_match_any(inst, patterns): @@ -304,16 +311,12 @@ def get_cors_options(appInstance, *dicts): def get_app_kwarg_dict(appInstance=None): """Returns the dictionary of CORS specific app configurations.""" - app = (appInstance or current_app) + app = appInstance or current_app # In order to support blueprints which do not have a config attribute - app_config = getattr(app, 'config', {}) + app_config = getattr(app, "config", {}) - return { - k.lower().replace('cors_', ''): app_config.get(k) - for k in CONFIG_OPTIONS - if app_config.get(k) is not None - } + return {k.lower().replace("cors_", ""): app_config.get(k) for k in CONFIG_OPTIONS if app_config.get(k) is not None} def flexible_str(obj): @@ -341,13 +344,12 @@ def ensure_iterable(inst): """ Wraps scalars or string types as a list, or returns the iterable instance. """ - if isinstance(inst, str): - return [inst] - elif not isinstance(inst, Iterable): + if isinstance(inst, str) or not isinstance(inst, Iterable): return [inst] else: return inst + def sanitize_regex_param(param): return [re_fix(x) for x in ensure_iterable(param)] @@ -363,22 +365,22 @@ def serialize_options(opts): LOG.warning("Unknown option passed to Flask-CORS: %s", key) # Ensure origins is a list of allowed origins with at least one entry. - options['origins'] = sanitize_regex_param(options.get('origins')) - options['allow_headers'] = sanitize_regex_param(options.get('allow_headers')) + options["origins"] = sanitize_regex_param(options.get("origins")) + options["allow_headers"] = sanitize_regex_param(options.get("allow_headers")) # This is expressly forbidden by the spec. Raise a value error so people # don't get burned in production. - if r'.*' in options['origins'] and options['supports_credentials'] and options['send_wildcard']: - raise ValueError("Cannot use supports_credentials in conjunction with" - "an origin string of '*'. See: " - "http://www.w3.org/TR/cors/#resource-requests") - - + if r".*" in options["origins"] and options["supports_credentials"] and options["send_wildcard"]: + raise ValueError( + "Cannot use supports_credentials in conjunction with" + "an origin string of '*'. See: " + "http://www.w3.org/TR/cors/#resource-requests" + ) - serialize_option(options, 'expose_headers') - serialize_option(options, 'methods', upper=True) + serialize_option(options, "expose_headers") + serialize_option(options, "methods", upper=True) - if isinstance(options.get('max_age'), timedelta): - options['max_age'] = str(int(options['max_age'].total_seconds())) + if isinstance(options.get("max_age"), timedelta): + options["max_age"] = str(int(options["max_age"].total_seconds())) return options diff --git a/contrib/python/Flask-Cors/py3/flask_cors/decorator.py b/contrib/python/Flask-Cors/py3/flask_cors/decorator.py index b61d22f802..f8915b62d5 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/decorator.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/decorator.py @@ -1,22 +1,13 @@ -# -*- coding: utf-8 -*- -""" - decorator - ~~~~ - This unit exposes a single decorator which should be used to wrap a - Flask route with. It accepts all parameters and options as - the CORS extension. - - :copyright: (c) 2016 by Cory Dolphin. - :license: MIT, see LICENSE for more details. -""" import logging from functools import update_wrapper -from flask import make_response, request, current_app -from .core import get_cors_options, set_cors_headers, FLASK_CORS_EVALUATED +from flask import current_app, make_response, request + +from .core import FLASK_CORS_EVALUATED, get_cors_options, set_cors_headers LOG = logging.getLogger(__name__) + def cross_origin(*args, **kwargs): """ This function is the decorator which is used to wrap a Flask route with. @@ -115,16 +106,16 @@ def cross_origin(*args, **kwargs): # If f.provide_automatic_options is unset or True, Flask's route # decorator (which is actually wraps the function object we return) # intercepts OPTIONS handling, and requests will not have CORS headers - if _options.get('automatic_options', True): - f.required_methods = getattr(f, 'required_methods', set()) - f.required_methods.add('OPTIONS') + if _options.get("automatic_options", True): + f.required_methods = getattr(f, "required_methods", set()) + f.required_methods.add("OPTIONS") f.provide_automatic_options = False def wrapped_function(*args, **kwargs): # Handle setting of Flask-Cors parameters options = get_cors_options(current_app, _options) - if options.get('automatic_options') and request.method == 'OPTIONS': + if options.get("automatic_options") and request.method == "OPTIONS": resp = current_app.make_default_options_response() else: resp = make_response(f(*args, **kwargs)) @@ -134,4 +125,5 @@ def cross_origin(*args, **kwargs): return resp return update_wrapper(wrapped_function, f) + return decorator diff --git a/contrib/python/Flask-Cors/py3/flask_cors/extension.py b/contrib/python/Flask-Cors/py3/flask_cors/extension.py index abf5cafe9c..87e55b7bdd 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/extension.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/extension.py @@ -1,37 +1,21 @@ -# -*- coding: utf-8 -*- -""" - extension - ~~~~ - Flask-CORS is a simple extension to Flask allowing you to support cross - origin resource sharing (CORS) using a simple decorator. - - :copyright: (c) 2016 by Cory Dolphin. - :license: MIT, see LICENSE for more details. -""" import logging from urllib.parse import unquote_plus -from flask import request -from .core import ( - parse_resources, - get_cors_options, - get_regexp_pattern, - ACL_ORIGIN, - try_match, - set_cors_headers -) +from flask import request +from .core import ACL_ORIGIN, get_cors_options, get_regexp_pattern, parse_resources, set_cors_headers, try_match LOG = logging.getLogger(__name__) -class CORS(object): + +class CORS: """ Initializes Cross Origin Resource sharing for the application. The - arguments are identical to :py:func:`cross_origin`, with the addition of a + arguments are identical to `cross_origin`, with the addition of a `resources` parameter. The resources parameter defines a series of regular expressions for resource paths to match and optionally, the associated options to be applied to the particular resource. These options are - identical to the arguments to :py:func:`cross_origin`. + identical to the arguments to `cross_origin`. The settings for CORS are determined in the following order @@ -144,7 +128,7 @@ class CORS(object): will be set with the value 'true' whenever the request header `Access-Control-Request-Private-Network` has a value 'true'. - If False, the reponse header `Access-Control-Allow-Private-Network` + If False, the response header `Access-Control-Allow-Private-Network` will be set with the value 'false' whenever the request header `Access-Control-Request-Private-Network` has a value of 'true'. @@ -168,19 +152,16 @@ class CORS(object): # Flatten our resources into a list of the form # (pattern_or_regexp, dictionary_of_options) - resources = parse_resources(options.get('resources')) + resources = parse_resources(options.get("resources")) # Compute the options for each resource by combining the options from # the app's configuration, the constructor, the kwargs to init_app, and # finally the options specified in the resources dictionary. - resources = [ - (pattern, get_cors_options(app, options, opts)) - for (pattern, opts) in resources - ] + resources = [(pattern, get_cors_options(app, options, opts)) for (pattern, opts) in resources] # Create a human-readable form of these resources by converting the compiled # regular expressions into strings. - resources_human = {get_regexp_pattern(pattern): opts for (pattern,opts) in resources} + resources_human = {get_regexp_pattern(pattern): opts for (pattern, opts) in resources} LOG.debug("Configuring CORS with resources: %s", resources_human) cors_after_request = make_after_request_function(resources) @@ -188,32 +169,38 @@ class CORS(object): # Wrap exception handlers with cross_origin # These error handlers will still respect the behavior of the route - if options.get('intercept_exceptions', True): + if options.get("intercept_exceptions", True): + def _after_request_decorator(f): def wrapped_function(*args, **kwargs): return cors_after_request(app.make_response(f(*args, **kwargs))) + return wrapped_function - if hasattr(app, 'handle_exception'): - app.handle_exception = _after_request_decorator( - app.handle_exception) - app.handle_user_exception = _after_request_decorator( - app.handle_user_exception) + if hasattr(app, "handle_exception"): + app.handle_exception = _after_request_decorator(app.handle_exception) + app.handle_user_exception = _after_request_decorator(app.handle_user_exception) + def make_after_request_function(resources): def cors_after_request(resp): # If CORS headers are set in a view decorator, pass if resp.headers is not None and resp.headers.get(ACL_ORIGIN): - LOG.debug('CORS have been already evaluated, skipping') + LOG.debug("CORS have been already evaluated, skipping") return resp normalized_path = unquote_plus(request.path) for res_regex, res_options in resources: if try_match(normalized_path, res_regex): - LOG.debug("Request to '%r' matches CORS resource '%s'. Using options: %s", - request.path, get_regexp_pattern(res_regex), res_options) + LOG.debug( + "Request to '%r' matches CORS resource '%s'. Using options: %s", + request.path, + get_regexp_pattern(res_regex), + res_options, + ) set_cors_headers(resp, res_options) break else: - LOG.debug('No CORS rule matches') + LOG.debug("No CORS rule matches") return resp + return cors_after_request diff --git a/contrib/python/Flask-Cors/py3/flask_cors/version.py b/contrib/python/Flask-Cors/py3/flask_cors/version.py index a0f66580ce..2fe5fde13b 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/version.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/version.py @@ -1 +1 @@ -__version__ = '5.0.0' +__version__ = "5.0.1" diff --git a/contrib/python/Flask-Cors/py3/ya.make b/contrib/python/Flask-Cors/py3/ya.make index c0e391c849..56b564e1d2 100644 --- a/contrib/python/Flask-Cors/py3/ya.make +++ b/contrib/python/Flask-Cors/py3/ya.make @@ -2,12 +2,13 @@ PY3_LIBRARY() -VERSION(5.0.0) +VERSION(5.0.1) LICENSE(MIT) PEERDIR( contrib/python/Flask + contrib/python/Werkzeug ) NO_LINT() |