Feb 04 2021 03:20 PM
I imported exported brain from azure as Docker image.
Ran the container.
Verified the webservice in postman. Obtained the response.
URL: http://localhost:5000/v1/prediction
Method: Get/Post
Sample Request body:
{
"x_position": 0.31,
"x_velocity": 0.07,
"angle_position": 11.3,
"angle_velocity": 0.8
}
Sample Response:
{
"command": 1.0
}
But on calling the endpoint using python code, the program is stuck with no response. Code as follows:
>>> import requests
>>> endpoint = "http://localhost:5000/v1/prediction"
>>> state = {
... "x_position": 0.31,
... "x_velocity": 0.07,
... "angle_position": 11.3,
... "angle_velocity": 0.8
... }
>>> requests.get(endpoint, json=state)
Feb 04 2021 05:22 PM
@smartsubbu Thanks for posting the question. I don't see anything obviously wrong with your Python code, but there must be some relevant difference between the postman query and the Python query.
I noticed that the postman query says "Method Get/Post", so I'm not sure which of those two methods was used. Exported brains support both get and post, but "post" is the preferred method, and "get" is deprecated (although still theoretically supported). Could you try changing your Python code to use "post" instead? I recommend restarting your brain container before you try sending it a new request.
If the "post" doesn't work, then the next step is to look more deeply at how the postman query differs form the query sent via Python.
-Eric
Feb 05 2021 08:10 AM
@erictr Thanks for your suggestions. I have already tried both get and post, but tried again today.
1. Restarted the container.
2. Verified again in postman with Post method - Pass
3. Ran a python code with Post method and including a header
B4 request
Traceback (most recent call last):
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 426, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
httplib_response = conn.getresponse()
File "C:\Users\subkris\Miniconda3\lib\http\client.py", line 1332, in getresponse
response.begin()
File "C:\Users\subkris\Miniconda3\lib\http\client.py", line 303, in begin
version, status, reason = self._read_status()
File "C:\Users\subkris\Miniconda3\lib\http\client.py", line 264, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "C:\Users\subkris\Miniconda3\lib\socket.py", line 669, in readinto
return self._sock.recv_into(b)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\adapters.py", line 439, in send
resp = conn.urlopen(
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 726, in urlopen
retries = retries.increment(
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\util\retry.py", line 410, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\packages\six.py", line 735, in reraise
raise value
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 670, in urlopen
httplib_response = self._make_request(
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 428, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "C:\Users\subkris\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 335, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='localhost', port=5000): Read timed out. (read timeout=5)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\subkris\Miniconda3\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\subkris\Miniconda3\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "c:\Users\subkris\.vscode\extensions\ms-python.python-2021.1.502429796\pythonFiles\lib\python\debugpy\__main__.py", line 45, in <module>
cli.main()
File "c:\Users\subkris\.vscode\extensions\ms-python.python-2021.1.502429796\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 444, in main
run()
File "c:\Users\subkris\.vscode\extensions\ms-python.python-2021.1.502429796\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 285, in run_file runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
File "C:\Users\subkris\Miniconda3\lib\runpy.py", line 265, in run_path
return _run_module_code(code, init_globals, run_name,
File "C:\Users\subkris\Miniconda3\lib\runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "C:\Users\subkris\Miniconda3\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "c:\Learning\Python_Trials\call_service.py", line 17, in <module>
response = requests.post(url, json=payload, timeout=5)
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\api.py", line 119, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "C:\Users\subkris\Miniconda3\lib\site-packages\requests\adapters.py", line 529, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='localhost', port=5000): Read timed out. (read timeout=5)
Without using timeout attribute, the code gets stuck at the request line.
Feb 05 2021 09:18 AM
There's clearly something different about postman and the Python `requests` library are formulating the HTTP query. We need to figure out what's going wrong with the latter.
Can you confirm that you added the headers to the request? In your sample below, you define `headers`, but you don't pass it in to post call. I don't think that should matter because the documentation for `requests` says that if you pass an argument to the `json` parameter, the `Content-Type` will be set to `application/json` automatically.
Another thought is to include the header _and_ manually encode the json payload to ensure that it's properly formed. That way, you can print it out and examine it before it's sent.
```python
json_payload = json.dumps(payload)
print(json_payload)
response = requests.post(url, data=json_payload, headers=headers)
```
Another idea is to modify the URL to "http://localhost:5000/v1/dummy" to see if you receive an error or a hang. That will tell us whether you're reaching the HTTP server within the container.
-Eric
Feb 05 2021 10:10 AM
I was making several changes and forgot to include header. But adding the header made no difference. I changed the code to try other options you suggested
Feb 05 2021 11:20 AM
@erictr The same python code works if I deploy in cloud in a acr and use the azurewebsites.net/v1/prediction url.
{"x_position": 0.31, "x_velocity": 0.07, "angle_position": 11.3, "angle_velocity": 0.8}
B4 request
{"command":1.0}
End of program
Feb 07 2021 09:13 AM
@smartsubbu Here's another suggestion from another engineer on our team.
Try running:
```
Feb 08 2021 01:03 PM
SolutionHi @smartsubbu,
Do you see this same freezing behavior with a local container only after trying to run it with postman, or regardless of whether you've run with postman or not? A quick test would be to restart the export brain container then try to access it with either curl or your python script as it's first request.
Feb 08 2021 01:16 PM
@erictr I tried the first curl command. After waiting around 10mins gave up. Its stuck with this message
* Trying 127.0.0.1:5000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /v1/status HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.68.0
> Accept: */*
>
Even tried the second command and waited for 5 mins. No response after this message
* Trying 127.0.0.1:5000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> POST /v1/prediction HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 87
>
* upload completely sent off: 87 out of 87 bytes
Feb 08 2021 01:34 PM
@chetand I never thought of this. As you mentioned, I restarted the container and ran both my python program and curl command in bash without verifying in Postman. Both worked fine.
Curl output:
> --header 'Content-Type: application/json' \
> --data-raw '{
> "x_position": 0.31,
> "x_velocity": 0.07,
> "angle_position": 7.3,
> "angle_velocity": 0.8
> }'
{"command":1.0}
Any idea, why running in postman would be creating an issue. Is it blocking all other connections?
Feb 08 2021 02:08 PM
@smartsubbu That's good news!
We've found that postman adds a "keep-alive" header by default, and that's what causes this behavior. IIRC, there's a setting in postman to not specify this header.
Feb 08 2021 02:10 PM
Feb 08 2021 07:48 PM
Feb 09 2021 01:40 PM
@erictr That's great. I verified myself, disabling that hidden header and running in postman. Now python code is also able to access. Thanks for figuring out the root cause.
Feb 09 2021 01:49 PM
@Kinshuman Thanks for your suggestion. I have tried waiting for 10 mins, but have waited for 5 mins several times. But by verifying other recommendations/suggestions in this thread, the root cause is postman trying to keep the connection alive after a request. With that header disabled, it works parallelly in both python and postman.