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.
CodePudding user response:
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.