Hello,

I just finished making my first working package definition (acutally, a
set of definitions...) for Guix. It's for mitmproxy, a popular
TLS-enabled proxy for observing and modifying HTTP(s) traffic, written
in Python.

I wanted to share this with others. The package module file is attached
- I'm making it available to everyone under Creative Commons Zero as
indicated by the SPDX identifier in the file.

I suspect I could instead make the changes in Guix' repo, make a commit,
generate a patch from git and send it to [email protected], but
- as you'll see, the package forced update of inputs of several existing
  packages and my current solution seems too imperfect to be included
  (even though it works),
- it's my first attempt at Guix packaging and there'll likely be some
  other issues that need resolving
- preparing and submitting a patch is simply more time-consuming than
  sending a .scm file 😅
- maybe I'm just unconsciously seeking integration with people?

Nevertheless, what do you think would be the best way to address the
conflict of propagated inputs (in this case caused by
python-cryptography and python-cryptography-next being required at the
same time)?

Best,
Wojtek

-- (sig_start)
website: https://koszko.org/koszko.html
PGP: https://koszko.org/key.gpg
fingerprint: E972 7060 E3C5 637C 8A4F  4B42 4BC5 221C 5A79 FD1A

Meet Kraków saints!           #13: blessed Jan Beyzym
Poznaj świętych krakowskich!  #13: błogosławiony Jan Beyzym
https://pl.wikipedia.org/wiki/Jan_Beyzym
-- (sig_end)
;; SPDX-License-Identifier: CC0-1.0

;; Copyright (C) 2022 Wojtek Kosior <[email protected]>

(define-module (mitmproxy))

(use-modules
 (guix packages)
 (guix download)
 (guix git-download)
 (guix build-system python)
 ((guix licenses) #:prefix license:)
 (gnu packages python-build)
 (gnu packages python-xyz)
 (gnu packages python-crypto)
 (gnu packages compression)
 (gnu packages python-compression)
 (gnu packages xdisorg)
 (gnu packages serialization)
 (gnu packages protobuf)
 (gnu packages python-web)
 (gnu packages check)
 (gnu packages sphinx))

(define-public python-kaitaistruct
  (package
    (name "python-kaitaistruct")
    (version "0.10")
    (source
     (origin
       (method url-fetch)
       (uri (pypi-uri "kaitaistruct" version))
       (sha256
        (base32 "0ap5ka51gnc2mc4s1kqqsi6nb6zqv8wsrg17ryxazmkkj7idwi50"))))
    (build-system python-build-system)
    (home-page "https://kaitai.io";)
    (native-inputs (list python-wheel))
    (synopsis
     "Declarative parser generator for binary data: runtime library for Python")
    (description
     "Kaitai Struct is a declarative language used for describing various binary
data structures, laid out in files or in memory - i.e. binary file formats,
network stream packet formats, etc.")
    (license license:expat)))

(define-public python-parver
  (package
    (name "python-parver")
    (version "0.3.1")
    (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "parver" version))
        (sha256
          (base32 "1lyzqp8bz0n2kzabzl7k7g7cn90rlnrxjzva2p62gsfc7djy00n9"))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'relax-requirements
           (lambda _
             (substitute* "setup.py"
                          (("arpeggio[^']*") "arpeggio"))))
         (replace 'check
           (lambda* (#:key tests? #:allow-other-keys)
             (when tests?
               (invoke "pytest")))))))
    (propagated-inputs (list python-arpeggio python-attrs python-six))
    (native-inputs
      (list python-hypothesis
            python-pretend
            python-pytest))
    (home-page "https://github.com/RazerM/parver";)
    (synopsis "Parse and manipulate version numbers.")
    (description "Parver facilitates parsing and manipulation of
@url{https://www.python.org/dev/peps/pep-0440/,PEP 440} version numbers.")
    (license license:expat)))

(define-public python-pyopenssl-for-mitmproxy
  (let ((base python-pyopenssl))
    (package
      (inherit base)
      (version "22.0.0")
      (source
       (origin
         (inherit (package-source base))
         (uri (pypi-uri "pyOpenSSL" version))
         (sha256
          (base32
           "1gzihw09sqi71lwx97c69hab7w4rbnl6hhfrl6za3i5a4la1n2v6"))))
      (propagated-inputs
       (modify-inputs (package-propagated-inputs base)
         (replace "python-cryptography" python-cryptography-next))))))

(define-public python-urllib3-for-mitmproxy
  (let ((base python-urllib3))
    (package
      (inherit base)
      (propagated-inputs
       (modify-inputs (package-propagated-inputs base)
         (replace "python-cryptography" python-cryptography-next)
         (replace "python-pyopenssl" python-pyopenssl-for-mitmproxy))))))

(define-public python-requests-for-mitmproxy
  (let ((base python-requests))
    (package
      (inherit base)
      (propagated-inputs
       (modify-inputs (package-propagated-inputs base)
         (replace "python-urllib3" python-urllib3-for-mitmproxy))))))

(define-public python-werkzeug-for-mitmproxy
  (let ((base python-werkzeug))
    (package
      (inherit base)
      (propagated-inputs
       (modify-inputs (package-propagated-inputs base)
         (replace "python-requests" python-requests-for-mitmproxy))))))

(define-public python-flask-for-mitmproxy
  (let ((base python-flask))
    (package
      (inherit base)
      (propagated-inputs
       (modify-inputs (package-propagated-inputs base)
         (replace "python-werkzeug" python-werkzeug-for-mitmproxy))))))

(define-public mitmproxy
  (package
    (name "mitmproxy")
    (version "8.1.1")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://github.com/mitmproxy/mitmproxy";)
             (commit (string-append "v" version))))
       (sha256
        (base32 "0kpzk8ci02vyjg9nqnpnadmgyaxxrpdydgfnm2xmxf1s4rzdcvwx"))
       (snippet
        '(begin
           ;; The player contains some minified JS. It would be possible to find
           ;; player sources elsewhere on the internet but there's no point in
           ;; doing do since we're not building the docs anyway.
           (delete-file "docs/src/assets/asciinema-player.js")
           #t))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'relax-requirements
           (lambda _
             (substitute* "setup.py"
               (("kaitaistruct>=0\\.7[^\"]*") "kaitaistruct")
               ;; The ">=2.8" req was there because older ldap3 lacked a crucial
               ;; ">=0.4.8" req for its dep, pyasn. It's not an issue for Guix
               ;; which ships with pyasn 4.8 anyway.
               (("ldap3>=2\\.8[^\"]*") "ldap3")
               (("protobuf>=3\\.14,<5") "protobuf")
               (("sortedcontainers>=2\\.3[^\"]*") "sortedcontainers")
               (("wsproto>=1\\.0[^\"]*") "wsproto")
               (("pytest-timeout[^\"]*<2[^\"]*") "pytest-timeout")
               (("pytest-asyncio[^\"]*<0.14[^\"]*") "pytest-asyncio"))
             (substitute* "test/mitmproxy/proxy/layers/http/test_http.py"
               (("isinstance\\(x, HTTPFlow\\)")
                "issubclass(type(x), HTTPFlow)"))))
         (replace 'check
           (lambda* (#:key tests? inputs outputs #:allow-other-keys)
             (when tests?
               (setenv "HOME" "/tmp")
               (invoke "pytest" "--timeout" "60")))))))
    (propagated-inputs
     (list python-asgiref
           python-blinker
           python-brotli
           python-cryptography-next
           python-flask-for-mitmproxy
           python-h11
           python-h2
           python-hyperframe
           python-kaitaistruct
           python-ldap3
           python-msgpack
           python-passlib
           python-protobuf
           python-pyopenssl-for-mitmproxy
           python-pyparsing
           python-pyperclip
           python-ruamel.yaml
           python-sortedcontainers
           python-tornado-6
           python-urwid
           python-wsproto
           python-publicsuffix2
           python-zstandard))
    (native-inputs
     (list python-parver
           python-pytest
           python-pytest-asyncio
           python-pytest-timeout))
    (home-page "https://mitmproxy.org/";)
    (synopsis "A free interactive HTTPS proxy")
    (description
     "An interactive TLS-capable intercepting HTTP proxy for penetration testers
and software developers.  It can be used to intercept, inspect, modify and
replay web traffic such as HTTP/1, HTTP/2, WebSockets, or any other
SSL/TLS-protected protocols.")
    (license license:expat)))

Attachment: pgpuFIwP9mXlK.pgp
Description: OpenPGP digital signature

Reply via email to