13 Commits

Author SHA256 Message Date
13dbb0b66c Accepting request 1300396 from devel:languages:python
- Convert to libalternatives on SLE-16-based and newer systems

OBS-URL: https://build.opensuse.org/request/show/1300396
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=29
2025-08-20 11:26:19 +00:00
56db6d0738 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=68 2025-08-20 06:49:35 +00:00
62fb66a27b - Convert to libalternatives on SLE-16-based and newer systems
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=67
2025-08-19 12:25:48 +00:00
86c7d5129c Accepting request 1291282 from devel:languages:python
- Convert to libalternatives

OBS-URL: https://build.opensuse.org/request/show/1291282
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=28
2025-07-09 15:27:45 +00:00
7fcebf74b5 - Convert to libalternatives
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=65
2025-07-08 13:24:23 +00:00
3987ef8b38 Accepting request 1256063 from devel:languages:python
OBS-URL: https://build.opensuse.org/request/show/1256063
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=27
2025-03-26 20:19:44 +00:00
937f80fbe9 Accepting request 1256021 from home:mcalabkova:branches:devel:languages:python
- Add websockets.patch to fix test failure

OBS-URL: https://build.opensuse.org/request/show/1256021
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=63
2025-03-25 20:52:57 +00:00
9768347acc Accepting request 1236160 from devel:languages:python
- Build doc package just for tumbleweed to remove
  pydata-sphinx-theme requirement

OBS-URL: https://build.opensuse.org/request/show/1236160
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=26
2025-01-12 10:14:02 +00:00
638d3461d3 - Build doc package just for tumbleweed to remove
pydata-sphinx-theme requirement

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=61
2025-01-09 12:05:38 +00:00
dfaad2ac82 Accepting request 1223760 from devel:languages:python
OBS-URL: https://build.opensuse.org/request/show/1223760
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=25
2024-11-13 14:28:29 +00:00
26e1a41bd5 Accepting request 1223640 from home:glaubitz:branches:devel:languages:python
- Update to 4.0.2
  * Running Mypy on code that uses parts of falcon.testing would
    previously lead to errors like:
     "Name "falcon.testing.TestClient" is not defined"
    This has been fixed by explicitly exporting the names that
    are imported into the falcon.testing namespace. (#2387)
  * The printable PDF version of our documentation was enabled
    on Read the Docs. (#2365)

OBS-URL: https://build.opensuse.org/request/show/1223640
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=59
2024-11-12 17:08:27 +00:00
5357ddc88c Accepting request 1220150 from devel:languages:python
- Update to 4.0.1:
  * Overview
    + CPython 3.11 - 3.13 is now fully supported.
    + End-of-life Python 3.5, 3.6 & 3.7 are no longer supported.
    + End-of-life Python 3.8 is no longer actively supported.
    + Type checking support was introduced.
    + Falcon is no longer vendoring the python-mimeparse library.
    + A number of undocumented internal helpers were renamed to start with an
      underscore.
    + A number of previously deprecated methods, attributes and classes have
      now been removed.
    + We decided, on the other hand, to keep the deprecated falcon.API alias
      until Falcon 5.0.
    + The deprecated api_helpers was removed in favor of the app_helpers
      module.
    + The function falcon.http_date_to_dt now validates HTTP dates to have
      the correct timezone set. It now also returns timezone-aware
      datetime.datetime objects.
    + setup.cfg was dropped in favor of consolidating all static project
      configuration in pyproject.toml
  * New & Improved
    + A new path converter falcon.routing.PathConverter
      capable of matching segments that include / was added.
    + Similar to the existing falcon.routing.IntConverter, a new
      falcon.routing.FloatConverter has been added, allowing to convert
      path segments to float.
    + A new method falcon.Request.get_header_as_int was implemented.
    + A new property, falcon.Request.headers_lower, was added to provide a
      unified, self-documenting way to get a copy of all request headers with
      lowercase names to facilitate case-insensitive matching.

OBS-URL: https://build.opensuse.org/request/show/1220150
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-falcon?expand=0&rev=24
2024-11-02 15:11:54 +00:00
60805abe63 - Update to 4.0.1:
* Overview
    + CPython 3.11 - 3.13 is now fully supported.
    + End-of-life Python 3.5, 3.6 & 3.7 are no longer supported.
    + End-of-life Python 3.8 is no longer actively supported.
    + Type checking support was introduced.
    + Falcon is no longer vendoring the python-mimeparse library.
    + A number of undocumented internal helpers were renamed to start with an
      underscore.
    + A number of previously deprecated methods, attributes and classes have
      now been removed.
    + We decided, on the other hand, to keep the deprecated falcon.API alias
      until Falcon 5.0.
    + The deprecated api_helpers was removed in favor of the app_helpers
      module.
    + The function falcon.http_date_to_dt now validates HTTP dates to have
      the correct timezone set. It now also returns timezone-aware
      datetime.datetime objects.
    + setup.cfg was dropped in favor of consolidating all static project
      configuration in pyproject.toml
  * New & Improved
    + A new path converter falcon.routing.PathConverter
      capable of matching segments that include / was added.
    + Similar to the existing falcon.routing.IntConverter, a new
      falcon.routing.FloatConverter has been added, allowing to convert
      path segments to float.
    + A new method falcon.Request.get_header_as_int was implemented.
    + A new property, falcon.Request.headers_lower, was added to provide a
      unified, self-documenting way to get a copy of all request headers with
      lowercase names to facilitate case-insensitive matching.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-falcon?expand=0&rev=57
2024-11-02 06:34:21 +00:00
5 changed files with 222 additions and 68 deletions

BIN
falcon-4.0.2.tar.gz LFS Normal file

Binary file not shown.

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c13e86e49696d6655411fe09473c34997e49ff45e8cdf7576297b0ca71ceac3d
size 665894

View File

@@ -1,67 +1,3 @@
-------------------------------------------------------------------
Wed Nov 12 11:43:09 UTC 2025 - Bernhard Wiedemann <bwiedemann@suse.com>
- 4.2.0
* Typing enhancements and performance optimizations
* Fix reproducible builds of docs
-------------------------------------------------------------------
Tue Oct 28 09:03:20 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
- Update to 4.1.0
* CPython 3.14 is now fully supported. (#2413)
* Although the Falcon 4.x series is only guaranteed to support Python 3.10+,
this release still supports 3.8 & 3.9 at runtime using the pure Python wheel.
* Falcon 4.2 is expected to drop the end-of-life Python 3.8 completely (but
runtime support will continue for 3.9 on a best effort basis).
* StaticRoute now renders Etag headers. It also checks If-None-Match in requests
and returns HTTP 304 response if appropriate. (#2243)
* StaticRoute now sets the Last-Modified header when serving static files. The
improved implementation also checks the value of the If-Modified-Since header,
and renders an HTTP 304 response when the requested file has not been modified. (#2244)
* Similar to create_environ(), the create_scope() testing helper now preserves the
raw URI path, and propagates it to the created ASGI connection scope as the
raw_path byte string (according to the ASGI specification). (#2262)
* Two new media_type constants, falcon.MEDIA_CSV and falcon.MEDIA_PARQUET, were
added in order to provide better support for Python data analysis applications
out of the box. (#2335)
* Support for allowing cross-origin private network access was added to the built-in
CORSMiddleware. The new feature is off by default, and can be enabled by passing
the keyword argument allow_private_network=True to CORSMiddleware during
initialization. (#2381)
* The falcon.secure_filename() utility function can now ensure that the length of the
sanitized filename does not exceed the requested limit (passed via the max_length
argument). In addition, a new option, max_secure_filename_length, was added to
MultipartParseOptions in order to automatically populate this argument when
referencing a body parts secure_filename. (#2420)
* The unset_cookie() method now accepts a same_site parameter (with underscore) for
consistency with set_cookie(). The previous samesite parameter (without underscore)
is now deprecated (referencing it will emit a deprecation warning). (#2453)
* A new method, __rich__, has been added to falcon.testing.Result for facilitating
a rich-text representation when used together with the popular rich library.
* The cythonization process was revised in the light of the performance improvements
in newer CPython versions (especially 3.12+), and the compilation is now largely
confined to hand-crafted C/Cython code. As a result, the framework should run even
faster on modern CPython. (#2470)
* JSONHandler can now detect a non-standard (not a subclass of ValueError) deserialization
error type for a custom loads function.
(Normally, json.loads() and third party alternatives do raise a subclass of ValueError
on invalid input data, however, this is not the case for, e.g., the popular msgspec
library at the time of writing.) (#2476)
* Previously, Falcons WebSocket implementation was not documented to route the request
to any sink. However, in the case of a missing route, a matching sink was actually
invoked, passing ws in place of the incompatible resp.
This mismatch has been addressed by introducing a ws keyword argument (similar to
ASGI error handlers) for sink functions meant to accept WebSocket connections.
For backwards-compatibility, when ws is absent from the sinks signature, the WebSocket
object is still passed in place of the incompatible resp. This behavior will change in
Falcon 5.0: when draining a WebSocket connection, resp will always be set to None. (#2414)
* The readability of the Contributing docs was improved by properly rendering GitHub
Markdown-flavored checkboxes. (#2318)
* The falcon.testing.httpnow compatibility alias is now considered deprecated, and will
be removed in Falcon 5.0. Use the falcon.http_now() function instead. (#2389)
- Drop websockets.patch, merged upstream
-------------------------------------------------------------------
Tue Aug 19 12:18:37 UTC 2025 - Markéta Machová <mmachova@suse.com>

View File

@@ -28,12 +28,14 @@
%endif
%{?sle15_python_module_pythons}
Name: python-falcon
Version: 4.2.0
Version: 4.0.2
Release: 0
Summary: A web framework for building APIs and app backends
License: Apache-2.0
URL: https://falconframework.org
Source: https://files.pythonhosted.org/packages/source/f/falcon/falcon-%{version}.tar.gz
# PATCH-FIX-UPSTREAM https://github.com/falconry/falcon/pull/2406 chore(tests/asgi): migrate to the new websockets async client
Patch0: websockets.patch
BuildRequires: %{python_module PyYAML}
BuildRequires: %{python_module Sphinx}
BuildRequires: %{python_module base >= 3.8}

216
websockets.patch Normal file
View File

@@ -0,0 +1,216 @@
From cf51816a2f7cd7a23d3e1129fe9418a5fc85d8be Mon Sep 17 00:00:00 2001
From: Vytautas Liuolia <vytautas.liuolia@gmail.com>
Date: Mon, 11 Nov 2024 08:43:02 +0100
Subject: [PATCH] chore(tests/asgi): migrate to the new `websockets` async
client (#2406)
* chore(tests/asgi): migrate to the new `websockets` async client
* chore: update the unsupported WS protocol exception for Daphne/Hypercorn
---
requirements/tests | 2 +-
tests/asgi/test_asgi_servers.py | 67 +++++++++++++++++----------------
2 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/requirements/tests b/requirements/tests
index ada7c3729..36825fd23 100644
--- a/requirements/tests
+++ b/requirements/tests
@@ -13,7 +13,7 @@ testtools; python_version < '3.10'
aiofiles
httpx
uvicorn >= 0.17.0
-websockets
+websockets >= 13.1
# Handler Specific
cbor2
diff --git a/tests/asgi/test_asgi_servers.py b/tests/asgi/test_asgi_servers.py
index eb35ac62d..044d46a38 100644
--- a/tests/asgi/test_asgi_servers.py
+++ b/tests/asgi/test_asgi_servers.py
@@ -24,6 +24,7 @@
try:
import websockets
+ import websockets.asyncio.client
import websockets.exceptions
except ImportError:
websockets = None # type: ignore
@@ -232,9 +233,9 @@ async def test_hello(
if close_code:
extra_headers['X-Close-Code'] = str(close_code)
- async with websockets.connect(
+ async with websockets.asyncio.client.connect(
server_url_events_ws,
- extra_headers=extra_headers,
+ additional_headers=extra_headers,
) as ws:
got_message = False
@@ -273,22 +274,22 @@ async def test_rejected(self, explicit_close, close_code, server_url_events_ws):
if close_code:
extra_headers['X-Close-Code'] = str(close_code)
- with pytest.raises(websockets.exceptions.InvalidStatusCode) as exc_info:
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ with pytest.raises(websockets.exceptions.InvalidStatus) as exc_info:
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
):
pass
- assert exc_info.value.status_code == 403
+ assert exc_info.value.response.status_code == 403
async def test_missing_responder(self, server_url_events_ws):
server_url_events_ws += '/404'
- with pytest.raises(websockets.exceptions.InvalidStatusCode) as exc_info:
- async with websockets.connect(server_url_events_ws):
+ with pytest.raises(websockets.exceptions.InvalidStatus) as exc_info:
+ async with websockets.asyncio.client.connect(server_url_events_ws):
pass
- assert exc_info.value.status_code == 403
+ assert exc_info.value.response.status_code == 403
@pytest.mark.parametrize(
'subprotocol, expected',
@@ -301,9 +302,9 @@ async def test_select_subprotocol_known(
self, subprotocol, expected, server_url_events_ws
):
extra_headers = {'X-Subprotocol': subprotocol}
- async with websockets.connect(
+ async with websockets.asyncio.client.connect(
server_url_events_ws,
- extra_headers=extra_headers,
+ additional_headers=extra_headers,
subprotocols=['amqp', 'wamp'],
) as ws:
assert ws.subprotocol == expected
@@ -312,9 +313,9 @@ async def test_select_subprotocol_unknown(self, server_url_events_ws):
extra_headers = {'X-Subprotocol': 'xmpp'}
try:
- async with websockets.connect(
+ async with websockets.asyncio.client.connect(
server_url_events_ws,
- extra_headers=extra_headers,
+ additional_headers=extra_headers,
subprotocols=['amqp', 'wamp'],
):
pass
@@ -329,8 +330,8 @@ async def test_select_subprotocol_unknown(self, server_url_events_ws):
except websockets.exceptions.NegotiationError as ex:
assert 'unsupported subprotocol: xmpp' in str(ex)
- # Daphne
- except websockets.exceptions.InvalidMessage:
+ # Daphne, Hypercorn
+ except EOFError:
pass
# NOTE(kgriffs): When executing this test under pytest with the -s
@@ -340,8 +341,8 @@ async def test_select_subprotocol_unknown(self, server_url_events_ws):
# but the usual ways of capturing stdout/stderr with pytest do
# not work.
async def test_disconnecting_client_early(self, server_url_events_ws):
- ws = await websockets.connect(
- server_url_events_ws, extra_headers={'X-Close': 'True'}
+ ws = await websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers={'X-Close': 'True'}
)
await asyncio.sleep(0.2)
@@ -361,8 +362,8 @@ async def test_disconnecting_client_early(self, server_url_events_ws):
async def test_send_before_accept(self, server_url_events_ws):
extra_headers = {'x-accept': 'skip'}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
message = await ws.recv()
assert message == 'OperationNotAllowed'
@@ -370,8 +371,8 @@ async def test_send_before_accept(self, server_url_events_ws):
async def test_recv_before_accept(self, server_url_events_ws):
extra_headers = {'x-accept': 'skip', 'x-command': 'recv'}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
message = await ws.recv()
assert message == 'OperationNotAllowed'
@@ -379,8 +380,8 @@ async def test_recv_before_accept(self, server_url_events_ws):
async def test_invalid_close_code(self, server_url_events_ws):
extra_headers = {'x-close': 'True', 'x-close-code': 42}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
start = time.time()
@@ -395,22 +396,22 @@ async def test_invalid_close_code(self, server_url_events_ws):
async def test_close_code_on_unhandled_error(self, server_url_events_ws):
extra_headers = {'x-raise-error': 'generic'}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
await ws.wait_closed()
- assert ws.close_code in {3011, 1011}
+ assert ws.protocol.close_code in {3011, 1011}
async def test_close_code_on_unhandled_http_error(self, server_url_events_ws):
extra_headers = {'x-raise-error': 'http'}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
await ws.wait_closed()
- assert ws.close_code == 3400
+ assert ws.protocol.close_code == 3400
@pytest.mark.parametrize('mismatch', ['send', 'recv'])
@pytest.mark.parametrize('mismatch_type', ['text', 'data'])
@@ -420,8 +421,8 @@ async def test_type_mismatch(self, mismatch, mismatch_type, server_url_events_ws
'X-Mismatch-Type': mismatch_type,
}
- async with websockets.connect(
- server_url_events_ws, extra_headers=extra_headers
+ async with websockets.asyncio.client.connect(
+ server_url_events_ws, additional_headers=extra_headers
) as ws:
if mismatch == 'recv':
if mismatch_type == 'text':
@@ -431,13 +432,13 @@ async def test_type_mismatch(self, mismatch, mismatch_type, server_url_events_ws
await ws.wait_closed()
- assert ws.close_code in {3011, 1011}
+ assert ws.protocol.close_code in {3011, 1011}
async def test_passing_path_params(self, server_base_url_ws):
expected_feed_id = '1ee7'
url = f'{server_base_url_ws}feeds/{expected_feed_id}'
- async with websockets.connect(url) as ws:
+ async with websockets.asyncio.client.connect(url) as ws:
feed_id = await ws.recv()
assert feed_id == expected_feed_id