{"id":977,"library":"curl-cffi","title":"curl-cffi","description":"curl-cffi is a Python binding for the curl-impersonate fork via CFFI. It enables Python applications to impersonate browsers' TLS/JA3 and HTTP/2 fingerprints, effectively bypassing many anti-bot systems. The library provides a high-level API that mimics the popular `requests` library, making it intuitive to use. It supports asynchronous operations, HTTP/2, HTTP/3, and WebSockets. The current stable version is 0.14.0, with active development and frequent updates.","status":"active","version":"0.14.0","language":"python","source_language":"en","source_url":"https://github.com/lexiforest/curl_cffi","tags":["web scraping","http client","impersonation","tls fingerprinting","http/2","http/3","asyncio","cffi"],"install":[{"cmd":"pip install curl-cffi","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for C Foreign Function Interface.","package":"cffi","optional":false},{"reason":"Provides a curated list of trusted CA certificates for SSL/TLS verification.","package":"certifi","optional":false},{"reason":"Underlying C library; pre-compiled wheels are provided, but manual compilation might be needed on unsupported platforms.","package":"libcurl","optional":false}],"imports":[{"note":"The `requests` module from `curl_cffi` provides the impersonation capabilities, not the standard `requests` library.","wrong":"import requests; requests.get(..., impersonate='chrome')","symbol":"requests","correct":"from curl_cffi import requests"},{"symbol":"Session","correct":"from curl_cffi.requests import Session"},{"symbol":"AsyncSession","correct":"from curl_cffi import AsyncSession"},{"symbol":"WebSocket","correct":"from curl_cffi import WebSocket"}],"quickstart":{"code":"from curl_cffi import requests\n\ndef main():\n    try:\n        # Make a GET request impersonating Chrome\n        response = requests.get('https://www.example.com', impersonate='chrome110')\n        response.raise_for_status()  # Raise an exception for HTTP errors (4xx or 5xx)\n        print(f\"Status Code: {response.status_code}\")\n        print(\"Response Header:\\n\", response.headers)\n        print(\"First 500 chars of Response Body:\\n\", response.text[:500])\n\n        # Using a session for persistent connections and cookies\n        with requests.Session() as s:\n            s.impersonate = 'safari15_5'\n            res_session = s.get('https://httpbin.org/cookies/set/sessioncookie/123')\n            print(f\"\\nSession Status Code: {res_session.status_code}\")\n            print(f\"Session Cookies: {s.cookies.get('sessioncookie')}\")\n\n    except requests.exceptions.RequestError as e:\n        print(f\"An error occurred: {e}\")\n\nif __name__ == '__main__':\n    main()","lang":"python","description":"This quickstart demonstrates how to make a basic GET request impersonating a specific browser (Chrome 110) and how to use a `Session` object for persistent connections with another impersonation profile (Safari 15.5) and cookie management. It includes basic error handling."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or newer.","message":"As of version 0.14.0, curl-cffi officially supports Python 3.10 and above. Older Python versions (e.g., 3.9) are no longer officially supported.","severity":"breaking","affected_versions":">=0.14.0"},{"fix":"Adjust cookie handling to use `curl_cffi.requests.Cookies` methods, which often mimic `requests.cookies.RequestsCookieJar`.","message":"In version 0.3.0, the `Response.cookies` attribute's type changed from `http.cookies.SimpleCookie` to `curl_cffi.requests.Cookies`. This might affect code expecting the standard library's cookie object for manipulation.","severity":"breaking","affected_versions":">=0.3.0"},{"fix":"Change proxy configuration from `{\"https\": \"https://localhost:3128\"}` to `{\"https\": \"http://localhost:3128\"}`.","message":"When configuring HTTPS proxies, specifying the proxy URL with an `https://` scheme might lead to `OPENSSL_internal:WRONG_VERSION_NUMBER` errors. The `http://` scheme is often required for the proxy's URL.","severity":"gotcha","affected_versions":"All"},{"fix":"Try removing the `Content-Length` header from your request or force HTTP/1.1 by setting `http_version=CurlHttpVersion.v1_1` in your request or session (e.g., `requests.get(url, http_version=CurlHttpVersion.v1_1)`).","message":"The error `ErrCode: 92, Reason: 'HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)'` often occurs with HTTP/2 requests, sometimes due to proxies or server-side issues. Removing `Content-Length` headers or forcing HTTP/1.1 can be workarounds.","severity":"gotcha","affected_versions":"All"},{"fix":"Iterate over `response.iter_content()` immediately or use the native `content_callback` function for processing streamed content to prevent excessive memory usage.","message":"When handling streamed responses (e.g., `stream=True`), content is buffered in memory by default. If not consumed immediately, this can lead to Out Of Memory (OOM) errors for large responses. Using `iter_content()` or `content_callback` is recommended.","severity":"gotcha","affected_versions":"All"},{"fix":"Adjust exception handling to catch specific `curl_cffi.requests.exceptions` types, such as `RequestsError` for general `curl-cffi` errors, or more specific ones like `SSLError` or `ConnectionError`.","message":"The exception hierarchy in `curl_cffi.requests.exceptions` differs from `requests`. Broad base exceptions like `requests.exceptions.RequestException` (or similar broad types like `RequestError` if used) might not exist or have different names in `curl-cffi`, leading to `AttributeError` when attempting to catch them.","severity":"breaking","affected_versions":"All"}],"env_vars":null,"search_vec":"'0.14.0':69 'activ':71 'anti':34 'anti-bot':33 'api':44 'applic':22 'asynchron':58 'asyncio':85 'bind':10 'bot':35 'browser':25 'bypass':31 'cffi':3,6,18,86 'client':79 'curl':2,5,14 'curl-cffi':1,4 'curl-imperson':13 'current':65 'develop':72 'effect':30 'enabl':20 'fingerprint':29,82 'fork':16 'frequent':74 'high':42 'high-level':41 'http':78 'http/2':28,60,83 'http/3':61,84 'imperson':15,24,80 'intuit':53 'level':43 'librari':38,50 'make':51 'mani':32 'mimic':46 'oper':59 'popular':48 'provid':39 'python':9,21 'request':49 'scrape':77 'stabl':66 'support':57 'system':36 'tls':81 'tls/ja3':26 'updat':75 'use':55 'version':67 'via':17 'web':76 'websocket':63","created_at":"2026-03-29T08:37:14.172013+00:00","updated_at":"2026-04-16T04:30:54.877822+00:00","problems":[{"fix":"Instruct PyInstaller to explicitly include the necessary modules and data files. Example: `pyinstaller -F your_script.py --hidden-import=_cffi_backend --collect-all curl_cffi`","cause":"When packaging a `curl-cffi` application with PyInstaller, the `_cffi_backend` module and associated data files are often not automatically included in the final executable.","error":"ModuleNotFoundError: No module named '_cffi_backend'"},{"fix":"Install the latest Microsoft Visual C++ Redistributable for Visual Studio (usually 2015-2022) from the Microsoft website. Ensure `curl-cffi` is installed correctly, allowing it to use pre-compiled binaries or correctly link to `curl-impersonate`.","cause":"This Windows-specific error typically occurs because the required Microsoft Visual C++ Redistributable libraries, essential for CFFI-based packages like `curl-cffi`, are missing or incompatible on the system. It can also indicate issues with the underlying `curl-impersonate` dependency.","error":"ImportError: DLL load failed: The specified module could not be found."},{"fix":"Try removing the `Content-Length` header from your request. Evaluate and switch to more reliable proxies if applicable. As a workaround, you can force the request to use HTTP/1.1 by adding `http_version=CurlHttpVersion.v1_1` to your `requests.get` or `Session.get` call.","cause":"This HTTP/2 protocol error often arises from issues such as incorrect `Content-Length` headers, problems with the proxies being used, or a server's faulty HTTP/2 implementation.","error":"curl_cffi.CurlError: Failed to perform, ErrCode: 92, Reason: 'HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)'"},{"fix":"Ensure your Python version meets the library's requirements (e.g., Python 3.10+ for `curl-cffi` v0.14.0). Install system-level development packages for curl (e.g., `sudo apt-get install libcurl4-openssl-dev` on Debian/Ubuntu, `sudo yum install libcurl-devel` on RHEL/CentOS). On platforms without pre-built wheels or complex build environments (like some ARM systems), you may need to manually compile `curl-impersonate` first, then set `LD_LIBRARY_PATH` or equivalent before installing `curl-cffi`.","cause":"This build error during `pip install` usually happens when pre-compiled binary wheels are not available for your specific operating system and Python version, and the system lacks the necessary development tools (like `curl-dev` or `libcurl4-openssl-dev` headers) to compile `curl-cffi` and its `curl-impersonate` dependency from source. An unsupported Python version can also contribute to this (e.g., Python < 3.10 for recent `curl-cffi` versions).","error":"ERROR: Failed building wheel for curl_cffi"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.16.2","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/lexiforest/curl_cffi","docs":null,"changelog":null,"pypi":"https://pypi.org/project/curl-cffi/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","web-framework"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}