Before any HTTP is exchanged, a client opens a TLS connection with a ClientHello message. It lists the TLS versions, cipher suites, extensions, curves and protocols the client supports, and each TLS library fills it in its own way. Chrome's BoringSSL, Firefox's NSS, the OpenSSL behind Python's requests and Go's crypto/tls all produce recognisably different messages. Hashing those details gives a fingerprint, most commonly JA3 or JA4.
Why it matters
A site can read your TLS fingerprint before your request line, headers or JavaScript. If a request claims a Chrome User-Agent but its handshake is plainly Python's, the mismatch is enough to block it, however clean the IP.
What a proxy does to it
Nothing. HTTPS traffic crosses an HTTP or SOCKS5 proxy inside a tunnel, so the ClientHello your library wrote is the ClientHello the site reads. Changing proxy type, provider or country leaves the fingerprint as it was. The fix is on the client side: a library that impersonates a browser handshake, such as curl_cffi, or a real browser driven by Playwright or Puppeteer.
See your own
curl -s https://tls.peet.ws/api/all
Run the same request through Python and through a browser and compare the JA4 values. TLS fingerprinting with curl_cffi shows measured results, and the HTTP/2 fingerprint is the next layer the same sites check.
Common confusion
A TLS fingerprint identifies software, not a person or a device. Millions of Chrome users share the same one, which is exactly why looking like Chrome helps and looking like a scripting library does not.