I have a strange issue with the TCP JSON-RPC server I've created in Python-2.7. I used the following code to build the server:
https://github.com/joshmarshall/jsonrpclib
I am communicating client to server from within the same local network. In the console window, I can connect to and run commands against the server from within Python. All is well there.
However, when I try to send JSON strings from a mobile app (in this case an iPad) I get an error on the server. I have also downloaded this tool in an attempt to send the JSON strings: http://www.simplecomtools.com/productcart/pc/downloads/tcptesttool.zip but with the same error result. The server is reporting a "Bad request syntax" error. I've tried several different strings - the displayed errors are:
192.168.1.107 - - [13/Oct/2012 09:48:17] code 400, message Bad request syntax ("{'jsonrpc':'2.0','method':'add','params':[3,6],'id':'8'}")
192.168.1.107 - - [13/Oct/2012 09:48:17] "{'jsonrpc':'2.0','method':'add','params':[3,6],'id':'8'}" 400 -
192.168.1.107 - - [13/Oct/2012 09:49:44] code 400, message Bad request syntax ('{"jsonrpc":"2.0","method":"add","params":[3,6],"id":"8"}')
192.168.1.107 - - [13/Oct/2012 09:49:44] "{"jsonrpc":"2.0","method":"add","params":[3,6],"id":"8"}" 400 -
192.168.1.107 - - [13/Oct/2012 09:50:49] code 400, message Bad request syntax ('{"jsonrpc":"2.0","method":"add","params":{"x":3,"y":6},"id":"8"}')
192.168.1.107 - - [13/Oct/2012 09:50:49] "{"jsonrpc":"2.0","method":"add","params":{"x":3,"y":6},"id":"8"}" 400 -
192.168.1.107 - - [13/Oct/2012 17:11:59] code 400, message Bad request syntax ("{'jsonrpc':'2.0', 'method':'add', 'params':{'x':3,'y':6}, 'id':8}")
192.168.1.107 - - [13/Oct/2012 17:11:59] "{'jsonrpc':'2.0', 'method':'add', 'params':{'x':3,'y':6}, 'id':8}" 400 -
I really have no idea why the server would think the request syntax is bad, and I feel a little silly even asking the question. Any ideas on what I could try to solve the syntax error?
In message 1 and 4, your client is not actually sending JSON; it is using ' to denote string boundaries, instead of ". While single quotes are supported by some JSON implementations, they are invalid according to the standard. Correct your client implementation to send actual JSON with "-delimited strings.
But the main problem is that you're not wrapping your messages into HTTP POST requests, but sending them raw. A proper JSONRPC request looks like:
POST / HTTP/1.0
Content-Length: 71
{"jsonrpc": "2.0", "params": [3, 6], "id": "er5qtdbz", "method": "pow"}
, but you're sending just the last line.
In Python, you can send a valid request with the following example program:
import json
try:
from urllib.request import urlopen
except ImportError: # Python<3
from urllib2 import urlopen
req = {"jsonrpc":"2.0","method":"add","params":[3,6],"id":0}
req_data = json.dumps(req).encode('utf-8')
u = urlopen('http://localhost:8080/', req_data)
print(u.read())
Related
I am trying to connect to a Confluence page using the python wrapper on the API (as I am not familiar with any of this) but I keep getting the following error:
requests.exceptions.HTTPError: 401 Client Error
I know that people talk about this being caused by the necessity of using an API token but the page runs on an old version of Confluence and I have been told that we cannot use access tokens.
So has anyone any other idea? Here's a small code:
from atlassian import Confluence
confluence = Confluence(
url='https://address',
username='name',
password='pwd'
)
confluence.create_page(
space='Test',
title='A title',
body='something')
I have tried to use an older version of atlassian-python-api just in case there was some conflict but it got me the same error.
Your code looks ok. Authenticating to Confluence using Basic Auth should work without generating an API token, afaik.
The 401 status definitely suggests a problem with the authentication though. The obvious reason for this would be of course wrong credentials, but I assume that you have double checked that the credentials work when interactively logging into confluence with a browser.
To get a better sense of the error, you can import logging to debug your requests and response:
from atlassian import Confluence
import logging
logging.basicConfig(filename='conf_connect.log', filemode='w', level=logging.DEBUG)
try:
c = Confluence(url='https://conf.yoursystem.com', username='name', password='pwd')
# atlassian API does not raise error on init if credentials are wrong, this only happens on the first request
c.get_user_details_by_username('name')
except Exception as e:
logging.error(e)
The Confluence module internally also uses logging, so the requests and responses will appear in your conf_connect.log logfile:
DEBUG:atlassian.rest_client:curl --silent -X GET -H 'Content-Type: application/json' -H 'Accept: application/json' 'https://conf.yoursystem.com/rest/api/user?username=name'
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): conf.yoursystem.com:443
DEBUG:urllib3.connectionpool:https://conf.yoursystem.com:443 "GET /rest/api/user?username=name HTTP/1.1" 401 751
DEBUG:atlassian.rest_client:HTTP: GET rest/api/user -> 401
DEBUG:atlassian.rest_client:HTTP: Response text -> <!doctype html><html lang="en"><head><title>HTTP Status 401 – Unauthorized</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 401 – Unauthorized</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Basic Authentication Failure - Reason : AUTHENTICATED_FAILED</p><p><b>Description</b> The request has not been applied because it lacks valid authentication credentials for the target resource.</p><hr class="line" /><h3>Apache Tomcat/9.0.33</h3></body></html>
ERROR:root:401 Client Error: for url: https://conf.yoursystem.com/rest/api/user?username=name
The response body may include some information on the reason:
HTTP Status 401 – UnauthorizedType Status ReportMessage Basic Authentication Failure - Reason : AUTHENTICATED_FAILEDDescription The request has not been applied because it lacks valid authentication credentials for the target resource.
The reason AUTHENTICATED_FAILED suggests something is likely wrong with your credentials. If you want to dig deeper into that, you can use this SO answer to also display the headers that are being sent with your request.
However, if your reason is AUTHENTICATION_DENIED the problem is likely the following: If you have too many failed authentication attempts in a row, a CAPTCHA challenge is triggered, and this error will occur until the Failed Login Count is reset. This can easily happen when you are developing a script and test it frequently. To remedy this, either open a browser and manually (re-)logon to Confluence, completing the CAPTCHA, or resolve it from the Confluence User Management.
I want to understand what gives rise to the 11200 HTTP retrieval error? I've sent the response to the POST request to DialogFlow, shouldn't it be handling sending this response to Twilio?
Here's what I've done until now
I've setup a local python server, and exposed the localhost using a ngrok. The idea is to create a weather bot using Twilio Programmable SMS. The initial message to Twilio is forwarded to DialogFlow, which then sends a post request to my python server. I then process this request, and get the relevant weather information from OpenWeatherMap API. Being relatively new to server dev, I assume I then need to send a response with the right structure as mentioned in the DialogFlow guidelines (include fulfillmentText parameter for eg.) back to DialogFlow, which then should send the response to Twilio and that should show up on my WhatsApp Twilio Sandbox.
** But what I get is a 11200 HTTP retrieval failure error in the Twilio Degugger, I wanted to understand if I'm sending the Data to DialogFlow correctly and what gives rise to this error** I read the documentation for the error on Twilio's website but that didn't help me much in understanding the problem in my case.
I had tried the same program using a PHP server, and it worked perfectly fine. I just wanted to recreate the program using a Python server, since I'm more comfortable using it for the time being.
// DO post method of webhook.py
def do_POST(self):
try:
content_len = int(self.headers.get('Content-Length'))
post_body = self.rfile.read(content_len)
requestjson = json.loads(post_body)
city = requestjson["queryResult"]["parameters"]["geo-city"]
if city:
print(city)
info = getWeatherInformation(city)
print(info) # Prints temp in city and weather condition successfully
self.send_response(200)
self.wfile.write(info.encode(encoding = "utf_8"))
info variable is returned in the following manner from getWeatherInformation
res = {"fulfillmentText":response}
info = json.dumps(res)
return info
Console debug statements for city Melbourne
Web Server running on port: 8080
Melbourne
{"fulfillmentText": "It is 31.29 degrees with clear sky"}
127.0.0.1 - - [27/Jan/2019 23:00:34] "POST /webhook.py HTTP/1.1" 200 -
PHP Webhook code from a blog post that works correctly
/
* Part of the code that sends weather data response to Dialogflow
*/
function sendFulfillmentResponse($temperature, $weatherDescription)
{
$response = "It is $temperature degrees with $weatherDescription";
$fulfillment = array(
"fulfillmentText" => $response
);
echo(json_encode($fulfillment));
}
I expect to see a response from the Twilio Sandbox account on WhatsApp, similar to when I created the server using PHP. Instead I get the 11200 error in Twilio Debugger, but no errors in the Server Terminal.
I've been getting some weird http requests on my AWS server. I run a python3/flask v0.12 web server on it.
Does anyone know if I should be worried about the requests below?
Is there anyway to automatically reject old http requests (e.g. http/0.8 or http/0.9) using flask?
77.72.83.21 - - [18/Mar/2018 22:46:32] "╚ *%à Cookie: mstshash=Test" HTTPStatus.BAD_REQUEST -
77.72.83.21 - - [18/Mar/2018 22:46:34] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00*%à\x00\x00\x00\x00\x00Cookie:')
77.72.83.21 - - [18/Mar/2018 22:46:34] "╚ *%à Cookie: mstshash=Test" HTTPStatus.BAD_REQUEST -
213.202.230.144 - - [19/Mar/2018 11:11:00] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
213.202.230.144 - - [19/Mar/2018 11:11:00] "╚ /*à Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
I've written a simple API call using requests and am getting an error 400 on executing the call. Can someone please tell me where I am going wrong? Thanks for the help. Here's the code i wrote -
import requests
params={
'api_key':'gozbsSP1fxqNSS5YjcFM7qcjjKch1tBB',
'api_secret':'HklHJCzfO87YyIC9DudGArVKJtioEhbO',
'image_url':'http://picz.in/data/media/7/study-in-canada-students.jpg'
}
r = requests.post(url='https://api-
us.faceplusplus.com/facepp/v3/detect',data=params)
print(r)
400 error code basically means it's a bad request. So it can be that you provided the wrong params for the api, or the api_key or api_secret is not correct.
Check the documentation of the API whether you are sending all the required params are there or not. If so check your secret keys and make sure it's the correct one.
Remeber to never post you API Keys on public forums like SO...
400 means its a bad request: the request you made is not what the server wanted.
(invalid arguments, wrong payload data, etc)
More info on 400 errors here:
https://airbrake.io/blog/http-errors/400-bad-request
The 400 Bad Request Error is an HTTP response status code that indicates that the server was unable to process the request sent by the client due to invalid syntax
Sometimes the response object will include information on why the request failed, but that's not always the case.
I wrote my own custom client which sends raw http requests via my wifi card to my flask webserver.
This is what a typical requests looks like:
Content-Length: 214
User-Agent: blah
Connection: close
Host: 1.2.3.4:5000
Content-Type: application/json
{"data":[{"scoutId":2,"message":"ph=5.65"},{"scoutId":4,"message":"ph=4.28"},{"scoutId":3,"message":"ph=4.28"},{"scoutId":2,"message":"ph=5.65"},{"scoutId":4,"message":"ph=4.28"},{"scoutId":3,"message":"ph=4.30"}]}
Sometimes, my clients screw up and send malformed JSON requests to my flask server. Typically, flask will just display:
1.2.3.5 - - [01/Sep/2014 22:13:03] "POST / HTTP/1.1" 400 -
and nothing informative about the request.
I would like to track every single request that resulted in 400 in my environment and analyze what is causing these errors.
Where can I place my custom error function in my flask server?
Try turning this on:
app.config['TRAP_BAD_REQUEST_ERRORS'] = True
This should make flask raise an exception instead of just logging the 400 (see documentation here).
If you need to do something more than that, make an event handler:
http://flask.pocoo.org/docs/0.10/patterns/errorpages/
#app.errorhandler(400)
def page_not_found(exc):
#do something with the exception object `exc` here
....
Or try wrapping the body of your view function in try/except.