git: 6af3796e4353 - main - ftp/py-curl-cffi: New port: libcurl ffi bindings for Python

Yuri Victorovich <[email protected]> Sun, 02 Aug 2026 00:26:15 +0000
Newsgroups gmane.os.freebsd.devel.cvs.ports
Message-ID <[email protected]>
The branch main has been updated by yuri:

URL: https://cgit.FreeBSD.org/ports/commit/?id=6af3796e4353ecbbc1f42a0628e637beb291ac76

commit 6af3796e4353ecbbc1f42a0628e637beb291ac76
Author:     Yuri Victorovich <[email protected]>
AuthorDate: 2026-08-02 00:23:58 +0000
Commit:     Yuri Victorovich <[email protected]>
CommitDate: 2026-08-02 00:25:50 +0000

    ftp/py-curl-cffi: New port: libcurl ffi bindings for Python
---
 ftp/Makefile                                  |  1 +
 ftp/py-curl-cffi/Makefile                     | 34 +++++++++++++++
 ftp/py-curl-cffi/distinfo                     |  3 ++
 ftp/py-curl-cffi/files/patch-libs.json        | 59 +++++++++++++++++++++++++++
 ftp/py-curl-cffi/files/patch-scripts_build.py | 24 +++++++++++
 ftp/py-curl-cffi/pkg-descr                    |  6 +++
 6 files changed, 127 insertions(+)

diff --git a/ftp/Makefile b/ftp/Makefile
index 0bd724eeb5b3..cd719317ff94 100644
--- a/ftp/Makefile
+++ b/ftp/Makefile
@@ -68,6 +68,7 @@
     SUBDIR += profxp
     SUBDIR += pure-ftpd
     SUBDIR += py-aioftp
+    SUBDIR += py-curl-cffi
     SUBDIR += py-ftputil
     SUBDIR += py-parfive
     SUBDIR += py-pycurl
diff --git a/ftp/py-curl-cffi/Makefile b/ftp/py-curl-cffi/Makefile
new file mode 100644
index 000000000000..c4253871498e
--- /dev/null
+++ b/ftp/py-curl-cffi/Makefile
@@ -0,0 +1,34 @@
+PORTNAME=	curl-cffi
+PORTVERSION=	0.14.0
+CATEGORIES=	ftp python
+MASTER_SITES=	PYPI
+PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
+DISTNAME=	${PORTNAME:S/-/_/g}-${DISTVERSIONFULL}
+
+MAINTAINER=	[email protected]
+COMMENT=	libcurl ffi bindings for Python
+WWW=		https://curl-cffi.readthedocs.io/en/latest/ \
+		https://github.com/lexiforest/curl_cffi
+
+LICENSE=	MIT
+LICENSE_FILE=	${WRKSRC}/LICENSE
+
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}cffi>=1.12.0:devel/py-cffi@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}setuptools>=0:devel/py-setuptools@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}wheel>0:devel/py-wheel@${PY_FLAVOR}
+LIB_DEPENDS=	libcurl-impersonate.so:ftp/curl-impersonate
+RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}certifi>=2024.2.2:security/py-certifi@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}cffi>=1.12.0:devel/py-cffi@${PY_FLAVOR}
+TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}pytest>=8.1.1:devel/py-pytest@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest-asyncio>=0.23.6:devel/py-pytest-asyncio@${PY_FLAVOR}
+
+USES=		python ssl
+USE_PYTHON=	pep517 autoplist pytest
+
+TEST_ENV=	PYTHONPATH=
+TEST_WRKDIR=	${WRKSRC}/tests/unittest
+
+post-install:
+	${FIND} ${STAGEDIR}${PYTHON_SITELIBDIR} -name '*.so' -exec ${STRIP_CMD} {} +
+
+.include <bsd.port.mk>
diff --git a/ftp/py-curl-cffi/distinfo b/ftp/py-curl-cffi/distinfo
new file mode 100644
index 000000000000..e07f40d95dd5
--- /dev/null
+++ b/ftp/py-curl-cffi/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1773620906
+SHA256 (curl_cffi-0.14.0.tar.gz) = 5ffbc82e59f05008ec08ea432f0e535418823cda44178ee518906a54f27a5f0f
+SIZE (curl_cffi-0.14.0.tar.gz) = 162633
diff --git a/ftp/py-curl-cffi/files/patch-libs.json b/ftp/py-curl-cffi/files/patch-libs.json
new file mode 100644
index 000000000000..5d7f35dd7790
--- /dev/null
+++ b/ftp/py-curl-cffi/files/patch-libs.json
@@ -0,0 +1,59 @@
+--- libs.json.orig	2025-12-16 02:55:22 UTC
++++ libs.json
+@@ -122,6 +122,56 @@
+         "so_arch": "arm"
+     },
+     {
++        "system": "FreeBSD",
++        "machine": "amd64",
++        "pointer_size": 64,
++        "libdir": "",
++        "sysname": "freebsd",
++        "link_type": "static",
++        "so_name": "libcurl-impersonate-chrome.so",
++        "so_arch": "amd64"
++    },
++    {
++        "system": "FreeBSD",
++        "machine": "i686",
++        "pointer_size": 32,
++        "libdir": "",
++        "sysname": "freebsd",
++        "link_type": "static",
++        "so_name": "libcurl-impersonate-chrome.so",
++        "so_arch": "i386"
++    },
++    {
++        "system": "FreeBSD",
++        "machine": "aarch64",
++        "pointer_size": 64,
++        "libdir": "",
++        "sysname": "freebsd",
++        "link_type": "static",
++        "so_name": "libcurl-impersonate-chrome.so",
++        "so_arch": "aarch64"
++    },
++    {
++        "system": "FreeBSD",
++        "machine": "aarch64",
++        "pointer_size": 64,
++        "libdir": "~/.local/lib",
++        "sysname": "freebsd",
++        "link_type": "dynamic",
++        "so_name": "libcurl-impersonate-chrome.so",
++        "so_arch": "aarch64"
++    },
++    {
++        "system": "FreeBSD",
++        "machine": "armv7l",
++        "pointer_size": 32,
++        "libdir": "",
++        "sysname": "freebsd",
++        "link_type": "static",
++        "so_name": "libcurl-impersonate-chrome.so",
++        "so_arch": "arm"
++    },
++    {
+         "system": "Linux",
+         "machine": "armv7l",
+         "pointer_size": 32,
diff --git a/ftp/py-curl-cffi/files/patch-scripts_build.py b/ftp/py-curl-cffi/files/patch-scripts_build.py
new file mode 100644
index 000000000000..f4ed096ea201
--- /dev/null
+++ b/ftp/py-curl-cffi/files/patch-scripts_build.py
@@ -0,0 +1,24 @@
+--- scripts/build.py.orig	2025-12-16 02:55:22 UTC
++++ scripts/build.py
+@@ -53,6 +53,12 @@ def download_libcurl():
+ 
+ 
+ def download_libcurl():
++    # On FreeBSD, use system-installed curl-impersonate
++    if arch["system"] == "FreeBSD":
++        print("Using system curl-impersonate on FreeBSD")
++        arch["libdir"] = "/usr/local/lib"
++        return
++
+     if (Path(arch["libdir"]) / arch["so_name"]).exists():
+         print(".so files already downloaded.")
+         return
+@@ -132,7 +138,7 @@ def get_curl_libraries():
+         ]
+     elif arch["system"] == "Darwin" or (
+         arch["system"] == "Linux" and arch.get("link_type") == "dynamic"
+-    ):
++    ) or arch["system"] == "FreeBSD":
+         return ["curl-impersonate"]
+     else:
+         return []
diff --git a/ftp/py-curl-cffi/pkg-descr b/ftp/py-curl-cffi/pkg-descr
new file mode 100644
index 000000000000..b8caaac509f2
--- /dev/null
+++ b/ftp/py-curl-cffi/pkg-descr
@@ -0,0 +1,6 @@
+python-cffi is a Python binding for curl-impersonate fork via cffi.
+
+curl_cffi is the most popular Python binding for curl. Unlike other pure python
+http clients like httpx or requests, curl_cffi can impersonate browsers' TLS/JA3
+and HTTP/2 fingerprints. If you are blocked by some website for no obvious
+reason, you can give curl_cffi a try.