0

I am trying to send data to a URL. I've a code to send it for each cpu on my Mac. But the current code loops through each of the cpustats and sends them 1 after the other. I need to send all of them in 1 POST 'cycle' but it should be formatted such that it sends it like this -

cpuStats = {nice: 123.0, idle:123.0....}
cpuStats = {nice: 123.0, idle:123.0....}
cpuStats = {nice: 123.0, idle:123.0....}

and so on...

Further, the current code pulls the stats from my Mac (with a '200 OK' for each cpustat) but when I run it on Linux, Windows, it just returns the prompt without giving any errors or stats. My guess is that it has to do with the 'break' at 'socket.error:' (My Mac has 4 cpus but the Linux and Windows machines on which I test it have 1 each.

import psutil 
import socket
import time
import sample
import json
import httplib
import urllib

serverHost = sample.host
port = sample.port

thisClient = socket.gethostname()
currentTime = int(time.time())
s = socket.socket()
s.connect((serverHost,port))
cpuStats = psutil.cpu_times_percent(percpu=True)


def loop_thru_cpus():
    global cpuStats
    for stat in cpuStats:
        stat = json.dumps(stat._asdict())

        try:

            command = 'put cpu.usr ' + str(currentTime) + " " + str(cpuStats[0]) + "host ="+ thisClient+ "/n"
            s.sendall(command)
            command = 'put cpu.nice ' + str(currentTime) + " " + str(cpuStats[1]) + "host ="+ thisClient+ "/n"
            s.sendall(command)
            command = 'put cpu.sys ' + str(currentTime) + " " + str(cpuStats[2]) + "host ="+ thisClient+ "/n"
            s.sendall(command)
            command = 'put cpu.idle ' + str(currentTime) + " " + str(cpuStats[3]) + "host ="+ thisClient+ "/n"
            s.sendall(command)

            params = urllib.urlencode({'cpuStats': stat, 'thisClient': 1234})
            headers = headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
            conn = httplib.HTTPConnection(serverHost, port)
            conn.request("POST", "", params, headers)
            response = conn.getresponse()
            print response.status, response.reason

        except IndexError:
            continue
        except socket.error:
            print "Connection refused"
            continue

    print stat

loop_thru_cpus()
s.close()
3
  • Are you trying to send a POST with all of the data at once, or are you trying to send four POST requests at once? Commented Sep 12, 2013 at 2:35
  • @SlaterTyranus, should be the first one Commented Sep 12, 2013 at 2:37
  • @SlaterTyranus - I have to send just 1 POST request that includes all the cpus. Commented Sep 12, 2013 at 3:01

1 Answer 1

2

If you're just trying to send the data all at once you should realize that you're not actually sending a dictionary across, but instead you're sending a string. In that case, you could easily send all the data in one go by just constructing your data like so:

data = "\n".join([json.dumps(stat._asdict()) for stat in cpuStats])

If that endpoint is someone else's that might not be sensible, but assuming that's your own endpoint you're pointing at it should be pretty trivial to unbundle this data.

Additionally I would HIGHLY suggest switching to the requests module over urllib as it extends all of the same functionality in a MUCH easier wrapper. For instance, in requests you would send that request by doing the following:

import requests

response = requests.post("your://url.here", data=data)
print response.content
Sign up to request clarification or add additional context in comments.

2 Comments

Thx. I have to work with built-in libraries and therefore am not using 'requests'. The stats will be posted on the server which is used by others as well and so I have to send it in the format. If it helps, here's the instructions I got - "one params line params = urllib.urlencode({'cpuStats': statJson, 'deviceKey': 1234}) should have cpuStats repeated with appropriate value for each cpu and it shouldnt be that you have to send the request again. It all should be part of one single http POST request."
@user2480526 that is in fact in line with this response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.