I've written a game server in python which communicates to multiple pygame clients via sockets. Since it's a turn-based card game there isnt that much data flowing and it's in JSON format. Because I don't want people having to download the client I've started working on a 3D UI with three.js and it's not looking bad.
However I am currently stuck with the communication between the backend (my python game server) and the frontend (The webpage / client I am building with html, javascript and three.js). I feel like my question is already pretty specific and don't get any helpful results when looking online.
How can the webpage (client) and the python server communicate? What changes do I need to make on the python server side? And what do I need to know to implement this on the client side in javascript?
Because your client is running in a web browser, your main limitation is what the browser supports. Javascript in browsers is severely limited so that a website can't trick computers that visit the website into doing bad stuff.
So the first step is to find out "How can my Javascript web page communicate with a backend at all?" and then once you have chosen something, write the backend after that.
You have two options: HTTP requests (AJAX) or websockets.
An HTTP request is basically the same way the browser downloads the page to begin with, and the pictures on the page. The browser says to the server "hey, give me the address http://127.0.0.1:8000/play_card?card_number=3 and the server says back "the page says OK". Little does the browser know, that your server made you play card number 3 and now it's the next player's turn.
This is one-way - the client can ask for stuff, the server can't just send it. So the client has to keep asking over and over, whether anything has happened. The client might ask for address http://127.0.0.1:8000/game_status?player=5 and maybe the server says {} if nothing has changed. (Or maybe it says the entire game status and then you don't need the player number. Depends on the game.)
The other option is websockets. The browser sends a special request saying "hey please make this connection into a websocket" and the server sends a special response saying "okay, this connection is now a websocket", and then the connection stays open for as long as the client wants, and the client and server can send data at any time. It's not just a normal socket, though, because there are extra security measures to prevent the webpage from doing naughty stuff. And the connection always starts with an HTTP request and response.

In either case, note that http://127.0.0.1:8000 has to be the same website that the web page came from - websites can't just send requests to other websites (that would be naughty), so your server also has to serve the game page itself. (not difficult)
You can implement HTTP and/or websockets yourself by listening on a socket on port 8000 (or any other port), but you'll have to learn the HTTP protocol and get it right or else it won't work. It's actually not too difficult but it is work that you have to do. Or you can use a library someone else wrote, like http.server or websockets.
What steps do I need to take to replace my pygame client with a browser game?