简体   繁体   中英

Python sending and receiving HTTP POST

I am in the process of learning Python and I am trying to do something really simple: send an HTTP POST from one application and receive it in the other, not only I can't get it to work, I can't get it to work with what would seem reasonable, using def post(self). This is the code I have, which doesn't give errors, but doesn't do the task either: Sender Application:

import cgi
import webapp2
import urllib
import urllib2
import json

from google.appengine.api import urlfetch
from google.appengine.ext import webapp

senddata = {}
senddata["message"] = 'Testing the Sender'


class MainPagePost(webapp2.RequestHandler):

    def get(self):
        txt_url_values = urllib.urlencode(senddata)
        txturl = 'http://localhost:10080'
        result = urllib.urlopen(txturl, txt_url_values)
        self.redirect('http://localhost:10080') 

application = webapp2.WSGIApplication([
    ('/', MainPagePost), 
], debug=True)

Recieving Application:

import cgi
import webapp2
import urllib
import urllib2
import json

from google.appengine.api import urlfetch
from google.appengine.ext import webapp

class MainPageGet(webapp2.RequestHandler):

    def get(self):
        self.response.write('you sent:')
        con = self.request.get("message")
        self.response.write(con)

application = webapp2.WSGIApplication([
    ('/', MainPageGet), 
], debug=True)

All I get on the localhost is "you sent:" :( Worst of all I don't understand why both defs need to be "get(self)" so that I don't get 405 error... Thanks all :)

This is the "new" code, for the sender no change:

import cgi
import webapp2
import urllib
import urllib2
import json

from google.appengine.api import urlfetch
from google.appengine.ext import webapp

senddata = {}
senddata["message"] = 'Testing Tester'


class MainPagePost(webapp2.RequestHandler):

    def get(self):
        txt_url_values = urllib.urlencode(senddata)
        txturl = 'http://localhost:10080'
        result = urllib.urlopen(txturl, txt_url_values)
        self.redirect('http://localhost:10080') 

application = webapp2.WSGIApplication([
    ('/', MainPagePost), 
], debug=True)

The receiver I changed to post, as Sam suggested, but I am getting 405:

# -*- coding: utf-8 -*-
import cgi
import webapp2
import urllib
import urllib2
import json

from google.appengine.api import urlfetch
from google.appengine.ext import webapp

class MainPageGet(webapp2.RequestHandler):

    def post(self):
        # self.response.write('you sent:')
        con = self.request.get("message")
        self.response.write('you sent: ' + con)

application = webapp2.WSGIApplication([
    ('/', MainPageGet), 
], debug=True)

Thanks :)

Your last comments mentions 3 points of contact:

  • application-1 responding to GET requests POSTing to application-2
  • application-2 responding to POST requests POSTing to application-3
  • application-3 responding to POST requests showing responses to screen

If you must have all the work and message passing take place on the server side, I would suggest using App Engine's URL Fetch service from application-1 to issue a POST request to application-2 followed by a POST request to application-3 . This is because you cannot reliably redirect from application-2 to application-3 with a server-initiated POST request based on how most browsers implement redirection .

Server-side example

# Application 1
import webapp2
import urllib
from google.appengine.api import urlfetch

url_app_2 = 'http://application-2.com/'
url_app_3 = 'http://application-3.com/'

class MainPage(webapp2.RequestHandler):
  def get(self):
    data_to_post = {
      'message': 'Important data to pass on'
    }
    encoded_data = urllib.urlencode(data_to_post)
    # Send encoded data to application-2
    result = urlfetch.fetch(url_app_2, encoded_data, method='POST')

    data_to_post = {
      'message': result.content
    }
    encoded_data = urllib.urlencode(data_to_post)
    # Send encoded application-2 response to application-3
    result = urlfetch.fetch(url_app_3, encoded_data, method='POST')

    # Output response of application-3 to screen
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write(result.content)

app = webapp2.WSGIApplication([
  ('/', MainPage),
], debug=True)


# Application 2
import webapp2

response_template = 'The message sent was:\n{0}'

class MainPage(webapp2.RequestHandler):
  def post(self):
    message = self.request.get('message')
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write(response_template.format(message))

app = webapp2.WSGIApplication([
  ('/', MainPage),
], debug=True)


# Application 3
import webapp2

class MainPage(webapp2.RequestHandler):
  def post(self):
    message = self.request.get('message')
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write(message)

app = webapp2.WSGIApplication([
  ('/', MainPage),
], debug=True)

The major downside to this is the initial GET request will not receive a response until both sequential POST requests have returned. This risks high response times.

Client side example

This version could be accomplished using XMLHttpRequest from the client. The advantage here is that the client gets an immediate response from the initial GET request while the subsequent POST requests are treated in the client's browser. application-2 and application-3 should serve responses in the same way. Only application-1 changes and would simply need to serve the following HTML and Javascript to the client as in this example .

Check this example :

self.response.write("<html><body><p>Hi there!</p></body></html>")

The response buffers all output in memory, then sends the final output when the handler exits. webapp2 does not support streaming data to the client.

so basically, response.write must be the last thing you call:

def get(self):            
        con = self.request.get("message")
        self.response.write("you sent: " + con )

Also, I suggest you check this link to read more about POST and GET requests with forms on Appengine. I don't understand what you're trying to do with those two views, but they clash with each other

I'm a newbie too. Learning Python from last weekend and your question has been a reference for my learning.

The sending app

============================

import webapp2
import urllib
import urllib2
import json
import os
import random
import time
i=0


class MainHandler(webapp2.RequestHandler):
    def get(self):

        url = "http://localhost:12080/"


        response = urllib2.urlopen(url)
        html_string = response.read()
        self.response.write(html_string)
        self.response.write(os.environ.get("HTTP_USER_AGENT", "N/A"))
        self.response.write(random.uniform(1,10))

        """


        while True:
            self.post()
            global i
            i+=1
            time.sleep(2)

        """




    def post(self):

        url = "http://localhost:12080/receive"

        name = random.uniform(1,10)
        post_data_dictionary = {'name':str(name), "age":i, "favorite OS":"Ubuntu"}
        http_headers = {'User-Agent':'OWN'}
        post_data_encoded = urllib.urlencode(post_data_dictionary)
        request_object = urllib2.Request(url, post_data_encoded,http_headers)
        response = urllib2.urlopen(request_object)



app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

The receiving app

import webapp2

import cgi
import webapp2
import urllib
import urllib2
import json

from google.appengine.api import urlfetch
from google.appengine.ext import webapp
from google.appengine.ext import db
import os

class Message(db.Model):
    msg=db.StringProperty()
    #user_agent=db.StringProperty()
    age=db.StringProperty()
    fOS=db.StringProperty()
    useragent=db.StringProperty()


class Receive(webapp2.RequestHandler):
    #def get(self):
        #self.response.write('Rececive!')
        #self.post()

    def post(self):
        var1 = self.request.get("name")
        var2 = self.request.get("age")
        var3 = self.request.get("favorite OS")
        var4 = os.environ.get("HTTP_USER_AGENT")





        mes=Message()
        mes.msg=var1
        mes.age=var2
        mes.useragent=var4
        mes.fOS=var3



        mes.put()
        #self.response.write('you sent: ' + con)

class MainHandler(webapp2.RequestHandler):
    def get(self):

        #req=datastore.RunQueryRequest()
        #gql_query= req.gql_query

        self.response.write(os.environ.get("HTTP_USER_AGENT"))








        #a=Message()







app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/receive', Receive)
        ], debug=True)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM