Forums

POSTing data to your own endpoint? - help needed

I'm trying to post data to this view, or at least get a working response:

in flask_app.py:

@app.route('/json-example', methods=['POST'])
def json_example():
    req_data = request.get_json()

    language = req_data['language']
    framework = req_data['framework']
    python_version = req_data['version_info']['python'] #two keys are needed because of the nested object
    example = req_data['examples'][0] #an index is needed because of the array
    boolean_test = req_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

then from Pyhon idle I am trying to send this json dictionary:

import requests

username = 'MadMartin'
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
host = 'www.pythonanywhere.com'

pload = {
    "language" : "Python",
    "framework" : "Flask",
    "website" : "Scotch",
    "version_info" : {
        "python" : 3.4,
        "flask" : 0.12
    },
    "examples" : ["query", "form", "json"],
    "boolean_test" : True
}


response = requests.post(
    'https://{host}/api/v0/user/{username}/json-example/'.format(
        host=host, username=username, data = pload
    ),
    headers={'Authorization': 'Token {token}'.format(token=token)}
)
if response.status_code == 200:
    print('Succes - payload delivered!2020')
    print(response.content)
else:
    print('Got unexpected status code {}: {!r}'.format(response.status_code, response.headers))

however, I end up with 404 error:

Got unexpected status code 404: {'x-xss-protection': '1; mode=block', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Server': 'PythonAnywhere', 'x-content-type-options': 'nosniff', 'Date': 'Sun, 28 Jun 2020 07:13:02 GMT', 'Content-Type': 'text/html; charset=utf-8', 'X-Frame-Options': 'SAMEORIGIN', 'Set-Cookie': 'csrftoken=vsqANIy1L8CpAjxN0wVqJHDr69gwHNTvDDF2qZdeRNcquZZDnnCsORX42snOloWc; expires=Sun, 27-Jun-2021 07:13:02 GMT; Max-Age=31449600; Path=/; Secure, sessionid=j5ps6sewhef8pkejumn2i2nfhg3ri9bg; expires=Sun, 12-Jul-2020 07:13:02 GMT; HttpOnly; Max-Age=1209600; Path=/; Secure', 'Transfer-Encoding': 'chunked', 'Referrer-Policy': 'same-origin', 'Vary': 'Accept-Encoding, Cookie'}

any ideas how to fix this? ta

You appear to be trying to post to the PythonAnywhere API, but if your view is defined in your web app, you should be using the address of your web app, not the PythonAnywhere API. The address you're looking for is probably more like https://madmartin.pythonanywhere.com/json-example/

still not quite getting it to work:

I've changed the api route to :

    response = requests.post(
        'https://madmartin.pythonanywhere.com/json-example'.format(
            host=host, username=username, data = pload
        ),
        headers={'Authorization': 'Token {token}', 'Content-type': 'application/json', 'Accept': 'text/plain'.format(token=token)}
    )

which comes up with 400 error, though seemingly giving the length of the content posted(?)

Got unexpected status code 400: {'Date': 'Sun, 28 Jun 2020 10:07:42 GMT', 'Connection': 'keep-alive', 'Server': 'PythonAnywhere', 'Content-Type': 'text/html', 'Content-Length': '187'}

if I post it to: 'https://madmartin.pythonanywhere.com/json-example/'

then it's still 404 error

also 404 for 'https://madmartin.pythonanywhere.com/json-example/post'

You do not have the trailing slash in your route definition, so don't is it in the URL. The second one will not work because there is not route for /json-example/post.

unfortunately , even without the trailing slash, it's still not quite right:

response = requests.post(
    'https://madmartin.pythonanywhere.com/json-example'.format(
        host=host, username=username, data = pload

adding this, returns this message in idle:

Got unexpected status code 400: {'Server': 'PythonAnywhere', 'Content-Length': '187', 'Content-Type': 'text/html', 'Connection': 'keep-alive', 'Date': 'Sun, 28 Jun 2020 17:06:15 GMT'}

it gives out Content-Length of 187 - is that the json dictionary I'm trying to post?

and also I think that Content-Type should be changed to JSON, yet the code isn't doing that - it seems that the syntax is not quite right when having to add in the Python Anywhere username, password and token - as this code works ok outside , ie. with httpbin.org or similar

I've also removed "website" : "Scotch", from OP as that didn't seem to fit in, still get 400 error

If you use the json parameter instead of the data parameter, requests encodes the request as json.

changing post to:

response = requests.post( 'https://madmartin.pythonanywhere.com/json-example'.format( host=host, username=username, json=pload

gives 500 error

I've found now that if I POST the dictionary to the url without adding in the username, password and api token it works fine:

ie:

import requests
import json

response = requests.post('https://madmartin.pythonanywhere.com/json-example', json={
    "language" : "Python",
    "framework" : "Flask",

    "version_info" : {
        "python" : 3.4,
        "flask" : 0.12
    },
    "examples" : ["query", "form", "json"],
    "boolean_test" : True
})
response.status_code

if response.status_code == 200:
    print('Success- payload delivered!2020')
    print(response.content)
else:
    print('Got unexpected status code {}: {!r}'.format(response.status_code, response.headers))

so I guess I was barking up the wrong tree, as I'm not using the api anyway?

next thing, is it possible to read the posted data from within the server, ie. I guess it can be saved to a file?

thanks for the help

If you get a 500 response, there will be something in the error log that gives the details of the underlying error.

Yes, you can do anything you want with the posted data -- in your first post on this thread, you've extracted all of it into variables, and you can use those.

I'm having a problem now with reading/saving data from those variables.

ie. I can POST the data, but it only seems to 'ping' the server, but not save anything to the variable.

I have this code in flask_app.py:

@app.route('/postit', methods=['GET', 'POST'])
def postit():

    req_data = request.get_json()
    language = req_data['language']
    framework = req_data['framework']
    python_version = req_data['version_info']['python'] #two keys are needed because of the nested object
    example = req_data['examples'][0] #an index is needed because of the array
    boolean_test = req_data['boolean_test']


    POST={}
    #args=sys.stdin.read()
    x = POST.get('framework')

    with open('/home/MadMartin/datapostfiles/EFL4.json', 'w') as f:
        f.write(str(x))
        f.close()


    return '''
           The framework value is: {}
           The language value is: {}'''.format(language, framework, x)

the textfile just returns 'None', and any other way of trying to save the variable just gives None as well.

So it doesn't seem to me to be actually sending anything other than some kind of code?? from Requests Post (in idle) that just checks if it lines up with what is written in the flask_app routs. Is that right?

Python script (from laptop) that does POST request to PA server:

import requests
import json

response = requests.post('https://madmartin.pythonanywhere.com/postit', json={
    "language" : "German",
    "framework" : "Flask",

    "version_info" : {
        "python" : 3.4,
        "flask" : 0.12
    },
    "examples" : ["query", "form", "json"],
    "boolean_test" : True
})
response.status_code

if response.status_code == 200:
    print('Success- payload delivered!2020')
    print(response.content)
else:
    print('Got unexpected status code {}: {!r}'.format(response.status_code, response.headers))

output in Idle after running code:

Success- payload delivered!2020
b'\n           The framework value is: German\n           The language value is: Flask'

so, how to save this output in server, either as text file or any other way?

Here you go: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files

many thanks, yes, json.dump does the trick!

with open('/home/MadMartin/datapostfiles/EFL6.json', 'w') as f:
        json.dump(req_data, f)