0

I want to POST three values to a localhost server, but apparently always have missing values. If I do the whole thing with Postman, everything is working, although I use the exact same header, and the exact same body.

I tried to leave the header away as a whole and make the values of the body static and user controlled. I also searched for other HTTP POST problems with python that people have.

Server code:

import json
from urllib.parse import urlparse
import requests
from flask import Flask, jsonify, request

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
values = request.get_json(force=True)

# Check that the required fields are in the POST'ed data
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
    return 'Missing Values', 400

# Create a new Transaction
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201

Client code:

import urllib.request
import requests

if user_input == "-s" != "--send":
    send_recipient = input("Please enter the address of the recipient: ")
    send_amount = input("Please enter the amount you want to send: ")
    node_identifier = 12345678

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    r = requests.post("http://localhost:5000/transactions/new", data={'sender': node_identifier, 'recipient': send_recipient, 'amount': send_amount}, headers=headers)

In the server console, I always get code 400, instead of 201. When I use Postman, everything works out and the 201 shows up.

Matthias G.
  • 61
  • 1
  • 11
  • What do you see if you try `print(values)` in your `server.py`? – sphoenix Jun 18 '19 at 10:12
  • Just the normal, sorry I don't know how to print the values on a server running on flask: 127.0.0.1 - - [18/Jun/2019 12:16:30] "POST /transactions/new HTTP/1.1" 400 - – Matthias G. Jun 18 '19 at 10:17
  • Also, in your `server.py`, I believe you can try, `headers = 'Content-Type': 'application/json; charset=utf-8'` – sphoenix Jun 18 '19 at 10:17
  • If you encode the data as `json` and use it as headers then you can decode the data with `request.get_json` – sphoenix Jun 18 '19 at 10:33
  • I used the header you mentioned, but the `request.get_json` still doesn't work. – Matthias G. Jun 18 '19 at 10:37

1 Answers1

1

Use values = request.form instead request.get_json,

LOG:

ImmutableMultiDict([('sender', '12345678'), ('recipient', 'ab'), ('amount', 'ab')])

127.0.0.1 - - [18/Jun/2019 12:20:41] "POST /transactions/new/ HTTP/1.1" 201

More info: How to get data received in Flask request

You can test with Postman too like this: Postman test

NBlack
  • 306
  • 1
  • 7
  • No, I just posted a snippet. node_identifier can be any number. I'll quickly edit it. – Matthias G. Jun 18 '19 at 09:58
  • Ironically, Postman doesn't work anymore now. But postman isn't what I want anyway, so thank you! – Matthias G. Jun 18 '19 at 10:26
  • 1
    Remember to attach your data in Body tag / using x-www-form-urlencoded. Tested and working. (Updated with photo) – NBlack Jun 18 '19 at 10:30
  • Thanks! Until now I used the Body Tag / raw and now everything is working!! – Matthias G. Jun 18 '19 at 10:46
  • Probably you was sending RAW JSON formed. Read about send data in JSON: https://www.geeksforgeeks.org/working-with-json-data-in-python/ Different encapsulation or object, different way of use ;) – NBlack Jun 18 '19 at 11:32