gnu: emacs-sly: Update to 20200228.
[jackhill/guix/guix.git] / gnu / packages / python-web.scm
index b7d03ac..d294e43 100644 (file)
@@ -5,16 +5,16 @@
 ;;; Copyright © 2016, 2017 Danny Milosavljevic <dannym+a@scratchpost.org>
 ;;; Copyright © 2013, 2014, 2015, 2016 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2016, 2017 Marius Bakke <mbakke@fastmail.com>
-;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2017 Roel Janssen <roel@gnu.org>
-;;; Copyright © 2016, 2017 Julien Lepiller <julien@lepiller.eu>
+;;; Copyright © 2016, 2017, 2020 Julien Lepiller <julien@lepiller.eu>
 ;;; Copyright © 2016, 2017 ng0 <ng0@n0.is>
 ;;; Copyright © 2014, 2017 Eric Bavier <bavier@member.fsf.org>
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 Cyril Roelandt <tipecaml@gmail.com>
 ;;; Copyright © 2015, 2016, 2017, 2019 Leo Famulari <leo@famulari.name>
-;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
-;;; Copyright © 2016, 2017, 2018, 2019 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2016, 2019 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2016, 2017, 2018, 2019, 2020 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2015, 2017 Ben Woodcroft <donttrustben@gmail.com>
 ;;; Copyright © 2015, 2016 Christopher Allan Webber <cwebber@dustycloud.org>
 ;;; Copyright © 2017 Adriano Peluso <catonano@gmail.com>
 ;;; Copyright © 2015, 2016 David Thompson <davet@gnu.org>
 ;;; Copyright © 2017 Mark Meyer <mark@ofosos.org>
 ;;; Copyright © 2018 Tomáš Čech <sleep_walker@gnu.org>
-;;; Copyright © 2018 Nicolas Goaziou <mail@nicolasgoaziou.fr>
+;;; Copyright © 2018, 2019 Nicolas Goaziou <mail@nicolasgoaziou.fr>
 ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com>
 ;;; Copyright © 2018 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;; Copyright © 2019 Vagrant Cascadian <vagrant@debian.org>
+;;; Copyright © 2019 Brendan Tildesley <mail@brendan.scot>
+;;; Copyright © 2019 Pierre Langlois <pierre.langlois@gmx.com>
+;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
+;;; Copyright © 2020 Evan Straw <evan.straw99@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
   #:use-module (guix build-system python)
   #:use-module (guix utils)
   #:use-module (gnu packages)
+  #:use-module (gnu packages base)
   #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages curl)
   #:use-module (gnu packages databases)
   #:use-module (gnu packages django)
+  #:use-module (gnu packages groff)
   #:use-module (gnu packages libffi)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages python-check)
   #:use-module (gnu packages python-crypto)
   #:use-module (gnu packages python-xyz)
+  #:use-module (gnu packages serialization)
+  #:use-module (gnu packages sphinx)
+  #:use-module (gnu packages texinfo)
   #:use-module (gnu packages tls)
   #:use-module (gnu packages time)
   #:use-module (gnu packages web)
 (define-public python-aiohttp
   (package
     (name "python-aiohttp")
-    (version "3.4.4")
+    (version "3.6.2")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "aiohttp" version))
        (sha256
         (base32
-         "1ykm6kdjkrg556j0zd7dx2l1rsrbh0d9g27ivr6dmaahz9pyrbsi"))))
+         "09pkw6f1790prnrq0k8cqgnf1qy57ll8lpmc6kld09q7zw4vi6i5"))))
     (build-system python-build-system)
     (arguments
      `(#:tests? #f))                    ;missing pytest-timeout
@@ -150,22 +161,22 @@ using @url{https://github.com/saghul/pycares,pycares}.")
 (define-public python-aiorpcx
   (package
     (name "python-aiorpcx")
-    (version "0.10.2")
+    (version "0.18.3")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "aiorpcX" version))
        (sha256
         (base32
-         "1p88k15jh0d2a18pnnbfcamsqi2bxvmmhpizmdlxfdxf8vy5ggyj"))))
+         "0k545hc7wl6sh1svydzbv6x7sx5pig2pqkl3yxs9riwmvzawx9xp"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-attrs" ,python-attrs)))
     (home-page "https://github.com/kyuupichan/aiorpcX")
     (synopsis "Generic asyncio RPC implementation")
     (description
-     "aiorpcX is a generic asyncio library implementation of RPC suitable for
-an application that is a client, server or both.
+     "The aiorpcX library is a generic asyncio implementation of RPC suitable
+for an application that is a client, server or both.
 
 The package includes a module with full coverage of JSON RPC versions 1.0 and
 2.0, JSON RPC protocol auto-detection, and arbitrary message framing.  It also
@@ -299,6 +310,64 @@ other HTTP libraries.")
 (define-public python2-httplib2
   (package-with-python2 python-httplib2))
 
+(define-public httpie
+  (package
+    (name "httpie")
+    (version "2.0.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "httpie" version))
+       (sha256
+        (base32
+         "02bw20cwv3a1lzrn919dk25dq4v81x6q786zlrqsqzhsdxszj14c"))))
+    (build-system python-build-system)
+    (arguments
+     ;; The tests attempt to access external web servers, so we cannot run them.
+     '(#:tests? #f))
+    (propagated-inputs
+     `(("python-colorama" ,python-colorama)
+       ("python-pygments" ,python-pygments)
+       ("python-requests" ,python-requests)))
+    (home-page "https://httpie.org/")
+    (synopsis "cURL-like tool for humans")
+    (description
+     "A command line HTTP client with an intuitive UI, JSON support,
+syntax highlighting, wget-like downloads, plugins, and more.  It consists of
+a single http command designed for painless debugging and interaction with
+HTTP servers, RESTful APIs, and web services.")
+    (license license:bsd-3)))
+
+(define-public python-html2text
+  (package
+    (name "python-html2text")
+    (version "2019.8.11")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "html2text" version))
+       (sha256
+        (base32
+         "0ppgjplg06kmv9sj0x8p7acczcq2mcfgk1jdjwm4w5w40b0vj5pm"))))
+    (build-system python-build-system)
+    (arguments
+     '(#:phases
+       (modify-phases %standard-phases
+         (replace 'check
+           (lambda _
+             (invoke "pytest" "test/"))))))
+    (native-inputs
+     `(("python-pytest" ,python-pytest)))
+    (home-page "https://github.com/Alir3z4/html2text")
+    (synopsis "Convert HTML into plain text")
+    (description "html2text takes HTML and converts it into plain ASCII text
+which is also valid markdown.  html2text was originally written by Aaron
+Swartz.")
+    (license license:gpl3+)))
+
+(define-public python2-html2text
+  (package-with-python2 python-html2text))
+
 (define-public python-mechanicalsoup
   (package
     (name "python-mechanicalsoup")
@@ -637,6 +706,28 @@ options.")
 (define-public python2-cssutils
   (package-with-python2 python-cssutils))
 
+(define-public python-css-parser
+  (package
+    (inherit python-cssutils)
+    (name "python-css-parser")
+    (version "1.0.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "css-parser" version ".tar.gz"))
+       (sha256
+        (base32
+         "0i4xfykiffxzr4f6y0m2ggqvx1rzam6pw6krlr5k6ldf29akbay7"))))
+    (home-page "https://github.com/ebook-utils/css-parser")
+    (synopsis "Fork of cssutils modified for parsing ebooks")
+    (description
+     "Css-parser is a fork of cssutils 1.0.2, updated and modified for parsing
+ebooks, due to cssutils not receiving updates as of 1.0.2.")
+    (license license:lgpl3+)))
+
+(define-public python2-css-parser
+  (package-with-python2 python-css-parser))
+
 (define-public python-cssselect
   (package
     (name "python-cssselect")
@@ -761,21 +852,18 @@ connection to each user.")
 (define-public python-tornado-http-auth
   (package
     (name "python-tornado-http-auth")
-    (version "1.1.0")
+    (version "1.1.1")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "tornado-http-auth" version))
        (sha256
-        (base32
-         "0znrgqd7k2s4ia474xizi6h3061zj4sn5n6cq76bkwl3wwshifn5"))))
+        (base32 "0hyc5f0a09i5yb99pk4bxpg6w9ichbrb5cv7hc9hff7rxd8w0v0x"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-tornado" ,python-tornado)))
-    (home-page
-     "https://github.com/gvalkov/tornado-http-auth")
-    (synopsis
-     "Digest and basic authentication module for Tornado")
+    (home-page "https://github.com/gvalkov/tornado-http-auth")
+    (synopsis "Digest and basic authentication module for Tornado")
     (description
      "Provides support for adding authentication to services using the Tornado
 web framework, either via the basic or digest authentication schemes.")
@@ -816,6 +904,7 @@ term.js Javascript terminal emulator library.")
       (propagated-inputs
        `(("python2-backport-ssl-match-hostname"
           ,python2-backport-ssl-match-hostname)
+         ("python2-futures" ,python2-futures)
           ,@(package-propagated-inputs terminado))))))
 
 (define-public python-wsgi-intercept
@@ -874,16 +963,16 @@ object to help create WSGI responses.")
 (define-public python-zope-event
   (package
     (name "python-zope-event")
-    (version "4.1.0")
+    (version "4.4")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "zope.event" version))
        (sha256
         (base32
-         "11p75zpfz3ffhz21nzx9wb23xs993ck5s6hkjcvhswwizni5jynw"))))
+         "1ksbc726av9xacml6jhcfyn828hlhb9xlddpx6fcvnlvmpmpvhk9"))))
     (build-system python-build-system)
-    (home-page "https://pypi.python.org/pypi/zope.event")
+    (home-page "https://pypi.org/project/zope.event/")
     (synopsis "Event publishing system for Python")
     (description "Zope.event provides an event publishing API, intended for
 use by applications which are unaware of any subscribers to their events.  It
@@ -932,10 +1021,10 @@ conforming to a given API or contract.")
          "0zwxaaa66sqxg5k7zcrvs0fbg9ym1njnxnr28dfmchzhwjvwnfzl"))))
     (build-system python-build-system)
     (arguments
-     '(#:tests? #f)) ; circular dependency with zope.testrunner
+     '(#:tests? #f))                ; circular dependency with zope.testrunner
     (propagated-inputs
      `(("python-zope-interface" ,python-zope-interface)))
-    (home-page "http://cheeseshop.python.org/pypi/zope.exceptions")
+    (home-page "https://pypi.org/project/zope.exceptions/")
     (synopsis "Zope exceptions")
     (description "Zope.exceptions provides general-purpose exception types
 that have uses outside of the Zope framework.")
@@ -962,7 +1051,7 @@ that have uses outside of the Zope framework.")
            (for-each delete-file (find-files "." "(\\.pyc|~)$"))
            #t))))
     (build-system python-build-system)
-    (home-page "https://pypi.python.org/pypi/zope.testing")
+    (home-page "https://pypi.org/project/zope.testing/")
     (synopsis "Zope testing helpers")
     (description "Zope.testing provides a number of testing utilities for HTML
 forms, HTTP servers, regular expressions, and more.")
@@ -993,7 +1082,7 @@ forms, HTTP servers, regular expressions, and more.")
        ("unzip" ,unzip)))
     (propagated-inputs
      `(("python-zope-interface" ,python-zope-interface)))
-    (home-page "https://pypi.python.org/pypi/zope.testrunner")
+    (home-page "https://pypi.org/project/zope.testrunner/")
     (synopsis "Zope testrunner script")
     (description "Zope.testrunner provides a script for running Python
 tests.")
@@ -1020,7 +1109,7 @@ tests.")
         (base32
          "1rslyph0klk58dmjjy4j0jxy21k03azksixc3x2xhqbkv97cmzml"))))
     (build-system python-build-system)
-    (home-page "https://pypi.python.org/pypi/zope.i18nmessageid")
+    (home-page "https://pypi.org/project/zope.i18nmessageid/")
     (synopsis "Message identifiers for internationalization")
     (description "Zope.i18nmessageid provides facilities for declaring
 internationalized messages within program source text.")
@@ -1051,7 +1140,7 @@ internationalized messages within program source text.")
      `(("python-zope-testing" ,python-zope-testing)
        ("python-coverage" ,python-coverage)
        ("python-nose" ,python-nose)))
-    (home-page "https://pypi.python.org/pypi/zope.schema")
+    (home-page "https://pypi.org/project/zope.schema/")
     (synopsis "Zope data schemas")
     (description "Zope.scheme provides extensions to zope.interface for
 defining data schemas.")
@@ -1076,7 +1165,7 @@ defining data schemas.")
     (propagated-inputs
      `(("python-zope-i18nmessageid" ,python-zope-i18nmessageid)
        ("python-zope-schema" ,python-zope-schema)))
-    (home-page "https://pypi.python.org/pypi/zope.configuration")
+    (home-page "https://pypi.org/project/zope.configuration/")
     (synopsis "Zope Configuration Markup Language")
     (description "Zope.configuration implements ZCML, the Zope Configuration
 Markup Language.")
@@ -1101,7 +1190,7 @@ Markup Language.")
      '(#:tests? #f)) ; FIXME: Tests can't find zope.interface.
     (propagated-inputs
      `(("python-zope-interface" ,python-zope-interface)))
-    (home-page "https://pypi.python.org/pypi/zope.proxy")
+    (home-page "https://pypi.org/project/zope.proxy/")
     (synopsis "Generic, transparent proxies")
     (description "Zope.proxy provides generic, transparent proxies for Python.
 Proxies are special objects which serve as mostly-transparent wrappers around
@@ -1130,7 +1219,7 @@ brokering, etc.) for which the proxy is responsible.")
     (propagated-inputs
      `(("python-zope-proxy" ,python-zope-proxy)
        ("python-zope-schema" ,python-zope-schema)))
-    (home-page "https://pypi.python.org/pypi/zope.location/")
+    (home-page "https://pypi.org/project/zope.location/")
     (synopsis "Zope location library")
     (description "Zope.location implements the concept of \"locations\" in
 Zope3, which are are special objects that have a structural location.")
@@ -1164,7 +1253,7 @@ Zope3, which are are special objects that have a structural location.")
        ("python-zope-location" ,python-zope-location)
        ("python-zope-testrunner" ,python-zope-testrunner)
        ("python-zope-testing" ,python-zope-testing)))
-    (home-page "https://pypi.python.org/pypi/zope.security")
+    (home-page "https://pypi.org/project/zope.security/")
     (synopsis "Zope security framework")
     (description "Zope.security provides a generic mechanism to implement
 security policies on Python objects.")
@@ -1280,15 +1369,19 @@ WebSocket usage in Python programs.")
 (define-public python-requests
   (package
     (name "python-requests")
-    (version "2.13.0")
+    (version "2.22.0")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "requests" version))
              (sha256
               (base32
-               "1s0wg4any4dsv5l3hqjxqk2zgb7pdbqhy9rhc8kh3aigfq4ws8jp"))))
-    ;; TODO: unbundle urllib3 and chardet.
+               "1d5ybh11jr5sm7xp6mz8fyc7vrp4syifds91m7sj60xalal0gq0i"))))
     (build-system python-build-system)
+    (propagated-inputs
+     `(("python-certifi" ,python-certifi)
+       ("python-chardet" ,python-chardet)
+       ("python-idna" ,python-idna)
+       ("python-urllib3" ,python-urllib3)))
     (arguments
      ;; FIXME: Some tests require network access.
      '(#:tests? #f))
@@ -1299,6 +1392,22 @@ WebSocket usage in Python programs.")
 than Python’s urllib2 library.")
     (license license:asl2.0)))
 
+;; Some software requires an older version of Requests, notably Docker/Docker
+;; Compose.
+(define-public python-requests-2.20
+  (package (inherit python-requests)
+           (version "2.20.1")
+           (source (origin
+                     (method url-fetch)
+                     (uri (pypi-uri "requests" version))
+                     (sha256
+                      (base32
+                       "0qzj6cgv3k9wyj7wlxgz7xq0cfg4jbbkfm24pp8dnhczwl31527a"))))
+           (propagated-inputs
+            `(("python-urllib3" ,python-urllib3-1.24)
+              ("python-idna" ,python-idna-2.7)
+              ,@(package-propagated-inputs python-requests)))))
+
 ;; Some software requires an older version of Requests, notably Docker
 ;; Compose.
 (define-public python-requests-2.7
@@ -1383,34 +1492,36 @@ with python-requests.")
 (define-public python-oauthlib
   (package
     (name "python-oauthlib")
-    (version "1.0.3")
+    (version "3.0.1")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "oauthlib" version))
               (sha256
                (base32
-                "1bfrj70vdjxjw74khbyh6f0dksv7p5rh2346jnlrffyacd3gwjzg"))))
+                "163jg4a8f7c5ki655grrr47kgljy12wri3qly7ijf64sk1fjrqqc"))))
     (build-system python-build-system)
+    (arguments
+     `(#:phases (modify-phases %standard-phases
+                  (replace 'check
+                    (lambda _
+                      (invoke "pytest" "-vv"))))))
     (native-inputs
-     `(("python-nose" ,python-nose)
-       ("python-mock" ,python-mock)
-       ("python-cryptography" ,python-cryptography)
+     `(("python-pytest" ,python-pytest)
+       ("python-pytest-cov" ,python-pytest-cov)
+       ("python-mock" ,python-mock)))
+    (propagated-inputs
+     `(("python-cryptography" ,python-cryptography)
        ("python-pyjwt" ,python-pyjwt)
        ("python-blinker" ,python-blinker)))
-    (home-page "https://github.com/idan/oauthlib")
+    (home-page "https://github.com/oauthlib/oauthlib")
     (synopsis "OAuth implementation for Python")
     (description
      "Oauthlib is a generic, spec-compliant, thorough implementation of the
 OAuth request-signing logic.")
-    (license license:bsd-3)
-    (properties `((python2-variant . ,(delay python2-oauthlib))))))
+    (license license:bsd-3)))
 
 (define-public python2-oauthlib
-  (let ((base (package-with-python2 (strip-python2-variant python-oauthlib))))
-    (package
-      (inherit base)
-      (native-inputs `(("python2-unittest2" ,python2-unittest2)
-                       ,@(package-native-inputs base))))))
+  (package-with-python2 python-oauthlib))
 
 (define-public python-rauth
   (package
@@ -1447,21 +1558,16 @@ authenticated session objects providing things like keep-alive.")
 (define-public python-urllib3
   (package
     (name "python-urllib3")
-    (version "1.24.1")
+    (version "1.25.3")
     (source
       (origin
         (method url-fetch)
         (uri (pypi-uri "urllib3" version))
         (sha256
          (base32
-          "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy"))))
+          "0cij8qcvvpj62g1q8n785qjkdymfh4b7vf45si4sw64l41rr3rfv"))))
     (build-system python-build-system)
     (arguments `(#:tests? #f))
-    (native-inputs
-     `(;; some packages for tests
-       ("python-mock" ,python-mock)
-       ("python-pytest" ,python-pytest)
-       ("python-tornado" ,python-tornado)))
     (propagated-inputs
      `(;; These 5 inputs are used to build urrlib3[secure]
        ("python-certifi" ,python-certifi)
@@ -1478,48 +1584,71 @@ can reuse the same socket connection for multiple requests, it can POST files,
 supports url redirection and retries, and also gzip and deflate decoding.")
     (license license:expat)))
 
+;; Some software requires an older version of urllib3, notably Docker.
+(define-public python-urllib3-1.24
+  (package (inherit python-urllib3)
+           (version "1.24.3")
+           (source (origin
+                     (method url-fetch)
+                     (uri (pypi-uri "urllib3" version))
+                     (sha256
+                      (base32
+                       "1x0slqrv6kixkbcdnxbglvjliwhc1payavxjvk8fvbqjrnasd4r3"))))))
+
+
 (define-public python2-urllib3
   (package-with-python2 python-urllib3))
 
 (define-public awscli
   (package
-   (name "awscli")
-   (version "1.14.41")
-   (source
-    (origin
-     (method url-fetch)
-     (uri (pypi-uri name version))
-     (sha256
-      (base32
-       "0sispclx263lybbk19zp1n9yhg8xxx4jddypzgi24vpjaqnsbwlc"))))
-   (build-system python-build-system)
-   (propagated-inputs
-    `(("python-colorama" ,python-colorama)
-      ("python-botocore" ,python-botocore)
-      ("python-s3transfer" ,python-s3transfer)
-      ("python-docutils" ,python-docutils)
-      ("python-pyyaml" ,python-pyyaml)
-      ("python-rsa" ,python-rsa)))
-   (arguments
-    ;; FIXME: The 'pypi' release does not contain tests.
-    '(#:tests? #f))
-   (home-page "https://aws.amazon.com/cli/")
-   (synopsis "Command line client for AWS")
-   (description "AWS CLI provides a unified command line interface to the
+    (name "awscli")
+    (version "1.18.6")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri name version))
+       (sha256
+        (base32
+         "0p479mfs9r0m82a217pap8156ijwvhv6r3kqa4k267gd05wgvygm"))))
+    (build-system python-build-system)
+    (arguments
+     ;; FIXME: The 'pypi' release does not contain tests.
+     '(#:tests? #f
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'fix-reference-to-groff
+           (lambda _
+             (substitute* "awscli/help.py"
+               (("if not self._exists_on_path\\('groff'\\):") "")
+               (("raise ExecutableNotFoundError\\('groff'\\)") "")
+               (("cmdline = \\['groff'")
+                (string-append "cmdline = ['" (which "groff") "'")))
+             #t)))))
+    (propagated-inputs
+     `(("python-colorama" ,python-colorama)
+       ("python-botocore" ,python-botocore)
+       ("python-s3transfer" ,python-s3transfer)
+       ("python-docutils" ,python-docutils)
+       ("python-pyyaml" ,python-pyyaml)
+       ("python-rsa" ,python-rsa)))
+    (native-inputs
+     `(("groff" ,groff)))
+    (home-page "https://aws.amazon.com/cli/")
+    (synopsis "Command line client for AWS")
+    (description "AWS CLI provides a unified command line interface to the
 Amazon Web Services (AWS) API.")
-   (license license:asl2.0)))
+    (license license:asl2.0)))
 
 (define-public python-wsgiproxy2
   (package
     (name "python-wsgiproxy2")
-    (version "0.4.5")
+    (version "0.4.6")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "WSGIProxy2" version ".tar.gz"))
        (sha256
-        (base32
-         "19d9dva282vfjs784i0zkxp078lxfz4h3f621z30ij9wbf5rba6a"))))
+        (base32 "16jch5nic0hia28lps3c678s9s9mjdq8n87igxncjg0rpi5adqnf"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-webtest" ,python-webtest)))
@@ -1553,7 +1682,7 @@ and to spawn subprocesses to handle requests.")
     (build-system python-build-system)
     (native-inputs
      `(("python-nose" ,python-nose)))
-    (home-page "http://pythonpaste.org/deploy/")
+    (home-page "https://pylonsproject.org/")
     (synopsis
      "Load, configure, and compose WSGI applications and servers")
     (description
@@ -1586,7 +1715,7 @@ file.")
        ("python-webob" ,python-webob)
        ("python-six" ,python-six)
        ("python-beautifulsoup4" ,python-beautifulsoup4)))
-    (home-page "http://webtest.pythonpaste.org/")
+    (home-page "https://docs.pylonsproject.org/projects/webtest/")
     (synopsis "Helper to test WSGI applications")
     (description "Webtest allows you to test your Python web applications
 without starting an HTTP server.  It supports anything that supports the
@@ -1599,13 +1728,13 @@ minimum of WSGI.")
 (define-public python-flask
   (package
     (name "python-flask")
-    (version "1.0.2")
+    (version "1.0.3")
     (source (origin
               (method url-fetch)
-              (uri (pypi-uri "flask" version))
+              (uri (pypi-uri "Flask" version))
               (sha256
                (base32
-                "0j6f4a9rpfh25k1gp7azqhnni4mb4fgy50jammgjgddw1l3w0w92"))))
+                "1wxnhjlxwwjhjxmghykjhllpahv5pkdc5hln4ab6nab43s26sz5d"))))
     (build-system python-build-system)
     (arguments
      '(#:phases
@@ -1718,13 +1847,13 @@ Python.")
 (define-public python-responses
   (package
     (name "python-responses")
-    (version "0.5.1")
+    (version "0.10.6")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "responses" version))
               (sha256
                (base32
-                "1spcfxixyk9k7pk82jm6zqkwk031s95lh8q0mz7539jrb7269bcc"))))
+                "147pacwkkqy3qf3hr33fnl1xbzgw0zsm3qppvvy9qhq8h069qbah"))))
     (build-system python-build-system)
     (arguments
      `(;; Test suite is not distributed:
@@ -1820,14 +1949,14 @@ concurrent HTTP client library for python using @code{gevent}.")
 (define-public python-requests-oauthlib
   (package
     (name "python-requests-oauthlib")
-    (version "0.6.2")
+    (version "1.2.0")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "requests-oauthlib" version))
        (sha256
         (base32
-         "0ykff67sjcl227c23g0rxzfx34rr5bf21kwv0z3zmgk0lfmch7hn"))))
+         "0mrglgcvq7k48pf27s4gifdk0za8xmgpf55jy15yjj471qrk6rdx"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
@@ -1838,7 +1967,8 @@ concurrent HTTP client library for python using @code{gevent}.")
              (delete-file "tests/test_core.py")
              #t)))))
     (native-inputs
-     `(("python-requests-mock" ,python-requests-mock)
+     `(("python-pyjwt" ,python-pyjwt)
+       ("python-requests-mock" ,python-requests-mock)
        ("python-mock" ,python-mock)))
     (propagated-inputs
      `(("python-oauthlib" ,python-oauthlib)
@@ -1888,36 +2018,23 @@ provide an easy-to-use Python interface for building OAuth1 and OAuth2 clients."
 (define-public python-cachecontrol
   (package
     (name "python-cachecontrol")
-    (version "0.11.6")
+    (version "0.12.5")
     (source
      (origin
-       (method url-fetch)
+       (method git-fetch)
        ;; Pypi does not have tests.
-       (uri (string-append
-             "https://github.com/ionrock/cachecontrol/archive/v"
-             version ".tar.gz"))
-       (file-name (string-append name "-" version ".tar.gz"))
+       (uri (git-reference
+             (url "https://github.com/ionrock/cachecontrol")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
        (sha256
         (base32
-         "0yj60d0f69a2l8p7y86k4zhzzm6rnxpq74sfl240pry9l0lfw2vw"))))
+         "03lgc65sl04n0cgzmmgg99bk83f9i6k8yrmcd4hpl46q1pymn0kz"))))
     (build-system python-build-system)
     (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (replace 'check
-           (lambda _
-             ;; Drop test that requires internet access.
-             (delete-file "tests/test_regressions.py")
-             (setenv "PYTHONPATH"
-                     (string-append (getcwd) "/build/lib:"
-                                    (getenv "PYTHONPATH")))
-             (invoke "py.test" "-vv")
-             #t)))))
-    (native-inputs
-     `(("python-pytest" ,python-pytest)
-       ("python-redis" ,python-redis)
-       ("python-webtest" ,python-webtest)
-       ("python-mock" ,python-mock)))
+     ;; Versions > 0.11.6 depend on CherryPy for testing.
+     ;; It's too much work to package CherryPy for now.
+     `(#:tests? #f))
     (propagated-inputs
      `(("python-requests" ,python-requests)
        ("python-lockfile" ,python-lockfile)))
@@ -1983,21 +2100,21 @@ Betamax.")
 (define-public python-s3transfer
   (package
     (name "python-s3transfer")
-    (version "0.1.13")
+    (version "0.2.0")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "s3transfer" version))
               (sha256
                (base32
-                "1harvyn1s8v54n1w5h7c0lg4bgjh68aylhg28s8n174q53h1ip4h"))))
+                "08fhj73b1ai52hrs2q3nggshq3pswn1gq8ch3m009cb2v2vmqggj"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
        (modify-phases %standard-phases
          (replace 'check
            (lambda _
-             ;; 7 of the 'integration' tests require network access or login
-             ;; credentials.
+             ;; Some of the 'integration' tests require network access or
+             ;; login credentials.
              (invoke "nosetests" "--exclude=integration")
              #t)))))
     (native-inputs
@@ -2005,7 +2122,8 @@ Betamax.")
        ("python-mock" ,python-mock)
        ("python-nose" ,python-nose)))
     (propagated-inputs
-     `(("python-botocore" ,python-botocore)))
+     `(("python-botocore" ,python-botocore)
+       ("python-urllib3" ,python-urllib3)))
     (synopsis "Amazon S3 Transfer Manager")
     (description "S3transfer is a Python library for managing Amazon S3
 transfers.")
@@ -2099,27 +2217,48 @@ pretty printer and a tree visitor.")
       "This package provides HTTP basic access authentication for Flask.")
     (license license:bsd-3)))
 
-(define-public python-flask-sqlalchemy
+(define-public python-flask-htpasswd
   (package
-    (name "python-flask-sqlalchemy")
-    (version "2.1")
+    (name "python-flask-htpasswd")
+    (version "0.3.1")
     (source
       (origin
         (method url-fetch)
-        (uri (pypi-uri "Flask-SQLAlchemy" version))
+        (uri (pypi-uri "flask-htpasswd" version))
         (sha256
           (base32
-            "1i9ps5d5snih9xlqhrvmi3qfiygkmqzxh92n25kj4pf89kj4s965"))))
+            "14q1y1y9i9bhabdnwd25jqzc4ljli23smxfyyh8abxz1vq93pxra"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-flask" ,python-flask)
+       ("python-itsdangerous" ,python-itsdangerous)
+       ("python-passlib" ,python-passlib)
+       ("python-tox" ,python-tox)))
+    (home-page "http://github.com/carsongee/flask-htpasswd")
+    (synopsis "Basic authentication via htpasswd files in Flask applications")
+    (description "This package provides Basic authentication via
+@file{htpasswd} files and access_token authentication in Flask
+applications.")
+    (license license:bsd-3)))
+
+(define-public python-flask-sqlalchemy
+  (package
+    (name "python-flask-sqlalchemy")
+    (version "2.4.0")
+    (source (origin
+              (method url-fetch)
+              (uri (pypi-uri "Flask-SQLAlchemy" version))
+              (sha256
+               (base32
+                "0nnllf0ddbh9jlhngnyjj98lbxgxr1csaplllx0caw98syq0k5hc"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-flask" ,python-flask)
        ("python-sqlalchemy" ,python-sqlalchemy)))
-    (home-page
-      "https://github.com/mitsuhiko/flask-sqlalchemy")
-    (synopsis
-      "Module adding SQLAlchemy support to your Flask application")
+    (home-page "https://github.com/mitsuhiko/flask-sqlalchemy")
+    (synopsis "Module adding SQLAlchemy support to your Flask application")
     (description
-      "This package adds SQLAlchemy support to your Flask application.")
+     "This package adds SQLAlchemy support to your Flask application.")
     (license license:bsd-3)))
 
 (define-public python-flask-restplus
@@ -2396,14 +2535,14 @@ CSS tidy.  Also supports URL rewriting in CSS files.")
 (define-public python-elasticsearch
   (package
     (name "python-elasticsearch")
-    (version "6.1.1")
+    (version "7.1.0")
     (source
       (origin
         (method url-fetch)
         (uri (pypi-uri "elasticsearch" version))
         (sha256
          (base32
-          "1kjxl45yvvgfb5fmamx0kfsfg9pzphiqrwbkns3s28r1w7ya74cd"))))
+          "0rnjvlhw4v3vg14l519qliy1s1zpmx3827q0xfviwvk42rr7hh01"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-mock" ,python-mock)
@@ -2437,6 +2576,14 @@ this it tries to be opinion-free and very extendable.")
         (base32
           "0r8w2v89nj6b9p91p495cga5m72a673l2wc0hp0zqk05j4yrc9b4"))))
   (build-system python-build-system)
+  (arguments
+   `(#:phases
+     (modify-phases %standard-phases
+       (add-after 'unpack 'patch-tests
+         (lambda _
+           (substitute* "tests.py"
+            (("flask\\.ext\\.script") "flask_script"))
+           #t)))))
   (propagated-inputs
    `(("python-flask" ,python-flask)
      ("python-argcomplete" ,python-argcomplete)
@@ -2487,7 +2634,7 @@ for Flask programs that are using @code{python-alembic}.")
 (define-public python-genshi
   (package
     (name "python-genshi")
-    (version "0.7.1")
+    (version "0.7.2")
     (source
      (origin
        (method git-fetch)
@@ -2496,7 +2643,7 @@ for Flask programs that are using @code{python-alembic}.")
              (commit version)))
        (file-name (git-file-name name version))
        (sha256
-        (base32 "01fx8fnpay5w048ppyjivg2dgfpp5rybn07y3pfsgj2knram3nhl"))))
+        (base32 "06rch30x10l105k5b6rahd839lkhmgrzn6691wbci0cb2fzps32w"))))
     (build-system python-build-system)
     (home-page "https://genshi.edgewall.org/")
     (synopsis "Toolkit for generation of output for the web")
@@ -2525,7 +2672,7 @@ textual content for output generation on the web.")
     (native-inputs
      `(("python-flask" ,python-flask)
        ("python-nose" ,python-nose)))
-    (home-page "http://packages.python.org/Flask-Principal/")
+    (home-page "https://pythonhosted.org/Flask-Principal/")
     (synopsis "Identity management for Flask")
     (description "@code{flask_principal} is a identity management library for
 Flask.  It supports managing both authentication and authorization data in a
@@ -2604,17 +2751,26 @@ List.")
 (define-public python-publicsuffix2
   (package
     (name "python-publicsuffix2")
-    (version "2.20160818")
+    (version "2.20191221")
     (source
      (origin
        (method url-fetch)
-       (uri (pypi-uri "publicsuffix2" version ".tar.bz2"))
+       (uri (pypi-uri "publicsuffix2" version))
        (sha256
-        (base32
-         "1bb55yka9vkn7i6y1kjzxa516kh6v4gsrxa90w5wdz5p5n968r68"))))
+        (base32 "0yzysvfj1najr1mb4pcqrbmjir3xpb69rlffln95a3cdm8qwry00"))))
     (build-system python-build-system)
     (arguments
-     '(#:tests? #f)) ; The test suite requires network access.
+     '(#:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'ignore-maintainer-inputs
+           (lambda _
+             ;; Comment out a demand for python-requests, which is used only by
+             ;; the unused ‘update_psl’ helper command.
+             (substitute* "setup.py"
+               (("'requests " match)
+                (format "# ~a" match)))
+             #t)))
+       #:tests? #f))                  ; the test suite requires network access
     (home-page "https://github.com/pombredanne/python-publicsuffix2")
     (synopsis "Get a public suffix for a domain name using the Public Suffix List")
     (description "Get a public suffix for a domain name using the Public Suffix
@@ -2741,7 +2897,7 @@ available in Django, but is a standalone package.")
        ("python-nose" ,python-nose)))
     (propagated-inputs
      `(("python-six" ,python-six)))
-    (home-page "http://pythonpaste.org")
+    (home-page "https://pythonpaste.readthedocs.io/")
     (synopsis
      "Python web development tools, focusing on WSGI")
     (description
@@ -2770,7 +2926,8 @@ follows ideas flowing from WSGI (Web Standard Gateway Interface).")
     (propagated-inputs
      `(("python-paste" ,python-paste)
        ("python-pastedeploy" ,python-pastedeploy)))
-    (home-page "http://pythonpaste.org/script/")
+    (home-page (string-append "https://web.archive.org/web/20161025192515/"
+                              "http://pythonpaste.org/script/"))
     (arguments
      '(;; Unfortunately, this requires the latest unittest2,
        ;; but that requires traceback2 which requires linecache2 which requires
@@ -3094,3 +3251,326 @@ Python.")
     (propagated-inputs
      `(("python-gevent" ,python2-gevent)
        ("python-tornado" ,python2-tornado)))))
+
+(define-public python-slugify
+  (package
+    (name "python-slugify")
+    (version "3.0.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "python-slugify" version))
+       (sha256
+        (base32 "0dv97yi5fq074q5qyqbin09pmi8ixg36caf5nkpw2bqkd8jh6pap"))
+       (patches
+        (search-patches "python-slugify-depend-on-unidecode.patch"))))
+    (native-inputs
+     `(("python-wheel" ,python-wheel)))
+    (propagated-inputs
+     `(("python-unidecode" ,python-unidecode)))
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (replace 'check
+           (lambda _
+             (invoke "python" "test.py"))))))
+    (build-system python-build-system)
+    (home-page "https://github.com/un33k/python-slugify")
+    (synopsis "Python Slugify application that handles Unicode")
+    (description "This package provides a @command{slufigy} command and
+library to create slugs from unicode strings while keeping it DRY.")
+    (license license:expat)))
+
+(define-public python-branca
+  (package
+    (name "python-branca")
+    (version "0.3.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "branca" version))
+       (sha256
+        (base32
+         "0pmigd521j2228xf8x34vbx0niwvms7xl7za0lymywj0vydjqxiy"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-jinja2" ,python-jinja2)
+       ("python-six" ,python-six)))
+    (native-inputs
+     `(("python-pytest" ,python-pytest)))
+    (home-page "https://github.com/python-visualization/branca")
+    (synopsis "Generate complex HTML+JS pages with Python")
+    (description "Generate complex HTML+JS pages with Python")
+    (license license:expat)))
+
+(define-public python-tinycss2
+  (package
+    (name "python-tinycss2")
+    (version "1.0.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "tinycss2" version))
+       (sha256
+        (base32 "1kw84y09lggji4krkc58jyhsfj31w8npwhznr7lf19d0zbix09v4"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (replace 'check
+           (lambda _ (invoke "pytest"))))))
+    (propagated-inputs
+     `(("python-webencodings" ,python-webencodings)))
+    (native-inputs
+     `(("python-pytest-flake8" ,python-pytest-flake8)
+       ("python-pytest-isort" ,python-pytest-isort)
+       ("python-pytest-runner" ,python-pytest-runner)))
+    (home-page "https://tinycss2.readthedocs.io/")
+    (synopsis "Low-level CSS parser for Python")
+    (description "@code{tinycss2} can parse strings, return Python objects
+representing tokens and blocks, and generate CSS strings corresponding to
+these objects.
+
+Based on the CSS Syntax Level 3 specification, @code{tinycss2} knows the
+grammar of CSS but doesn’t know specific rules, properties or values supported
+in various CSS modules.")
+    (license license:bsd-3)))
+
+(define-public python-cssselect2
+  (package
+    (name "python-cssselect2")
+    (version "0.2.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "cssselect2" version))
+       (sha256
+        (base32 "0skymzb4ncrm2zdsy80f53vi0arf776lvbp51hzh4ayp1il5lj3h"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (replace 'check
+           (lambda _ (invoke "pytest"))))))
+    (propagated-inputs
+     `(("python-tinycss2" ,python-tinycss2)))
+    (native-inputs
+     `(("python-pytest-cov" ,python-pytest-cov)
+       ("python-pytest-flake8" ,python-pytest-flake8)
+       ("python-pytest-isort" ,python-pytest-isort)
+       ("python-pytest-runner" ,python-pytest-runner)))
+    (home-page "https://cssselect2.readthedocs.io/")
+    (synopsis "CSS selectors for Python ElementTree")
+    (description "@code{cssselect2} is a straightforward implementation of
+CSS3 Selectors for markup documents (HTML, XML, etc.) that can be read by
+ElementTree-like parsers (including cElementTree, lxml, html5lib, etc.).
+
+Unlike the Python package @code{cssselect}, it does not translate selectors to
+XPath and therefore does not have all the correctness corner cases that are
+hard or impossible to fix in cssselect.")
+    (license license:bsd-3)))
+
+(define-public gunicorn
+  (package
+    (name "gunicorn")
+    (version "20.0.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "gunicorn" version))
+       (sha256
+        (base32
+         "0l1zm8a0vz8ws3lkn8q9a0f93ipdzyvlf2zlwdj5xyadh6jdwsgg"))))
+    (outputs '("out" "doc"))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-after 'build 'build-doc
+           (lambda _
+             (invoke "make" "-C" "docs" "PAPER=a4" "html" "info")
+             (delete-file "docs/build/texinfo/Makefile")
+             (delete-file "docs/build/texinfo/Gunicorn.texi")
+             #t))
+         (replace 'check
+           (lambda _
+             (setenv "PYTHONPATH"
+                     (string-append ".:" (getenv "PYTHONPATH")))
+             ;; Remove test modules failing due to libc not found due to
+             ;; section '.dynamic' not found in libc.so
+             (delete-file "tests/test_arbiter.py")
+             (delete-file "tests/test_config.py")
+             (delete-file "tests/test_sock.py")
+             (invoke "pytest")))
+         (add-after 'install 'install-doc
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((doc (string-append (assoc-ref outputs "doc")
+                                        "/share/doc/" ,name "-" ,version))
+                    (html (string-append doc "/html"))
+                    (info (string-append doc "/info"))
+                    (examples (string-append doc "/examples")))
+               (mkdir-p html)
+               (mkdir-p info)
+               (mkdir-p examples)
+               (copy-recursively "docs/build/html" html)
+               (copy-recursively "docs/build/texinfo" info)
+               (copy-recursively "examples" examples)
+               (for-each (lambda (file)
+                           (copy-file file (string-append doc "/" file)))
+                         '("README.rst" "NOTICE" "LICENSE" "THANKS")))
+             #t)))))
+    (native-inputs
+     `(("binutils" ,binutils)  ;; for ctypes.util.find_library()
+       ("python-aiohttp", python-aiohttp)
+       ("python-pytest" ,python-pytest)
+       ("python-pytest-cov" ,python-pytest-cov)
+       ("python-sphinx" ,python-sphinx)
+       ("texinfo" ,texinfo)))
+    (home-page "https://gunicorn.org/")
+    (synopsis "Python WSGI HTTP Server for UNIX")
+    (description "Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP
+Server for UNIX.  It’s a pre-fork worker model ported from Ruby’s
+Unicorn project.  The Gunicorn server is broadly compatible with
+various web frameworks, simply implemented, light on server resources,
+and fairly speedy.")
+  (license license:expat)))
+
+(define-public python-translation-finder
+  (package
+    (name "python-translation-finder")
+    (version "1.7")
+    (source
+      (origin
+        (method url-fetch)
+        (uri (pypi-uri "translation-finder" version))
+        (sha256
+         (base32
+          "1pcy9z8gmb8x41gjhw9x0lkr0d2mv5mdxcs2hwg6q8mxs857j589"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-before 'build 'remove-failing-test
+           (lambda _
+             (delete-file "translation_finder/test_api.py")
+             #t)))))
+    (propagated-inputs
+     `(("python-chardet" ,python-chardet)
+       ("python-pathlib2" ,python-pathlib2)
+       ("python-ruamel.yaml" ,python-ruamel.yaml)
+       ("python-six" ,python-six)))
+    (native-inputs
+     `(("python-codecov" ,python-codecov)
+       ("python-codacy-coverage" ,python-codacy-coverage)
+       ("python-pytest-cov" ,python-pytest-cov)
+       ("python-pytest-runner" ,python-pytest-runner)
+       ("python-twine" ,python-twine)))
+    (home-page "https://weblate.org/")
+    (synopsis "Translation file finder for Weblate")
+    (description "This package provides a function to find translation file in
+the source code of a project.  It supports many translation file formats and
+is part of the Weblate translation platform.")
+    (license license:gpl3+)))
+
+(define-public python-gitlab
+  (package
+    (name "python-gitlab")
+    (version "1.15.0")
+    (source
+      (origin
+        (method url-fetch)
+        (uri (pypi-uri "python-gitlab" version))
+        (sha256
+         (base32
+          "0zl6kz8v8cg1bcy2r78b2snb0lpw0b573gdx2x1ps0nhsh75l4j5"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-requests" ,python-requests)
+       ("python-six" ,python-six)))
+    (native-inputs
+     `(("python-httmock" ,python-httmock)
+       ("python-mock" ,python-mock)))
+    (home-page
+      "https://github.com/python-gitlab/python-gitlab")
+    (synopsis "Interact with GitLab API")
+    (description "This package provides an extended library for interacting
+with GitLab instances through their API.")
+    (license license:lgpl3+)))
+
+(define-public python-path-and-address
+  (package
+    (name "python-path-and-address")
+    (version "2.0.1")
+    (source
+     (origin
+       ;; The source distributed on PyPI doesn't include tests.
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/joeyespo/path-and-address")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0b0afpsaim06mv3lhbpm8fmawcraggc11jhzr6h72kdj1cqjk5h6"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (replace 'check
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (add-installed-pythonpath inputs outputs)
+             (invoke "py.test"))))))
+    (native-inputs
+     `(("python-pytest" ,python-pytest)))
+    (home-page "https://github.com/joeyespo/path-and-address")
+    (synopsis "Functions for command-line server tools used by humans")
+    (description "Path-and-address resolves ambiguities of command-line
+interfaces, inferring which argument is the path, and which is the address.")
+    (license license:expat)))
+
+(define-public grip
+  ;; No release by upstream for quite some time, some bugs fixed since. See:
+  ;; https://github.com/joeyespo/grip/issues/304
+  (let ((commit "27a4d6d87ea1d0ea7f7f120de55baabee3de73e3"))
+    (package
+      (name "grip")
+      (version (git-version "4.5.2" "1" commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/joeyespo/grip")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "0kx5hgb3q19i4l18a4vqdq9af390xgpk88lp2ay75qi96k0dc68w"))))
+      (build-system python-build-system)
+      (propagated-inputs
+       `(("python-docopt" ,python-docopt)
+         ("python-flask" ,python-flask)
+         ("python-markdown" ,python-markdown)
+         ("python-path-and-address" ,python-path-and-address)
+         ("python-pygments" ,python-pygments)
+         ("python-requests" ,python-requests)))
+      (native-inputs
+       `(("python-pytest" ,python-pytest)
+         ("python-responses" ,python-responses)))
+      (arguments
+       `(#:phases
+         (modify-phases %standard-phases
+           (replace 'check
+             (lambda* (#:key inputs outputs #:allow-other-keys)
+               (add-installed-pythonpath inputs outputs)
+               (setenv "PATH" (string-append
+                                (getenv "PATH") ":"
+                                (assoc-ref %outputs "out") "/bin"))
+               (invoke "py.test" "-m" "not assumption"))))))
+      (home-page "https://github.com/joeyespo/grip")
+      (synopsis "Preview Markdown files using the GitHub API")
+      (description "Grip is a command-line server application written in Python
+that uses the GitHub Markdown API to render a local Markdown file.  The styles
+and rendering come directly from GitHub, so you'll know exactly how it will
+appear.  Changes you make to the file will be instantly reflected in the browser
+without requiring a page refresh.")
+      (license license:expat))))