diff --git a/.gitignore b/.gitignore index 01029d0..8c44f93 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /httpbin-0.6.2.tar.gz /httpbin-0.7.0.tar.gz /httpbin-0.10.0.tar.gz +/httpbin-0.10.1.tar.gz diff --git a/0001-Make-flasgger-dep-optional-26.patch b/0001-Make-flasgger-dep-optional-26.patch new file mode 100644 index 0000000..240edef --- /dev/null +++ b/0001-Make-flasgger-dep-optional-26.patch @@ -0,0 +1,224 @@ +From 07214fe8822fecf98cbdd8aa80fac9932591c8ab Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 17 Oct 2023 17:17:16 -0700 +Subject: [PATCH] Make flasgger dep optional (#26) + +As discussed in the ticket, the flasgger dep is a pretty heavy +one which is not needed when using httpbin as a library. It's +only really needed to produce the fancy homepage and API docs +for httpbin.org. + +This makes the dependency optional, and falls back to the old +static HTML page for / if flasgger is not available. The flasgger +dependency is moved from the main set of dependencies to the +'mainapp' extras (to ensure we *do* get the shiny new homepage +when we want it). + +Signed-off-by: Adam Williamson +--- + httpbin/core.py | 151 +++++++++++++++++++++++++----------------------- + pyproject.toml | 2 +- + 2 files changed, 81 insertions(+), 72 deletions(-) + +diff --git a/httpbin/core.py b/httpbin/core.py +index 5c1783a..2a97447 100644 +--- a/httpbin/core.py ++++ b/httpbin/core.py +@@ -33,7 +33,11 @@ try: + 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 ++ ++try: ++ from flasgger import Swagger, NO_SANITIZER ++except ImportError: ++ Swagger = False + + from . import filters + from .helpers import ( +@@ -94,77 +98,78 @@ app.add_template_global("HTTPBIN_TRACKING" in os.environ, name="tracking_enabled + + app.config["SWAGGER"] = {"title": "httpbin.org", "uiversion": 3} + +-template = { +- "swagger": "2.0", +- "info": { +- "title": "httpbin.org", +- "description": ( +- "A simple HTTP Request & Response Service." +- "
A Kenneth Reitz project." +- "

Run locally:
" +- "$ docker pull ghcr.io/psf/httpbin
" +- "$ docker run -p 80:8080 ghcr.io/psf/httpbin" +- ), +- "contact": { +- "responsibleOrganization": "Python Software Foundation", +- "responsibleDeveloper": "Kenneth Reitz", +- "url": "https://github.com/psf/httpbin/", +- }, +- # "termsOfService": "http://me.com/terms", +- "version": version, +- }, +- "host": "httpbin.org", # overrides localhost:5000 +- "basePath": "/", # base bash for blueprint registration +- "schemes": ["https"], +- "protocol": "https", +- "tags": [ +- { +- "name": "HTTP Methods", +- "description": "Testing different HTTP verbs", +- # 'externalDocs': {'description': 'Learn more', 'url': 'https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html'} +- }, +- {"name": "Auth", "description": "Auth methods"}, +- { +- "name": "Status codes", +- "description": "Generates responses with given status code", +- }, +- {"name": "Request inspection", "description": "Inspect the request data"}, +- { +- "name": "Response inspection", +- "description": "Inspect the response data like caching and headers", +- }, +- { +- "name": "Response formats", +- "description": "Returns responses in different data formats", ++if Swagger: ++ template = { ++ "swagger": "2.0", ++ "info": { ++ "title": "httpbin.org", ++ "description": ( ++ "A simple HTTP Request & Response Service." ++ "
A Kenneth Reitz project." ++ "

Run locally:
" ++ "$ docker pull ghcr.io/psf/httpbin
" ++ "$ docker run -p 80:8080 ghcr.io/psf/httpbin" ++ ), ++ "contact": { ++ "responsibleOrganization": "Python Software Foundation", ++ "responsibleDeveloper": "Kenneth Reitz", ++ "url": "https://github.com/psf/httpbin/", ++ }, ++ # "termsOfService": "http://me.com/terms", ++ "version": version, + }, +- {"name": "Dynamic data", "description": "Generates random and dynamic data"}, +- {"name": "Cookies", "description": "Creates, reads and deletes Cookies"}, +- {"name": "Images", "description": "Returns different image formats"}, +- {"name": "Redirects", "description": "Returns different redirect responses"}, +- { +- "name": "Anything", +- "description": "Returns anything that is passed to request", +- }, +- ], +-} +- +-swagger_config = { +- "headers": [], +- "specs": [ +- { +- "endpoint": "spec", +- "route": "/spec.json", +- "rule_filter": lambda rule: True, # all in +- "model_filter": lambda tag: True, # all in +- } +- ], +- "static_url_path": "/flasgger_static", +- # "static_folder": "static", # must be set by user +- "swagger_ui": True, +- "specs_route": "/", +-} ++ "host": "httpbin.org", # overrides localhost:5000 ++ "basePath": "/", # base bash for blueprint registration ++ "schemes": ["https"], ++ "protocol": "https", ++ "tags": [ ++ { ++ "name": "HTTP Methods", ++ "description": "Testing different HTTP verbs", ++ # 'externalDocs': {'description': 'Learn more', 'url': 'https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html'} ++ }, ++ {"name": "Auth", "description": "Auth methods"}, ++ { ++ "name": "Status codes", ++ "description": "Generates responses with given status code", ++ }, ++ {"name": "Request inspection", "description": "Inspect the request data"}, ++ { ++ "name": "Response inspection", ++ "description": "Inspect the response data like caching and headers", ++ }, ++ { ++ "name": "Response formats", ++ "description": "Returns responses in different data formats", ++ }, ++ {"name": "Dynamic data", "description": "Generates random and dynamic data"}, ++ {"name": "Cookies", "description": "Creates, reads and deletes Cookies"}, ++ {"name": "Images", "description": "Returns different image formats"}, ++ {"name": "Redirects", "description": "Returns different redirect responses"}, ++ { ++ "name": "Anything", ++ "description": "Returns anything that is passed to request", ++ }, ++ ], ++ } ++ ++ swagger_config = { ++ "headers": [], ++ "specs": [ ++ { ++ "endpoint": "spec", ++ "route": "/spec.json", ++ "rule_filter": lambda rule: True, # all in ++ "model_filter": lambda tag: True, # all in ++ } ++ ], ++ "static_url_path": "/flasgger_static", ++ # "static_folder": "static", # must be set by user ++ "swagger_ui": True, ++ "specs_route": "/", ++ } + +-swagger = Swagger(app, sanitizer=NO_SANITIZER, template=template, config=swagger_config) ++ swagger = Swagger(app, sanitizer=NO_SANITIZER, template=template, config=swagger_config) + + # Set up Bugsnag exception tracking, if desired. To use Bugsnag, install the + # Bugsnag Python client with the command "pip install bugsnag", and set the +@@ -242,8 +247,12 @@ def set_cors_headers(response): + # Routes + # ------ + ++if Swagger: ++ staticroute = "/legacy" ++else: ++ staticroute = "/" + +-@app.route("/legacy") ++@app.route(staticroute) + def view_landing_page(): + """Generates Landing Page in legacy layout.""" + return render_template("index.html") +diff --git a/pyproject.toml b/pyproject.toml +index 73f3f41..5b255bc 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -34,7 +34,6 @@ dependencies = [ + "Flask", + "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"', +@@ -45,6 +44,7 @@ dependencies = [ + [project.optional-dependencies] + test = ["pytest", "tox"] + mainapp = [ ++ "flasgger", + "gunicorn", + "gevent", + ] +-- +2.41.0 + diff --git a/python-httpbin.spec b/python-httpbin.spec index d692802..96f13a1 100644 --- a/python-httpbin.spec +++ b/python-httpbin.spec @@ -11,13 +11,19 @@ This exists to cover all kinds of HTTP scenarios. Additional endpoints are \ being considered. All endpoint responses are JSON-encoded. Name: python-%{modname} -Version: 0.10.0 +Version: 0.10.1 Release: %autorelease Summary: HTTP Request & Response Service, written in Python + Flask License: MIT URL: https://github.com/psf/httpbin -Source0: %{url}/archive/v%{version}/%{modname}-%{version}.tar.gz +Source: https://files.pythonhosted.org/packages/source/h/%{modname}/%{modname}-%{version}.tar.gz +# https://github.com/psf/httpbin/issues/26 +# https://github.com/psf/httpbin/pull/32 +# Make the dependency on flasgger optional - it has a heavy dep chain +# of its own and is hard to package, and is not needed for using +# httpbin as a library +Patch: 0001-Make-flasgger-dep-optional-26.patch BuildArch: noarch %description @@ -32,7 +38,7 @@ BuildRequires: python3dist(pytest) %{desc}. %prep -%autosetup -n %{modname}-%{version} +%autosetup -n %{modname}-%{version} -p1 # Use the Google 'brotli' module, not 'brotlipy' # When I asked why this uses brotlipy, upstream (Cory Benfield) said: @@ -42,7 +48,7 @@ BuildRequires: python3dist(pytest) # deploy there. Hence: brotlipy, which uses CFFI." # For me that's not enough of a reason to bother packaging it. sed -i -e 's/brotlicffi/brotli/' httpbin/filters.py -sed -i -e 's/brotlicffi/brotli/' setup.py +sed -i -e 's/brotlicffi/brotli/' pyproject.toml %generate_buildrequires %pyproject_buildrequires @@ -63,8 +69,6 @@ chmod ugo-x httpbin/templates/forms-post.html %files -n python3-%{modname} -f %{pyproject_files} %doc README.md AUTHORS -%license LICENSE -%exclude %{python3_sitelib}/tests %changelog %autochangelog diff --git a/sources b/sources index 8c92f2a..9782292 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (httpbin-0.10.0.tar.gz) = 99ff53dae27eb7e50a747cbfcef8381d974f62f79a319fdcda3446fb23bec4e4fea04f7b8e2bac26cfd3b49b229db9659b17166814cdfbbe8b1f2481155b8117 +SHA512 (httpbin-0.10.1.tar.gz) = e3b851253c347893a80e866e7d0188c572f2a87a540125de3d9cbe0b8c3f1ddfab2c60ee3ffde3fd7274fc662294c978c39b1b52acfd92c52fd552966da203be