Accepting request 1118866 from home:mcalabkova:branches:devel:languages:python
- Repackage, new active upstream * In their words: We were unable to get ahold of the folks at postmanlabs to maintain the original project, and httpbin is used for other packages within the python ecosystem, such as pytest-httpbin which is in turn used by packages such as requests so we have forked this package. That means that httpbin.org is not actually backed by this repo, but the httpbin package is. Confusing right? * Drop now unneeded _service, changes in the *spec - Update to 0.10.1 * Override docker image port with HTTPBIN_PORT * A number of fixes for code rot, thanks @mgorny and @tjni - Drop upstreamed/no-longer-needed patches: * fix-setup-py.patch * httpbin-pr674-wekzeug2.1.patch * werkzeug.patch * support-werkzeug-2.3.patch - Add flask3.patch to support Flask 3.0 OBS-URL: https://build.opensuse.org/request/show/1118866 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-httpbin?expand=0&rev=27
This commit is contained in:
parent
8999a4f3d5
commit
168d17f0d5
14
_service
14
_service
@ -1,14 +0,0 @@
|
|||||||
<services>
|
|
||||||
<service name="tar_scm" mode="disabled">
|
|
||||||
<param name="filename">python-httpbin</param>
|
|
||||||
<param name="url">https://github.com/postmanlabs/httpbin.git</param>
|
|
||||||
<param name="scm">git</param>
|
|
||||||
<param name="changesgenerate">enable</param>
|
|
||||||
<param name="versionformat">0.7.0+git%cd.%h</param>
|
|
||||||
</service>
|
|
||||||
<service name="recompress" mode="disabled">
|
|
||||||
<param name="compression">xz</param>
|
|
||||||
<param name="file">*.tar</param>
|
|
||||||
</service>
|
|
||||||
<service name="set_version" mode="disabled"/>
|
|
||||||
</services>
|
|
@ -1,14 +0,0 @@
|
|||||||
Index: python-httpbin-0.7.0+git20181107.f8ec666/setup.py
|
|
||||||
===================================================================
|
|
||||||
--- python-httpbin-0.7.0+git20181107.f8ec666.orig/setup.py
|
|
||||||
+++ python-httpbin-0.7.0+git20181107.f8ec666/setup.py
|
|
||||||
@@ -35,7 +35,7 @@ setup(
|
|
||||||
packages=find_packages(),
|
|
||||||
include_package_data = True, # include files listed in MANIFEST.in
|
|
||||||
install_requires=[
|
|
||||||
- 'Flask', 'MarkupSafe', 'decorator', 'itsdangerous', 'six', 'brotlipy',
|
|
||||||
- 'raven[flask]', 'werkzeug>=0.14.1', 'gevent', 'flasgger'
|
|
||||||
+ 'Flask>=2.1', 'MarkupSafe', 'decorator', 'itsdangerous', 'six', 'brotli',
|
|
||||||
+ 'werkzeug>=2.0', 'gevent', 'flasgger'
|
|
||||||
],
|
|
||||||
)
|
|
109
flask3.patch
Normal file
109
flask3.patch
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
From c1d9e33049263fed3cb27806a97f094acc350905 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nate Prewitt <nate.prewitt@gmail.com>
|
||||||
|
Date: Thu, 12 Oct 2023 08:30:42 -0700
|
||||||
|
Subject: [PATCH] Support Flask 3.0 (#29)
|
||||||
|
|
||||||
|
---
|
||||||
|
httpbin/core.py | 8 +++-----
|
||||||
|
httpbin/helpers.py | 21 ++++++++++++++++-----
|
||||||
|
pyproject.toml | 3 +--
|
||||||
|
3 files changed, 20 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/httpbin/core.py b/httpbin/core.py
|
||||||
|
index 5c1783a1..a82c1b88 100644
|
||||||
|
--- a/httpbin/core.py
|
||||||
|
+++ b/httpbin/core.py
|
||||||
|
@@ -32,7 +32,7 @@
|
||||||
|
from werkzeug.wrappers import Response
|
||||||
|
except ImportError: # werkzeug < 2.1
|
||||||
|
from werkzeug.wrappers import BaseResponse as Response
|
||||||
|
-from werkzeug.http import parse_authorization_header
|
||||||
|
+
|
||||||
|
from flasgger import Swagger, NO_SANITIZER
|
||||||
|
|
||||||
|
from . import filters
|
||||||
|
@@ -47,6 +47,7 @@
|
||||||
|
H,
|
||||||
|
ROBOT_TXT,
|
||||||
|
ANGRY_ASCII,
|
||||||
|
+ parse_authorization_header,
|
||||||
|
parse_multi_value_header,
|
||||||
|
next_stale_after_value,
|
||||||
|
digest_challenge_response,
|
||||||
|
@@ -636,16 +637,13 @@ def redirect_to():
|
||||||
|
args_dict = request.args.items()
|
||||||
|
args = CaseInsensitiveDict(args_dict)
|
||||||
|
|
||||||
|
- # We need to build the response manually and convert to UTF-8 to prevent
|
||||||
|
- # werkzeug from "fixing" the URL. This endpoint should set the Location
|
||||||
|
- # header to the exact string supplied.
|
||||||
|
response = app.make_response("")
|
||||||
|
response.status_code = 302
|
||||||
|
if "status_code" in args:
|
||||||
|
status_code = int(args["status_code"])
|
||||||
|
if status_code >= 300 and status_code < 400:
|
||||||
|
response.status_code = status_code
|
||||||
|
- response.headers["Location"] = args["url"].encode("utf-8")
|
||||||
|
+ response.headers["Location"] = args["url"]
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
diff --git a/httpbin/helpers.py b/httpbin/helpers.py
|
||||||
|
index b29e1835..836c8026 100644
|
||||||
|
--- a/httpbin/helpers.py
|
||||||
|
+++ b/httpbin/helpers.py
|
||||||
|
@@ -13,8 +13,14 @@
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
from hashlib import md5, sha256, sha512
|
||||||
|
-from werkzeug.http import parse_authorization_header
|
||||||
|
from werkzeug.datastructures import WWWAuthenticate
|
||||||
|
+from werkzeug.http import dump_header
|
||||||
|
+
|
||||||
|
+try:
|
||||||
|
+ from werkzeug.http import parse_authorization_header
|
||||||
|
+except ImportError: # werkzeug < 2.3
|
||||||
|
+ from werkzeug.datastructures import Authorization
|
||||||
|
+ parse_authorization_header = Authorization.from_header
|
||||||
|
|
||||||
|
from flask import request, make_response
|
||||||
|
from six.moves.urllib.parse import urlparse, urlunparse
|
||||||
|
@@ -466,9 +472,14 @@ def digest_challenge_response(app, qop, algorithm, stale = False):
|
||||||
|
]), algorithm)
|
||||||
|
opaque = H(os.urandom(10), algorithm)
|
||||||
|
|
||||||
|
- auth = WWWAuthenticate("digest")
|
||||||
|
- auth.set_digest('me@kennethreitz.com', nonce, opaque=opaque,
|
||||||
|
- qop=('auth', 'auth-int') if qop is None else (qop,), algorithm=algorithm)
|
||||||
|
- auth.stale = stale
|
||||||
|
+ values = {
|
||||||
|
+ 'realm': 'me@kennethreitz.com',
|
||||||
|
+ 'nonce': nonce,
|
||||||
|
+ 'opaque': opaque,
|
||||||
|
+ 'qop': dump_header(('auth', 'auth-int') if qop is None else (qop,)),
|
||||||
|
+ 'algorithm': algorithm,
|
||||||
|
+ 'stale': stale,
|
||||||
|
+ }
|
||||||
|
+ auth = WWWAuthenticate("digest", values=values)
|
||||||
|
response.headers['WWW-Authenticate'] = auth.to_header()
|
||||||
|
return response
|
||||||
|
diff --git a/pyproject.toml b/pyproject.toml
|
||||||
|
index 020457ec..9454e569 100644
|
||||||
|
--- a/pyproject.toml
|
||||||
|
+++ b/pyproject.toml
|
||||||
|
@@ -31,14 +31,13 @@ classifiers = [
|
||||||
|
"Programming Language :: Python :: 3.12",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
- "Flask",
|
||||||
|
+ "flask >= 2.2.4",
|
||||||
|
"brotlicffi",
|
||||||
|
"decorator",
|
||||||
|
"flasgger",
|
||||||
|
'greenlet < 3.0; python_version<"3.12"',
|
||||||
|
'greenlet >= 3.0.0a1; python_version>="3.12.0rc0"',
|
||||||
|
'importlib-metadata; python_version<"3.8"',
|
||||||
|
- "werkzeug >= 0.14.1",
|
||||||
|
"six",
|
||||||
|
]
|
||||||
|
|
BIN
httpbin-0.10.1.tar.gz
(Stored with Git LFS)
Normal file
BIN
httpbin-0.10.1.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1,32 +0,0 @@
|
|||||||
From 5cc81ce87a3c447a127e4a1a707faf9f3b1c9b6b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maximino BOGADO <bogamax2@hotmail.fr>
|
|
||||||
Date: Wed, 30 Mar 2022 16:26:31 +0200
|
|
||||||
Subject: [PATCH] Replace BaseResponse to Response class (new werkzeug version
|
|
||||||
2.1.0)
|
|
||||||
|
|
||||||
---
|
|
||||||
httpbin/core.py | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/httpbin/core.py b/httpbin/core.py
|
|
||||||
index 305c9882..2bad408e 100644
|
|
||||||
--- a/httpbin/core.py
|
|
||||||
+++ b/httpbin/core.py
|
|
||||||
@@ -29,7 +29,7 @@
|
|
||||||
from six.moves import range as xrange
|
|
||||||
from werkzeug.datastructures import WWWAuthenticate, MultiDict
|
|
||||||
from werkzeug.http import http_date
|
|
||||||
-from werkzeug.wrappers import BaseResponse
|
|
||||||
+from werkzeug.wrappers import Response
|
|
||||||
from werkzeug.http import parse_authorization_header
|
|
||||||
from flasgger import Swagger, NO_SANITIZER
|
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ def jsonify(*args, **kwargs):
|
|
||||||
|
|
||||||
|
|
||||||
# Prevent WSGI from correcting the casing of the Location header
|
|
||||||
-BaseResponse.autocorrect_location_header = False
|
|
||||||
+Response.autocorrect_location_header = False
|
|
||||||
|
|
||||||
# Find the correct template folder when running from a different location
|
|
||||||
tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates")
|
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:6ca690b5d5d0b1e75a947559663400492c48be4713502f9466da658d4270f638
|
|
||||||
size 98088
|
|
@ -1,3 +1,24 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Oct 19 08:11:44 UTC 2023 - Markéta Machová <mmachova@suse.com>
|
||||||
|
|
||||||
|
- Repackage, new active upstream
|
||||||
|
* In their words: We were unable to get ahold of the folks at postmanlabs to
|
||||||
|
maintain the original project, and httpbin is used for other packages
|
||||||
|
within the python ecosystem, such as pytest-httpbin which is in turn used
|
||||||
|
by packages such as requests so we have forked this package. That means
|
||||||
|
that httpbin.org is not actually backed by this repo, but the httpbin
|
||||||
|
package is. Confusing right?
|
||||||
|
* Drop now unneeded _service, changes in the *spec
|
||||||
|
- Update to 0.10.1
|
||||||
|
* Override docker image port with HTTPBIN_PORT
|
||||||
|
* A number of fixes for code rot, thanks @mgorny and @tjni
|
||||||
|
- Drop upstreamed/no-longer-needed patches:
|
||||||
|
* fix-setup-py.patch
|
||||||
|
* httpbin-pr674-wekzeug2.1.patch
|
||||||
|
* werkzeug.patch
|
||||||
|
* support-werkzeug-2.3.patch
|
||||||
|
- Add flask3.patch to support Flask 3.0
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Jun 21 08:35:31 UTC 2023 - Steve Kowalik <steven.kowalik@suse.com>
|
Wed Jun 21 08:35:31 UTC 2023 - Steve Kowalik <steven.kowalik@suse.com>
|
||||||
|
|
||||||
|
@ -16,44 +16,35 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
# The PyPI version is 0.7.0 but the metadata reads an internal file with version 0.9.2
|
%define modname httpbin
|
||||||
%define internalversion 0.9.2
|
|
||||||
%{?sle15_python_module_pythons}
|
%{?sle15_python_module_pythons}
|
||||||
Name: python-httpbin
|
Name: python-httpbin
|
||||||
Version: 0.7.0+git20181107.f8ec666
|
Version: 0.10.1
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: HTTP Request and Response Service
|
Summary: HTTP Request and Response Service
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://github.com/Runscope/httpbin
|
URL: https://github.com/psf/httpbin
|
||||||
Source: python-httpbin-%{version}.tar.xz
|
Source: https://files.pythonhosted.org/packages/source/h/%{modname}/%{modname}-%{version}.tar.gz
|
||||||
# PATCH-FIX-UPSTREAM werkzeug.patch -- gh#postmanlabs/httpbin#555
|
# PATCH-FIX-UPSTREAM https://github.com/psf/httpbin/pull/29 Support Flask 3.0
|
||||||
Patch0: werkzeug.patch
|
Patch: flask3.patch
|
||||||
# PATCH-FIX-UPSTREAM fix-setup-py.patch -- gh#postmanlabs/httpbin#553
|
BuildRequires: %{python_module Flask >= 2.2.4}
|
||||||
Patch1: fix-setup-py.patch
|
|
||||||
# PATCH-FIX-UPSTREAM httpbin-pr674-wekzeug2.1.patch -- gh#postmanlabs/httpbin#674
|
|
||||||
Patch2: httpbin-pr674-wekzeug2.1.patch
|
|
||||||
# PATCH-FIX-OPENSUSE Support Werkzeug >= 2.3
|
|
||||||
Patch3: support-werkzeug-2.3.patch
|
|
||||||
BuildRequires: %{python_module Brotli}
|
|
||||||
BuildRequires: %{python_module Flask >= 2.1}
|
|
||||||
BuildRequires: %{python_module MarkupSafe}
|
|
||||||
BuildRequires: %{python_module Werkzeug >= 2.0}
|
BuildRequires: %{python_module Werkzeug >= 2.0}
|
||||||
|
BuildRequires: %{python_module brotlicffi}
|
||||||
BuildRequires: %{python_module decorator}
|
BuildRequires: %{python_module decorator}
|
||||||
BuildRequires: %{python_module flasgger}
|
BuildRequires: %{python_module flasgger}
|
||||||
BuildRequires: %{python_module gevent}
|
BuildRequires: %{python_module gevent}
|
||||||
BuildRequires: %{python_module itsdangerous}
|
BuildRequires: %{python_module pip}
|
||||||
BuildRequires: %{python_module pytest}
|
BuildRequires: %{python_module pytest}
|
||||||
BuildRequires: %{python_module setuptools}
|
BuildRequires: %{python_module setuptools}
|
||||||
|
BuildRequires: %{python_module wheel}
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: python-rpm-macros
|
BuildRequires: python-rpm-macros
|
||||||
Requires: python-Brotli
|
Requires: python-Flask >= 2.2.4
|
||||||
Requires: python-Flask >= 2.1
|
|
||||||
Requires: python-MarkupSafe
|
|
||||||
Requires: python-Werkzeug >= 2.0
|
Requires: python-Werkzeug >= 2.0
|
||||||
|
Requires: python-brotlicffi
|
||||||
Requires: python-decorator
|
Requires: python-decorator
|
||||||
Requires: python-flasgger
|
Requires: python-flasgger
|
||||||
Requires: python-gevent
|
Requires: python-gevent
|
||||||
Requires: python-itsdangerous
|
|
||||||
Requires: python-six
|
Requires: python-six
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
%python_subpackages
|
%python_subpackages
|
||||||
@ -69,16 +60,15 @@ all kinds of HTTP scenarios. Additional endpoints are being considered.
|
|||||||
All endpoint responses are JSON-encoded.
|
All endpoint responses are JSON-encoded.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -p1
|
%autosetup -p1 -n %{modname}-%{version}
|
||||||
chmod -x httpbin/templates/forms-post.html
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
%python_build
|
%pyproject_wheel
|
||||||
|
|
||||||
%install
|
%install
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
%python_install
|
%pyproject_install
|
||||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||||
|
|
||||||
%check
|
%check
|
||||||
@ -88,6 +78,6 @@ export LANG=en_US.UTF-8
|
|||||||
%doc README.md
|
%doc README.md
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
%{python_sitelib}/httpbin
|
%{python_sitelib}/httpbin
|
||||||
%{python_sitelib}/httpbin-%{internalversion}*-info
|
%{python_sitelib}/httpbin-%{version}*-info
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
Index: python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py
|
|
||||||
===================================================================
|
|
||||||
--- python-httpbin-0.7.0+git20181107.f8ec666.orig/test_httpbin.py
|
|
||||||
+++ python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py
|
|
||||||
@@ -167,8 +167,8 @@ class HttpbinTestCase(unittest.TestCase)
|
|
||||||
|
|
||||||
def test_base64(self):
|
|
||||||
greeting = u'Здравствуй, мир!'
|
|
||||||
- b64_encoded = _string_to_base64(greeting)
|
|
||||||
- response = self.app.get(b'/base64/' + b64_encoded)
|
|
||||||
+ b64_encoded = _string_to_base64(greeting).decode('utf-8')
|
|
||||||
+ response = self.app.get('/base64/' + b64_encoded)
|
|
||||||
content = response.data.decode('utf-8')
|
|
||||||
self.assertEqual(greeting, content)
|
|
||||||
|
|
||||||
@@ -422,7 +422,7 @@ class HttpbinTestCase(unittest.TestCase)
|
|
||||||
body, stale_after + 1)
|
|
||||||
self.assertEqual(stale_response.status_code, 401)
|
|
||||||
header = stale_response.headers.get('WWW-Authenticate')
|
|
||||||
- self.assertIn('stale=TRUE', header)
|
|
||||||
+ self.assertIn('stale=True', header)
|
|
||||||
|
|
||||||
def _test_digest_response_for_auth_request(self, header, username, password, qop, uri, body, nc=1, nonce=None):
|
|
||||||
auth_type, auth_info = header.split(None, 1)
|
|
||||||
@@ -474,13 +474,13 @@ class HttpbinTestCase(unittest.TestCase)
|
|
||||||
wrong_pass_response, nonce = self._test_digest_response_for_auth_request(header, username, "wrongPassword", qop, uri, body)
|
|
||||||
self.assertEqual(wrong_pass_response.status_code, 401)
|
|
||||||
header = wrong_pass_response.headers.get('WWW-Authenticate')
|
|
||||||
- self.assertNotIn('stale=TRUE', header)
|
|
||||||
+ self.assertNotIn('stale=True', header)
|
|
||||||
|
|
||||||
reused_nonce_response, nonce = self._test_digest_response_for_auth_request(header, username, password, qop, uri, \
|
|
||||||
body, nonce=nonce)
|
|
||||||
self.assertEqual(reused_nonce_response.status_code, 401)
|
|
||||||
header = reused_nonce_response.headers.get('WWW-Authenticate')
|
|
||||||
- self.assertIn('stale=TRUE', header)
|
|
||||||
+ self.assertIn('stale=True', header)
|
|
||||||
|
|
||||||
def test_drip(self):
|
|
||||||
response = self.app.get('/drip?numbytes=400&duration=2&delay=1')
|
|
@ -1,34 +0,0 @@
|
|||||||
From b6cb2b47a3813da5df8dbffada284b72d7fe099e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Simon Kowallik <github@simonkowallik.com>
|
|
||||||
Date: Sat, 18 May 2019 13:10:08 +0200
|
|
||||||
Subject: [PATCH] fix #554: update tests, Pipfile, Pipfile.lock for
|
|
||||||
werkzeug>=0.15.1
|
|
||||||
|
|
||||||
- update test_httpbin.py to reflect new behaviour of werkzeug
|
|
||||||
- require werkzeug>=0.15.1
|
|
||||||
---
|
|
||||||
Pipfile | 2 +-
|
|
||||||
Pipfile.lock | 6 +++---
|
|
||||||
test_httpbin.py | 2 --
|
|
||||||
3 files changed, 4 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
Index: python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py
|
|
||||||
===================================================================
|
|
||||||
--- python-httpbin-0.7.0+git20181107.f8ec666.orig/test_httpbin.py
|
|
||||||
+++ python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py
|
|
||||||
@@ -148,7 +148,6 @@ class HttpbinTestCase(unittest.TestCase)
|
|
||||||
data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.assertEqual(data['args'], {})
|
|
||||||
self.assertEqual(data['headers']['Host'], 'localhost')
|
|
||||||
- self.assertEqual(data['headers']['Content-Length'], '0')
|
|
||||||
self.assertEqual(data['headers']['User-Agent'], 'test')
|
|
||||||
# self.assertEqual(data['origin'], None)
|
|
||||||
self.assertEqual(data['url'], 'http://localhost/get')
|
|
||||||
@@ -162,7 +161,6 @@ class HttpbinTestCase(unittest.TestCase)
|
|
||||||
data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.assertEqual(data['args'], {})
|
|
||||||
self.assertEqual(data['headers']['Host'], 'localhost')
|
|
||||||
- self.assertEqual(data['headers']['Content-Length'], '0')
|
|
||||||
self.assertEqual(data['url'], 'http://localhost/anything/foo/bar')
|
|
||||||
self.assertEqual(data['method'], 'GET')
|
|
||||||
self.assertTrue(response.data.endswith(b'\n'))
|
|
Loading…
Reference in New Issue
Block a user