'http post request + response from localhost in python
Many questions regarding http post requests, but I can't make a complete example running.
$ tree
.
└── src
└── main.py # <----- this is the file I want to send data to
$ cat src/main.py
from typing import Dict, List
class Handler: # <----- (Probably should inherit from some class ?!)
def post(self, data: Dict[str, int]) -> List[str]:
return "+++".join([k for k in data])
$ python -m http.server 8001
Now I try to send data (from some other terminal)
$ cat send_something.py
import requests
x = requests.post("http://localhost:8001/src/main.py", data={"name": 700, "id": 99})
print(x)
And I get a 501 response which means I'm doing something wrong:
$ python send_something.py
<Response [501]>
On the localhost server I do see the post request, but with an error message:
127.0.0.1 - - [20/Apr/2022 09:29:22] code 501, message Unsupported method ('POST')
127.0.0.1 - - [20/Apr/2022 09:29:22] "POST /src/main.py HTTP/1.1" 501 -
Any help is very much appreciated, thanks.
Solution 1:[1]
Turns out I was missing many things. Here is the server code. It will receive json data and tweak it a bit as proof of concept.
import json
from typing import List
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
from attrs import asdict
from attrs import define
HOST = "127.0.0.1"
PORT = 8027 # <----- nailed it in the 27th try :)
@define
class Entry:
name: str
some_list: List[int]
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
# read incoming sent data
data = self.rfile.read(self._sent_data_size)
# do something with it ...
response = self._process(data.decode("utf-8"))
# perpare the (json) response
jsonbytes = self._prepare_json_response(response)
# send the (json) response back ...
self.wfile.write(jsonbytes)
def _process(self, data: str) -> List[Entry]:
return [
Entry("employee"+str(i), [d["id"], d["salary"]])
for i, d in enumerate(json.loads(data))
]
def _prepare_json_response(self, response: List[Entry]) -> bytes:
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
jsonstr = json.dumps(
response,
indent=4,
default=asdict
)
return jsonstr.encode()
@property
def _sent_data_size(self) -> int:
return int(self.headers.get("Content-Length"))
server = HTTPServer((HOST, PORT), Handler)
server.serve_forever()
server.serve_close()
Here is the client code:
import requests
with open("input.json") as fl:
data = json.load(fl)
x = requests.post("http://localhost:8027", json=data)
print(x.json())
The server is started, then the client sends the json data (from another terminal). the client receives the tweaked json properly and that's the happy end.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | OrenIshShalom |
