API References

curl low levl APIs

Curl

class curl_cffi.Curl(cacert: str = '', debug: bool = False, handle=None)[source]

Wrapper for curl_easy_* functions of libcurl.

__init__(cacert: str = '', debug: bool = False, handle=None) None[source]
Parameters:
  • cacert – CA cert path to use, by default, certs from certifi are used.

  • debug – whether to show curl debug messages.

  • handle – a curl handle instance from curl_easy_init.

debug() None[source]

Set debug to True

setopt(option: CurlOpt, value: Any) int[source]

Wrapper for curl_easy_setopt.

Parameters:
  • option – option to set, using constants from CurlOpt enum

  • value – value to set, strings will be handled automatically

Returns:

0 if no error, see CurlECode.

getinfo(option: CurlInfo) bytes | int | float | list[str | int][source]

Wrapper for curl_easy_getinfo. Gets information in response after curl.perform.

Parameters:

option – option to get info of, using constants from CurlInfo enum

Returns:

value retrieved from last perform.

version() bytes[source]

Get the underlying libcurl version.

impersonate(target: str, default_headers: bool = True) int[source]

Set the browser type to impersonate.

Parameters:
  • target – browser to impersonate.

  • default_headers – whether to add default headers, like User-Agent.

Returns:

0 if no error.

perform(clear_headers: bool = True, clear_resolve: bool = True) None[source]

Wrapper for curl_easy_perform, performs a curl request.

Parameters:
  • clear_headers – clear header slist used in this perform

  • clear_resolve – clear resolve slist used in this perform

Raises:

CurlError – if the perform was not successful.

duphandle() Curl[source]

Wrapper for curl_easy_duphandle.

This is not a full copy of entire curl object in python. For example, headers handle is not copied, you have to set them again.

reset() None[source]

Reset all curl options, wrapper for curl_easy_reset.

Extract cookies.SimpleCookie from header lines.

Parameters:

headers – list of headers in bytes.

Returns:

A parsed cookies.SimpleCookie instance.

static get_reason_phrase(status_line: bytes) bytes[source]

Extract reason phrase, like OK, Not Found from response status line.

static parse_status_line(status_line: bytes) tuple[CurlHttpVersion, int, bytes][source]

Parse status line.

Returns:

http_version, status_code, and reason phrase

close() None[source]

Close and cleanup curl handle, wrapper for curl_easy_cleanup.

ws_recv() tuple[bytes, CurlWsFrame][source]

Receive a frame from a websocket connection.

Returns:

a tuple of frame content and curl frame meta struct.

Raises:

CurlError – if failed.

ws_send(payload: bytes | memoryview, flags: CurlWsFlag | int = CurlWsFlag.BINARY) int[source]

Send data to a websocket connection.

Parameters:
  • payload – content to send.

  • flags – websocket flag to set for the frame, default: binary.

Returns:

The number of bytes sent.

Raises:

CurlError – if failed.

ws_close(code: int = 1000, message: bytes = b'') int[source]

Close a websocket connection. Shorthand for ws_send() with close code and message. Note that to completely close the connection, you must close the curl handle after this call with close().

Parameters:
  • code – close code.

  • message – close message.

Returns:

0 if no error.

Raises:

CurlError – if failed.

AsyncCurl

class curl_cffi.AsyncCurl(cacert: str = '', loop=None)[source]

Wrapper around curl_multi handle to provide asyncio support. It uses the libcurl socket_action APIs.

__init__(cacert: str = '', loop=None)[source]
Parameters:
  • cacert – CA cert path to use, by default, certs from certifi are used.

  • loop – EventLoop to use.

add_handle(curl: Curl)[source]

Add a curl handle to be managed by curl_multi. This is the equivalent of perform in the async world.

remove_handle(curl: Curl)[source]

Cancel a future for given curl handle.

set_result(curl: Curl)[source]

Mark a future as done for given curl handle.

set_exception(curl: Curl, exception)[source]

Raise exception of a future for given curl handle.

setopt(option, value)[source]

Wrapper around curl_multi_setopt.

socket_action(sockfd: int, ev_bitmask: int) int[source]

wrapper for curl_multi_socket_action, returns the number of running curl handles.

process_data(sockfd: int, ev_bitmask: int)[source]

Call curl_multi_info_read to read data for given socket.

async close()[source]

Close and cleanup running timers, readers, writers and handles.

CurlMime

class curl_cffi.CurlMime(curl: Curl | None = None)[source]

Wrapper for the curl_mime_ API.

__init__(curl: Curl | None = None)[source]
Parameters:

curl – Curl instance to use.

addpart(name: str, *, content_type: str | None = None, filename: str | None = None, local_path: str | bytes | Path | None = None, data: bytes | None = None) None[source]

Add a mime part for a mutlipart html form.

Note: You can only use either local_path or data, not both.

Parameters:
  • name – name of the field.

  • content_type – content_type for the field. for example: image/png.

  • filename – filename for the server.

  • local_path – file to upload on local disk.

  • data – file content to upload.

classmethod from_list(files: list[dict])[source]

Create a multipart instance from a list of dict, for keys, see addpart

attach(curl: Curl | None = None) None[source]

Attach the mime instance to a curl instance.

close() None[source]

Close the mime instance and underlying files. This method must be called after perform or request.

Constants

Enum values used by setopt and getinfo can be accessed from CurlOpt and CurlInfo.

class curl_cffi.CurlOpt(value)[source]

CULROPT_ constancs extracted from libcurl, see: https://curl.se/libcurl/c/curl_easy_setopt.html

class curl_cffi.CurlInfo(value)[source]

CURLINFO_ constancs extracted from libcurl, see: https://curl.se/libcurl/c/curl_easy_getinfo.html

class curl_cffi.CurlMOpt(value)[source]

CURLMOPT_ constancs extracted from libcurl, see: https://curl.se/libcurl/c/curl_multi_setopt.html

class curl_cffi.CurlECode(value)[source]

CURLECODE_ constancs extracted from libcurl, see: https://curl.se/libcurl/c/libcurl-errors.html

class curl_cffi.CurlHttpVersion(value)[source]

CURL_HTTP_VERSION constants from libcurl, see comments for details.

class curl_cffi.CurlWsFlag(value)[source]

CURL_WS_FLAG constants from libcurl, see comments for details.

class curl_cffi.CurlSslVersion(value)[source]

CURL_SSLVERSION constants from libcurl, see comments for details.

requests-like API

request method

requests.get, requests.post, etc are just aliases of .request(METHOD, ...)

curl_cffi.requests.request(method: Literal['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE', 'PATCH', 'QUERY'], url: str, thread: Literal['eventlet', 'gevent'] | None = None, curl_options: dict | None = None, debug: bool | None = None, **kwargs: None) Response[source]

Send an http request.

Parameters:
  • method – http method for the request: GET/POST/PUT/DELETE etc.

  • url – url for the requests.

  • params – query string for the requests.

  • data – form values(dict/list/tuple) or binary data to use in body, Content-Type: application/x-www-form-urlencoded will be added if a dict is given.

  • json – json values to use in body, Content-Type: application/json will be added automatically.

  • headers – headers to send.

  • cookies – cookies to use.

  • files – not supported, use multipart instead.

  • auth – HTTP basic auth, a tuple of (username, password), only basic auth is supported.

  • timeout – how many seconds to wait before giving up.

  • allow_redirects – whether to allow redirection.

  • max_redirects – max redirect counts, default 30, use -1 for unlimited.

  • proxies – dict of proxies to use, prefer to use proxy if they are the same. format: {"http": proxy_url, "https": proxy_url}.

  • proxy – proxy to use, format: “http://user@pass:proxy_url”. Can’t be used with proxies parameter.

  • proxy_auth – HTTP basic auth for proxy, a tuple of (username, password).

  • verify – whether to verify https certs.

  • referer – shortcut for setting referer header.

  • accept_encoding – shortcut for setting accept-encoding header.

  • content_callback – a callback function to receive response body. def callback(chunk: bytes) -> None:

  • impersonate – which browser version or fingerprint to impersonate.

  • ja3 – ja3 string to impersonate.

  • akamai – akamai string to impersonate.

  • extra_fp – extra fingerprints options, in complement to ja3 and akamai strings.

  • thread – thread engine to use for working with other thread implementations. choices: eventlet, gevent.

  • default_headers – whether to set default browser headers when impersonating.

  • default_encoding – encoding for decoding response content if charset is not found in headers. Defaults to “utf-8”. Can be set to a callable for automatic detection.

  • quote – Set characters to be quoted, i.e. percent-encoded. Default safe string is !#$%&'()*+,/:;=?@[]~. If set to a sting, the character will be removed from the safe string, thus quoted. If set to False, the url will be kept as is, without any automatic percent-encoding, you must encode the URL yourself.

  • curl_options – extra curl options to use.

  • http_version – limiting http version, defaults to http2.

  • debug – print extra curl debug info.

  • interface – interface name or local IP to bind to (bare IP = source address).

  • cert – a tuple of (cert, key) filenames for client cert.

  • stream – streaming the response, default False.

  • max_recv_speed – maximum receive speed, bytes per second.

  • multipart – upload files using the multipart format, see examples for details.

  • discard_cookies – discard cookies from server. Default to False.

Returns:

A Response object.

Sessions

class curl_cffi.requests.Session(curl: Curl | None = None, thread: ThreadType | None = None, use_thread_local_curl: bool = True, **kwargs: Unpack[BaseSessionParams[R]])[source]

A request session, cookies and connections will be reused. This object is thread-safe, but it’s recommended to use a separate session for each thread.

__init__(curl: Curl | None = None, thread: ThreadType | None = None, use_thread_local_curl: bool = True, **kwargs: Unpack[BaseSessionParams[R]]) None[source]

Parameters set in the __init__ method will be overridden by the same parameter in request method.

Parameters:
  • curl – curl object to use in the session. If not provided, a new one will be created. Also, a fresh curl object will always be created when accessed from another thread.

  • thread – thread engine to use for working with other thread implementations. choices: eventlet, gevent.

  • headers – headers to use in the session.

  • cookies – cookies to add in the session.

  • auth – HTTP basic auth, a tuple of (username, password), only basic auth is supported.

  • proxies – dict of proxies to use, prefer to use proxy if they are the same. format: {"http": proxy_url, "https": proxy_url}.

  • proxy – proxy to use, format: “http://proxy_url”. Cannot be used with the above parameter.

  • proxy_auth – HTTP basic auth for proxy, a tuple of (username, password).

  • base_url – absolute url to use as base for relative urls.

  • params – query string for the session.

  • verify – whether to verify https certs.

  • timeout – how many seconds to wait before giving up.

  • trust_env – use http_proxy/https_proxy and other environments, default True.

  • allow_redirects – whether to allow redirection. Can be a bool, a CurlFollow value, or the string "safe". Use CurlFollow.SAFE or "safe" to reject redirects to internal/private IP addresses (SSRF protection).

  • max_redirects – max redirect counts, default 30, use -1 for unlimited.

  • retry – number of retries or RetryStrategy for failed requests.

  • impersonate – which browser version or fingerprint to impersonate in the session.

  • ja3 – ja3 string to impersonate in the session.

  • akamai – akamai string to impersonate in the session.

  • perk – perk string to impersonate in the session.

  • extra_fp – extra fingerprints options, in complement to ja3 and akamai str.

  • interface – interface name or local IP to bind to (bare IP = source address).

  • doh_url – DNS-over-HTTPS server url, e.g. https://1.1.1.1/dns-query.

  • default_encoding – encoding for decoding response content if charset is not found in headers. Defaults to “utf-8”. Can be set to a callable for automatic detection.

  • cert – a tuple of (cert, key) filenames for client cert.

  • response_class – A customized subtype of Response to use.

  • raise_for_status – automatically raise an HTTPError for 4xx and 5xx status codes.

Notes

This class can be used as a context manager.

from curl_cffi.requests import Session

with Session() as s:
    r = s.get("https://example.com")
request(method: HttpMethod, url: str, params: dict | list | tuple | None = None, data: dict[str, str] | list[tuple] | str | BytesIO | bytes | None = None, json: dict | list | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, files: dict | None = None, auth: tuple[str, str] | None = None, timeout: float | tuple[float, float] | object | None = NOT_SET, allow_redirects: bool | CurlFollow | str | None = None, max_redirects: int | None = None, proxies: ProxySpec | None = None, proxy: str | None = None, proxy_auth: tuple[str, str] | None = None, verify: bool | None = None, referer: str | None = None, accept_encoding: str | None = 'gzip, deflate, br', content_callback: Callable | None = None, impersonate: BrowserTypeLiteral | Fingerprint | None = None, ja3: str | None = None, akamai: str | None = None, perk: str | None = None, extra_fp: ExtraFingerprints | ExtraFpDict | None = None, default_headers: bool | None = None, default_encoding: str | Callable[[bytes], str] = 'utf-8', quote: str | Literal[False] = '', http_version: CurlHttpVersion | HttpVersionLiteral | None = None, interface: str | None = None, doh_url: str | None = None, cert: str | tuple[str, str] | None = None, stream: bool | None = None, max_recv_speed: int = 0, multipart: CurlMime | None = None, discard_cookies: bool = False)[source]

Send the request, see requests.request for details on parameters.

stream(method: Literal['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE', 'PATCH', 'QUERY'], url: str, **kwargs: None) Generator[R, None, None][source]

Equivalent to with request(..., stream=True) as r:

ws_connect(url: str, on_message=None, on_error=None, on_open=None, on_close=None, **kwargs) WebSocket[source]

Connects to a websocket url.

Note: This method is deprecated, use WebSocket instead.

Parameters:
  • url – the ws url to connect.

  • on_message – message callback, def on_message(ws, str)

  • on_error – error callback, def on_error(ws, error)

  • on_open – open callback, def on_open(ws)

  • on_close – close callback, def on_close(ws)

Other parameters are the same as .request

Returns:

a WebSocket instance to communicate with the server.

class curl_cffi.requests.AsyncSession(*, loop: asyncio.AbstractEventLoop | None = None, async_curl: AsyncCurl | None = None, max_clients: int = 10, **kwargs: Unpack[BaseSessionParams[R]])[source]

An async request session, cookies and connections will be reused.

__init__(*, loop: asyncio.AbstractEventLoop | None = None, async_curl: AsyncCurl | None = None, max_clients: int = 10, **kwargs: Unpack[BaseSessionParams[R]]) None[source]

Parameters set in the __init__ method are overridden by the same parameter in request method.

Parameters:
  • loop – loop to use, if not provided, the running loop will be used.

  • async_curl – [AsyncCurl](/api/curl_cffi#curl_cffi.AsyncCurl) object to use.

  • max_clients – maxmium curl handle to use in the session, this will affect the concurrency ratio.

  • headers – headers to use in the session.

  • cookies – cookies to add in the session.

  • auth – HTTP basic auth, a tuple of (username, password), only basic auth is supported.

  • proxies – dict of proxies to use, prefer to use proxy if they are the same. format: {"http": proxy_url, "https": proxy_url}.

  • proxy – proxy to use, format: “http://proxy_url”. Cannot be used with the above parameter.

  • proxy_auth – HTTP basic auth for proxy, a tuple of (username, password).

  • base_url – absolute url to use for relative urls.

  • params – query string for the session.

  • verify – whether to verify https certs.

  • timeout – how many seconds to wait before giving up.

  • trust_env – use http_proxy/https_proxy and other environments, default True.

  • allow_redirects – whether to allow redirection. Can be a bool, a CurlFollow value, or the string "safe". Use CurlFollow.SAFE or "safe" to reject redirects to internal/private IP addresses (SSRF protection).

  • max_redirects – max redirect counts, default 30, use -1 for unlimited.

  • retry – number of retries or RetryStrategy for failed requests.

  • impersonate – which browser version or fingerprint to impersonate in the session.

  • ja3 – ja3 string to impersonate in the session.

  • akamai – akamai string to impersonate in the session.

  • perk – perk string to impersonate in the session.

  • extra_fp – extra fingerprints options, in complement to ja3 and akamai str.

  • default_encoding – encoding for decoding response content if charset is not found in headers. Defaults to “utf-8”. Can be set to a callable for automatic detection.

  • cert – a tuple of (cert, key) filenames for client cert.

  • response_class – A customized subtype of Response to use.

  • raise_for_status – automatically raise an HTTPError for 4xx and 5xx status codes.

Notes

This class can be used as a context manager, and it’s recommended to use via async with. However, unlike aiohttp, it is not required to use with.

from curl_cffi.requests import AsyncSession

# recommended.
async with AsyncSession() as s:
    r = await s.get("https://example.com")

s = AsyncSession()  # it also works.
async request(method: HttpMethod, url: str, params: dict[str, str] | list[tuple[str, str]] | tuple[tuple[str, str], ...] | None = None, data: dict[str, str] | list[tuple[str, str]] | str | BytesIO | bytes | None = None, json: dict[str, Any] | list[Any] | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, files: dict[str, Any] | None = None, auth: tuple[str, str] | None = None, timeout: float | tuple[float, float] | object | None = NOT_SET, allow_redirects: bool | CurlFollow | str | None = None, max_redirects: int | None = None, proxies: ProxySpec | None = None, proxy: str | None = None, proxy_auth: tuple[str, str] | None = None, verify: bool | None = None, referer: str | None = None, accept_encoding: str | None = 'gzip, deflate, br', content_callback: Callable[..., Any] | None = None, impersonate: BrowserTypeLiteral | Fingerprint | None = None, ja3: str | None = None, akamai: str | None = None, perk: str | None = None, extra_fp: ExtraFingerprints | ExtraFpDict | None = None, default_headers: bool | None = None, default_encoding: str | Callable[[bytes], str] = 'utf-8', quote: str | Literal[False] = '', http_version: CurlHttpVersion | HttpVersionLiteral | None = None, interface: str | None = None, doh_url: str | None = None, cert: str | tuple[str, str] | None = None, stream: bool | None = None, max_recv_speed: int = 0, multipart: CurlMime | None = None, discard_cookies: bool = False) R[source]

Send the request, see curl_cffi.requests.request for details on args.

stream(method: Literal['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE', 'PATCH', 'QUERY'], url: str, **kwargs: None) AsyncGenerator[R, None, None][source]

Equivalent to async with request(..., stream=True) as r:

async close() None[source]

Close the session.

ws_connect(url: str, autoclose: bool = True, params: dict[str, object] | list[object] | tuple[object, ...] | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: tuple[str, str] | None = None, timeout: float | tuple[float, float] | NotSetType | None = NOT_SET, allow_redirects: bool | CurlFollow | str | None = None, max_redirects: int | None = None, proxies: ProxySpec | None = None, proxy: str | None = None, proxy_auth: tuple[str, str] | None = None, verify: bool | None = None, referer: str | None = None, accept_encoding: str | None = 'gzip, deflate, br', impersonate: BrowserTypeLiteral | str | Fingerprint | None = None, ja3: str | None = None, akamai: str | None = None, perk: str | None = None, extra_fp: ExtraFingerprints | ExtraFpDict | None = None, default_headers: bool | None = None, quote: str | Literal[False] = '', http_version: CurlHttpVersion | HttpVersionLiteral | None = None, interface: str | None = None, doh_url: str | None = None, cert: str | tuple[str, str] | None = None, max_recv_speed: int = 0, recv_queue_size: int = 128, send_queue_size: int = 128, max_send_batch_size: int = 64, coalesce_frames: bool = False, ws_retry: WebSocketRetryStrategy | None = None, recv_time_slice: float = 0.01, send_time_slice: float = 0.005, max_message_size: int = 4194304, drain_on_error: bool = False, block_on_recv_queue_full: bool = True, curl_options: dict[CurlOpt, str] | None = None) AsyncWebSocketContext[source]

Connects to a WebSocket.

Parameters:
  • url – url for the requests.

  • autoclose – whether to close the WebSocket after receiving a close frame.

  • params – query string for the requests.

  • headers – headers to send.

  • cookies – cookies to use.

  • auth – HTTP basic auth, a tuple of (username, password), only basic auth is supported.

  • timeout – how many seconds to wait before giving up.

  • allow_redirects – whether to allow redirection. Can be a bool, a CurlFollow value, or the string "safe". Use CurlFollow.SAFE or "safe" to reject redirects to internal/private IP addresses (SSRF protection).

  • max_redirects – max redirect counts, default 30, use -1 for unlimited.

  • proxies – dict of proxies to use, prefer to use proxy if they are the same. format: {"http": proxy_url, "https": proxy_url}.

  • proxy – proxy to use, format: “http://user@pass:proxy_url”. Can’t be used with proxies parameter.

  • proxy_auth – HTTP basic auth for proxy, a tuple of (username, password).

  • verify – whether to verify https certs.

  • referer – shortcut for setting referer header.

  • accept_encoding – shortcut for setting accept-encoding header.

  • impersonate – which browser version or fingerprint to impersonate.

  • ja3 – ja3 string to impersonate.

  • akamai – akamai string to impersonate.

  • perk – perk string to impersonate.

  • extra_fp – extra fingerprints options, in complement to ja3 and akamai str.

  • default_headers – whether to set default browser headers.

  • quote – Set characters to be quoted, i.e. percent-encoded. Default safe string is !#$%&'()*+,/:;=?@[]~. If set to a string, the character will be removed from the safe string, thus quoted. If set to False, the url will be kept as is, without any automatic percent-encoding, you must encode the URL yourself.

  • http_version – limiting http version, defaults to http2.

  • interface – interface name or local IP to bind to (bare IP = source address).

  • doh_url – DNS-over-HTTPS server url, e.g. https://1.1.1.1/dns-query.

  • cert – a tuple of (cert, key) filenames for client cert.

  • max_recv_speed – maximum receive speed, bytes per second.

  • recv_queue_size – The maximum number of incoming WebSocket messages to buffer internally. This queue stores messages received by the Curl socket that are waiting to be consumed on calling recv().

  • send_queue_size – The maximum number of outgoing WebSocket messages to buffer before applying network backpressure. When you call send() the message is placed in this queue and transmitted when the Curl socket is next available for sending.

  • max_send_batch_size – The max batch size for sent frames.

  • coalesce_frames – When set, multiple pending messages in the send queue may be merged into a single WebSocket frame for improved throughput. Warning: This breaks the one-to-one mapping of send() calls to frames and should only be used when the application protocol is designed to handle concatenated data streams. Defaults to False.

  • ws_retry (WebSocketRetryStrategy) – Retry policy for WebSocket messages.

  • recv_time_slice – The maximum duration (in seconds) to process incoming messages before yielding to the event loop. Defaults to 0.01 (10ms).

  • send_time_slice – The maximum duration (in seconds) to process outgoing messages before yielding to the event loop. Defaults to 0.005 (5ms).

  • max_message_size – Maximum allowed size for a complete received WebSocket message (default: 4 MiB).

  • drain_on_error – If True, when a connection error occurs,

  • first (attempt to consume all the buffered received messages)

:param : :param before raising the error. Otherwise: :type before raising the error. Otherwise: default :param raise it immediately: :type raise it immediately: default :param block_on_recv_queue_full: If False, the connection

is failed immediately when the receive queue is full. The message that caused the overflow is not delivered; any messages already buffered may still be drained if drain_on_error=True.

Parameters:

curl_options – extra curl options to use.

Cache

class curl_cffi.requests.CacheBackend(*, expires: timedelta, methods: Sequence[str] | None = None, ignored: Sequence[str] | None = None)[source]
__init__(*, expires: timedelta, methods: Sequence[str] | None = None, ignored: Sequence[str] | None = None) None[source]
should_cache_request(request: Request, *, stream: bool = False, content_callback: Any = None) bool[source]

XXX: streamed content is not cached.

should_store_response(response: Response) bool[source]
get(request: Request, response_class: type[Response] = <class 'curl_cffi.requests.models.Response'>) Response | None[source]
set(request: Request, response: Response) None[source]
delete(request: Request) None[source]
abstractmethod _read_payload(key: str) dict[str, Any] | None[source]
abstractmethod _write_payload(key: str, payload: dict[str, Any]) None[source]
abstractmethod _delete_payload(key: str) None[source]
abstractmethod clear() None[source]
class curl_cffi.requests.FileCacheBackend(*, expires: timedelta, path: str | PathLike[str] | None = None, methods: Sequence[str] | None = None, ignored: Sequence[str] | None = None)[source]
__init__(*, expires: timedelta, path: str | PathLike[str] | None = None, methods: Sequence[str] | None = None, ignored: Sequence[str] | None = None) None[source]
clear() None[source]

Headers

class curl_cffi.requests.Headers(headers: Headers | Mapping[str, str | None] | Mapping[bytes, bytes | None] | Sequence[tuple[str, str]] | Sequence[tuple[bytes, bytes]] | Sequence[str | bytes] | None = None, encoding: str | None = None)[source]

HTTP headers, as a case-insensitive multi-dict.

property encoding: str

Header encoding is mandated as ascii, but we allow fallbacks to utf-8 or iso-8859-1.

raw()

Returns a list of the raw header items, as byte pairs.

multi_items() list[tuple[str, str | None]][source]

Return a list of (key, value) pairs of headers. Allow multiple occurrences of the same key without concatenating into a single comma separated value.

get(key: str, default: Any = None) Any[source]

Return a header value. If multiple occurrences of the header occur then concatenate them together with commas.

get_list(key: str, split_commas: bool = False) list[str | None][source]

Return a list of all header values for a given key. If split_commas=True is passed, then any comma separated header values are split into multiple return strings.

update([E, ]**F) None.  Update D from mapping/iterable E and F.[source]

If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

__getitem__(key: str) str | None[source]

Return a single header value. If there are multiple headers with the same key, then we concatenate them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2

__setitem__(key: str, value: str | None) None[source]

Set the header key to value, removing any duplicate entries. Retains insertion order.

__delitem__(key: str) None[source]

Remove the header key.

Cookies

class curl_cffi.requests.Cookies(cookies: Cookies | CookieJar | dict[str, str] | list[tuple[str, str]] | None = None)[source]

HTTP Cookies, as a mutable mapping.

set(name: str, value: str, domain: str = '', path: str = '/', secure=False) None[source]

Set a cookie value by name. May optionally include domain and path.

get(name: str, default: str | None = None, domain: str | None = None, path: str | None = None) str | None[source]

Get a cookie by name. May optionally include domain and path in order to specify exactly which cookie to retrieve.

delete(name: str, domain: str | None = None, path: str | None = None) None[source]

Delete a cookie by name. May optionally include domain and path in order to specify exactly which cookie to delete.

clear(domain: str | None = None, path: str | None = None) None[source]

Delete all cookies. Optionally include a domain and path in order to only delete a subset of all the cookies.

update([E, ]**F) None.  Update D from mapping/iterable E and F.[source]

If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

__getitem__(name: str) str[source]
__setitem__(name: str, value: str) None[source]
__delitem__(name: str) None[source]

Request, Response

class curl_cffi.requests.Request(url: str, headers: Headers, method: str, body: bytes | None = None)[source]

Representing a sent request.

url

request url.

headers

request headers.

method

request http method.

body

request body as bytes, or None if not provided.

class curl_cffi.requests.Response(curl: Curl | None = None, request: Request | None = None)[source]

Contains information the server sends.

url

url used in the request.

content

response body in bytes.

text

response body in str.

status_code

http status code.

reason

http response reason, such as OK, Not Found.

ok

is status_code in [200, 400)?

headers

response headers.

cookies

response cookies.

elapsed

timedelta of the request duration.

encoding

http body encoding.

charset

alias for encoding.

primary_ip

primary ip of the server.

primary_port

primary port of the server.

local_ip

local ip used in this connection.

local_port

local port used in this connection.

charset_encoding

encoding specified by the Content-Type header.

default_encoding

encoding for decoding response content if charset is not found in headers. Defaults to “utf-8”. Can be set to a callable for automatic detection.

redirect_count

how many redirects happened.

redirect_url

the final redirected url.

http_version

http version used.

history

history redirections, only headers are available.

download_size

total downloaded bytes (body).

upload_size

total uploaded bytes (body).

header_size

total header size.

request_size

request size.

response_size

download_size + header_size

raise_for_status()[source]

Raise an error if status code is not in [200, 400)

iter_lines(chunk_size=None, decode_unicode=False, delimiter=None)[source]

iterate streaming content line by line, separated by \n.

Copied from: https://requests.readthedocs.io/en/latest/_modules/requests/models/ which is under the License: Apache 2.0

iter_content(chunk_size=None, decode_unicode=False)[source]

iterate streaming content chunk by chunk in bytes.

json(**kw)[source]

return a parsed json object of the content.

close()[source]

Close the streaming connection, only valid in stream mode.

async aiter_lines(chunk_size=None, decode_unicode=False, delimiter=None)[source]

iterate streaming content line by line, separated by \n.

Copied from: https://requests.readthedocs.io/en/latest/_modules/requests/models/ which is under the License: Apache 2.0

async aiter_content(chunk_size=None, decode_unicode=False)[source]

iterate streaming content chunk by chunk in bytes.

async atext() str[source]

Return a decoded string.

async acontent() bytes[source]

wait and read the streaming content in one bytes object.

async aclose()[source]

Close the streaming connection, only valid in stream mode.

Asyncio

WebSocket

final class curl_cffi.requests.WebSocket(curl: Curl | NotSetType = NOT_SET, *, autoclose: bool = True, skip_utf8_validation: bool = False, debug: bool = False, on_open: ON_OPEN_T | None = None, on_close: ON_CLOSE_T | None = None, on_data: ON_DATA_T | None = None, on_message: ON_MESSAGE_T | None = None, on_error: ON_ERROR_T | None = None)[source]

A WebSocket implementation using libcurl.

__init__(curl: Curl | NotSetType = NOT_SET, *, autoclose: bool = True, skip_utf8_validation: bool = False, debug: bool = False, on_open: ON_OPEN_T | None = None, on_close: ON_CLOSE_T | None = None, on_data: ON_DATA_T | None = None, on_message: ON_MESSAGE_T | None = None, on_error: ON_ERROR_T | None = None) None[source]
Parameters:
  • autoclose – whether to close the WebSocket after receiving a close frame.

  • skip_utf8_validation – whether to skip UTF-8 validation for text frames in run_forever().

  • debug – print extra curl debug info.

  • on_open – open callback, def on_open(ws)

  • on_close – close callback, def on_close(ws, code, reason)

  • on_data – raw data receive callback, def on_data(ws, data, frame)

  • on_message – message receive callback, def on_message(ws, message)

  • on_error – error callback, def on_error(ws, exception)

connect(url: str, params: dict[str, object] | list[object] | tuple[str, int | list[str] | dict[str, str | int]] | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: tuple[str, str] | None = None, timeout: float | tuple[float, float] | object | None = NOT_SET, allow_redirects: bool | CurlFollow | str = True, max_redirects: int = 30, proxies: ProxySpec | None = None, proxy: str | None = None, proxy_auth: tuple[str, str] | None = None, verify: bool | None = None, referer: str | None = None, accept_encoding: str | None = 'gzip, deflate, br', impersonate: BrowserTypeLiteral | str | Fingerprint | None = None, ja3: str | None = None, akamai: str | None = None, perk: str | None = None, extra_fp: ExtraFingerprints | ExtraFpDict | None = None, default_headers: bool = True, quote: str | Literal[False] = '', http_version: CurlHttpVersion | None = None, interface: str | None = None, cert: str | tuple[str, str] | None = None, max_recv_speed: int = 0, curl_options: dict[CurlOpt, str] | None = None) Self[source]

Connect to the WebSocket.

libcurl automatically handles pings and pongs. ref: https://curl.se/libcurl/c/libcurl-ws.html

Parameters:
  • url – url for the requests.

  • params – query string for the requests.

  • headers – headers to send.

  • cookies – cookies to use.

  • auth – HTTP basic auth, a tuple of (username, password), only basic auth is supported.

  • timeout – how many seconds to wait before giving up.

  • allow_redirects – whether to allow redirection. Can be a bool, a CurlFollow value, or the string "safe".

  • max_redirects – max redirect counts, default 30, use -1 for unlimited.

  • proxies – dict of proxies to use, prefer to use proxy if they are the same. format: {"http": proxy_url, "https": proxy_url}.

  • proxy – proxy to use, format: “http://user@pass:proxy_url”. Can’t be used with proxies parameter.

  • proxy_auth – HTTP basic auth for proxy, a tuple of (username, password).

  • verify – whether to verify https certs.

  • referer – shortcut for setting referer header.

  • accept_encoding – shortcut for setting accept-encoding header.

  • impersonate – which browser version or fingerprint to impersonate.

  • ja3 – ja3 string to impersonate.

  • akamai – akamai string to impersonate.

  • perk – perk string to impersonate.

  • extra_fp – extra fingerprints options, in complement to ja3 and akamai str.

  • default_headers – whether to set default browser headers.

  • default_encoding – Encoding for decoding content if charset is not found. Defaults to “utf-8”.

  • quote – Set characters to be quoted (percent-encoded). Default safe string is !#$%&'()*+,/:;=?@[]~. If set to a string, the characters will be removed from the safe string. If set to False, the URL is used as-is (you must encode it yourself).

  • http_version – Limiting http version, defaults to http2.

  • interface – interface name or local IP to bind to (bare IP = source address).

  • cert – a tuple of (cert, key) filenames for client cert.

  • max_recv_speed – maximum receive speed, bytes per second.

  • curl_options – extra curl options to use.

recv() tuple[bytes, int][source]

Receive a frame as bytes. libcurl splits frames into fragments, so we have to collect all the chunks for a frame.

recv_str() str[source]

Receive a text frame.

recv_json(*, loads: Callable[[str], T] = <function loads>) T[source]

Receive a JSON frame.

Parameters:

loads – JSON decoder, default is json.loads.

send(payload: str | bytes, flags: CurlWsFlag = CurlWsFlag.BINARY) int[source]

Send a data frame.

Parameters:
  • payload – data to send.

  • flags – flags for the frame.

send_binary(payload: bytes) int[source]

Send a binary frame.

Parameters:

payload – binary data to send.

send_bytes(payload: bytes)[source]

Send a binary frame, alias of send_binary().

Parameters:

payload – binary data to send.

send_str(payload: str) int[source]

Send a text frame.

Parameters:

payload – text data to send.

send_json(payload: object, *, dumps: ~collections.abc.Callable[[...], str] = <function dumps>) int[source]

Send a JSON frame.

Parameters:
  • payload – data to send.

  • dumps – JSON encoder, default is json.dumps.

ping(payload: str | bytes) int[source]

Send a ping frame.

Parameters:

payload – data to send.

run_forever(url: str = '', **kwargs) None[source]

Run the WebSocket forever. See connect() for details on parameters.

libcurl automatically handles pings and pongs. ref: https://curl.se/libcurl/c/libcurl-ws.html

close(code: int = WsCloseCode.OK, message: bytes = b'')[source]

Close the connection.

Parameters:
  • code – close code.

  • message – close reason.

final class curl_cffi.requests.AsyncWebSocket(session: AsyncSession, curl: Curl, *, autoclose: bool = True, debug: bool = False, recv_queue_size: int = 128, send_queue_size: int = 128, max_send_batch_size: int = 64, coalesce_frames: bool = False, ws_retry: WebSocketRetryStrategy | None = None, recv_time_slice: float = 0.01, send_time_slice: float = 0.005, max_message_size: int = 4194304, drain_on_error: bool = False, block_on_recv_queue_full: bool = True)[source]

An asyncio WebSocket implementation using libcurl.

__init__(session: AsyncSession, curl: Curl, *, autoclose: bool = True, debug: bool = False, recv_queue_size: int = 128, send_queue_size: int = 128, max_send_batch_size: int = 64, coalesce_frames: bool = False, ws_retry: WebSocketRetryStrategy | None = None, recv_time_slice: float = 0.01, send_time_slice: float = 0.005, max_message_size: int = 4194304, drain_on_error: bool = False, block_on_recv_queue_full: bool = True) None[source]

Initializes an Async WebSocket session.

Do not instantiate this class directly. Use AsyncSession.ws_connect.

This class implements an async context manager, closing the connection automatically on exit:

async with AsyncSession() as session:
    async with session.ws_connect("wss://api.example.com") as ws:
        await ws.send("Hello")
        msg = await ws.recv()
Parameters:
  • session (AsyncSession) – The parent session object.

  • curl (Curl) – The underlying Curl handle.

  • autoclose (bool) – Automatically close on receiving a close frame.

  • debug (bool) – Enable verbose debug logging.

  • recv_queue_size (int) – Max number of incoming messages to buffer.

  • send_queue_size (int) – Max number of outgoing messages to buffer.

  • max_send_batch_size (int) – Max frames to coalesce per transmission.

  • coalesce_frames (bool) – Combine small frame payloads to improve throughput.

  • ws_retry (WebSocketRetryStrategy) – Retry configuration for failed receives.

  • recv_time_slice (float) – Max seconds to read messages before yielding.

  • send_time_slice (float) – Max seconds to write messages before yielding.

  • max_message_size (int) – Max size (bytes) of a single received message.

  • drain_on_error (bool) – Yield buffered messages before raising errors.

  • block_on_recv_queue_full (bool) – Behavior when the receive queue is full. If True (default), the reader blocks (may cause timeouts). If False, the connection fails immediately to prevent data loss.

Note

Architecture: This uses a background I/O model. Network operations run in background tasks. Errors are raised in subsequent calls to send() or recv().

Performance: The time_slice defaults (5ms read / 1ms write) favor reading to compensate for libcurl’s overhead. Increase these values to allocate more CPU time to I/O operations at the cost of event loop latency.

async recv(*, timeout: float | None = None) tuple[bytes, int][source]

Receive a WebSocket message.

This method waits for and returns the next complete WebSocket message.

Parameters:
  • timeout – How many seconds to wait for a message before raising

  • error. (a timeout)

Returns:

A tuple with the received payload and flags.

Return type:

tuple[bytes, int]

Raises:
  • WebSocketTimeout – If the timeout expires.

  • WebSocketClosed – If the connection is closed.

  • WebSocketError – If a network-level transport error occurs.

Notes

Message fragmentation and reassembly are handled automatically by the implementation, so callers will always receive complete messages.

WebSocketError exceptions may have originated from prior send() or recv() operations, since all operations share the same transport state once a failure occurs.

This method does not wait for additional messages after a transport error is detected. If drain_on_error=True, subsequent calls to recv() will return any messages that were buffered in the receive queue at the time the reader failed, before the connection error is raised.

Concurrent calls to recv() are supported and safe; each caller awaits the next available message and will receive distinct messages in FIFO order.

If this coroutine is cancelled while a message is being received, that message may be dropped. Cancellation is treated as abandoning the receive operation.

async recv_str(*, timeout: float | None = None) str[source]

Receive a text frame.

Parameters:

timeout – how many seconds to wait before giving up.

async recv_json(*, loads: Callable[[str], T] = <function loads>, timeout: float | None = None) T[source]

Receive a JSON frame.

Parameters:
  • loads – JSON decoder, default is json.loads().

  • timeout – how many seconds to wait before giving up.

Raises:

WebSocketError – Received frame is invalid or failed to decode JSON.

async send(payload: str | bytes | bytearray | memoryview, flags: CurlWsFlag | int = CurlWsFlag.BINARY, timeout: float | None = None) None[source]

Send a WebSocket message.

Parameters:
  • payload – Data to send (str/bytes/bytearray/memoryview).

  • flags – Frame type flags (e.g., CurlWsFlag.TEXT / CurlWsFlag.BINARY).

  • timeout – Max seconds to wait if the send queue is full.

Raises:
  • CurlError – Network related exception occured.

  • WebSocketClosed – The WebSocket has been closed.

  • WebSocketTimeout – The send operation timed out.

Note

There are no limits on the size of the message that can be sent. Large outbound messages are seamlessly broken down into optimal fragments using the CURLWS_CONT flag, arriving as a single logical message to the server.

Warning

This method is non-blocking. It queues the message for immediate transmission. Use await ws.flush() after sending if you need to guarantee that the data has actually reached the socket.

async send_binary(payload: bytes) None[source]

Send a binary frame.

Parameters:

payload – binary data to send.

For more info, see the docstring for send()

async send_bytes(payload: bytes) None[source]

Send a binary frame, alias of send_binary().

Parameters:

payload – binary data to send.

For more info, see the docstring for send()

async send_str(payload: str) None[source]

Send a text frame.

Parameters:

payload – text data to send.

For more info, see the docstring for send()

async send_json(payload: object, *, dumps: ~collections.abc.Callable[[...], str] = <function dumps>) None[source]

Send a JSON frame.

Parameters:
  • payload – data to send.

  • dumps – JSON encoder, default is json.dumps().

For more info, see the docstring for send()

async ping(payload: str | bytes) None[source]

Send a ping frame.

Parameters:

payload – data to send.

Raises:

WebSocketError – The payload length is outside specification.

For more info, see the docstring for send()

async close(code: int = WsCloseCode.OK, message: str | bytes = b'', timeout: float = 3.0) None[source]

Performs a graceful WebSocket closing handshake and terminates the connection.

This method sends a WebSocket close frame to the peer, waits for queued outgoing messages to be sent, and then shuts down the connection.

Parameters:
  • code (int) – Close code. Defaults to WsCloseCode.OK.

  • message (bytes) – Close reason. Defaults to b"".

  • timeout (float) – How long (in seconds) to wait for the connection to close gracefully before force-terminating.

Exceptions and Warnings

Exceptions

We try to follow the requests exception hirearchy, however, some are missing, while some are added.

If an exception is marked as “not used”, please catch the base exception.

class curl_cffi.requests.exceptions.RequestException(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Base exception for curl_cffi.requests package

class curl_cffi.requests.exceptions.CookieConflict(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Same cookie exists for different domains.

class curl_cffi.requests.exceptions.SessionClosed(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The session has already been closed.

class curl_cffi.requests.exceptions.ImpersonateError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The impersonate config was wrong or impersonate failed.

class curl_cffi.requests.exceptions.InvalidJSONError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

A JSON error occurred. not used

class curl_cffi.requests.exceptions.HTTPError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

An HTTP error occurred.

class curl_cffi.requests.exceptions.IncompleteRead(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Incomplete read of content

class curl_cffi.requests.exceptions.ConnectionError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

A Connection error occurred.

class curl_cffi.requests.exceptions.DNSError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Could not resolve

class curl_cffi.requests.exceptions.ProxyError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

A proxy error occurred.

class curl_cffi.requests.exceptions.SSLError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

An SSL error occurred.

class curl_cffi.requests.exceptions.CertificateVerifyError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Raised when certificate validated has failed

class curl_cffi.requests.exceptions.Timeout(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The request timed out.

class curl_cffi.requests.exceptions.ConnectTimeout(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The request timed out while trying to connect to the remote server.

Requests that produced this error are safe to retry.

not used

class curl_cffi.requests.exceptions.ReadTimeout(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The server did not send any data in the allotted amount of time. not used

class curl_cffi.requests.exceptions.URLRequired(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

A valid URL is required to make a request. not used

class curl_cffi.requests.exceptions.TooManyRedirects(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Too many redirects.

class curl_cffi.requests.exceptions.MissingSchema(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The URL scheme (e.g. http or https) is missing. not used

class curl_cffi.requests.exceptions.InvalidSchema(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The URL scheme provided is either invalid or unsupported. not used

class curl_cffi.requests.exceptions.InvalidURL(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The URL provided was somehow invalid.

class curl_cffi.requests.exceptions.InvalidHeader(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The header value provided was somehow invalid. not used

class curl_cffi.requests.exceptions.InvalidProxyURL(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The proxy URL provided is invalid. not used

class curl_cffi.requests.exceptions.ChunkedEncodingError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The server declared chunked encoding but sent an invalid chunk. not used

class curl_cffi.requests.exceptions.ContentDecodingError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Failed to decode response content. not used

class curl_cffi.requests.exceptions.StreamConsumedError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

The content for this response was already consumed. not used

class curl_cffi.requests.exceptions.RetryError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Custom retries logic failed. not used

class curl_cffi.requests.exceptions.UnrewindableBodyError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

Requests encountered an error when trying to rewind a body. not used

class curl_cffi.requests.exceptions.InterfaceError(msg, code: CurlECode | Literal[0] = 0, response=None, *args, **kwargs)[source]

A specified outgoing interface could not be used.

Warnings

class curl_cffi.requests.exceptions.RequestsWarning[source]

Base warning for Requests. not used

class curl_cffi.requests.exceptions.FileModeWarning[source]

A file was opened in text mode, but Requests determined its binary length. not used

class curl_cffi.requests.exceptions.RequestsDependencyWarning[source]

An imported dependency doesn’t match the expected version range.