Search code examples
jquerypythoncherrypy

Cherrypy Not exposing method


My code is below:

import cherrypy as cp
import numpy as np
import pandas as pd
import os
import simplejson
import sys
import operator
global pagearray
global timearray
global state
timearray = np.load("buyertimearray.npy")
pagearray = np.load("buyerpagearray.npy")
state = "All"
MAX_WEBSITES = 10
DIR = os.path.abspath(".")

class Main(object):
    @cp.expose
    def index(self):
        return open(os.path.join(DIR+"/client/", 'index.html'))

    @cp.expose
    def refresh(self, starttime, endtime):
        global pagearray
        global timearray
        starttime = int(starttime)
        endtime = int(endtime)
        if state == "Buyers":
            pagearray = np.load("buyerpagearray.npy")
        elif state == "All":
            pagearray = np.load("allpagearray.npy")
        newpagearray =[]
        for i in np.argsort(timearray):
            newpagearray += [pagearray[i]]
        pagearray = newpagearray
        timearraysorted = np.sort(timearray)
        i=1
        startindex = 0
        endindex = 0
        while len(timearraysorted)-1 > i and starttime > int(timearraysorted[i]):
             startindex = i
             i+=1
        while len(timearraysorted)-1 > i and endtime > int(timearraysorted[i]):
             endindex = i
             i+=1
        pagearray = pagearray[startindex:endindex]

        startingpages = []
        if not pagearray:
            returnvaluelist = []
            weight = []
        else:
            for i in pagearray:
                if(i):
                    startingpages+=[i[0]]
            x = build_dict(startingpages)
            sorted_x = sorted(x.items(), key=operator.itemgetter(1), reverse=True)
            totalelements = len(pagearray)
            returnvaluelist = []
            weight = []
            for i in sorted_x:
                returnvaluelist += [i[0]]
                weight += [(i[1]/(totalelements*1.0))*100]
        return simplejson.dumps({"startingvalues":returnvaluelist, "weight":weight})

    @cp.expose
    def initialize(self):
        global pagearray
        global timearray
        global state
        pagearray = np.load("allpagearray.npy")
        timearray = np.load("alltimearray.npy")
        state = "All"
        firstwebsites = []
        firstwebsitepercentage = []
        totalvisitsfirst = np.sum(first)
        lastwebsites = []
        lastwebsitepercentage = []
        totalvisitslast = np.sum(last)
        for i in sorted_first[-49:]:
            firstwebsites += [vs.site[i]]
            firstwebsitepercentage += [(first[i]/totalvisitsfirst)*100]
        for i in sorted_last[-49:]:
            lastwebsites += [vs.site[i]]
            lastwebsitepercentage += [(last[i]/totalvisitsfirst)*100]
        return simplejson.dumps({"firstID":sorted_first[-49:].tolist(), "firstWebsites":firstwebsites, "firstPercentage":firstwebsitepercentage, "lastID":sorted_last[-49:].tolist(), "lastWebsites":lastwebsites, "lastPercentage":lastwebsitepercentage})

    @cp.expose
    def getPopLinks(self, siteId, direction):
        websiteArray = []
        siteId = float(siteId)
        if direction == "forward":
            rawcolumn = freq[:,siteId]
            sorted_column = np.argsort(freq[:,siteId])
        if direction == "backward":
            rawcolumn = freq[siteId,:]
            sorted_column = np.argsort(freq[siteId,:])
        websiteIDArray = sorted_column[-49:]
        sum_raw = np.sum(rawcolumn)
        percentages = []
        for i in websiteIDArray:
            percentages += [(rawcolumn[i]/sum_raw)*100]
            websiteArray += [vs.site[i]]
        return simplejson.dumps({"ids":websiteIDArray.tolist(), "websites":websiteArray, "percentages":percentages})

    @cp.expose
    def getUserPath(self, website):
        subpagearray = []
        possibilities = []
        global pagearray
        print pagearray
        for i in pagearray:
            try:
                print i[0]
                if website==i[0]:
                    subpagearray += [i[1:]]
                    possibilities+= [i[1]]
            except IndexError:
                print "IndexError!"
                pass
        x = build_dict(possibilities)
        sorted_x = sorted(x.items(), key=operator.itemgetter(1), reverse=True)
        pagearray = subpagearray
        totalelements = len(pagearray)
        returnvaluelist = []
        weight = []
        for i in sorted_x:
            returnvaluelist += [i[0]]
            weight += [(i[1]/(totalelements*1.0))*100]
        print returnvaluelist, weight
        return simplejson.dumps({"returnvaluelist":returnvaluelist, "weight":weight})

        @cp.expose
        def swap(self):
            global pagearray
            global timearray
            global state
            if state == "Buyers":
                pagearray = np.load("allpagearray.npy")
                timearray = np.load("alltimearray.npy")
                state = "All"
            else:
                pagearray = np.load("buyerpagearray.npy")
                timearray = np.load("buyertimearray.npy")
                state = "Buyers"


def build_dict(a_list=None):
    if a_list is None:
        a_list = []
    site_dict = {}
    for site in a_list:
        try:
            site_dict[site] = site_dict[site] + 1
        except KeyError:
            site_dict[site] = 1
    return site_dict


if __name__ == "__main__":
    vs = pd.read_pickle('violet_sitemap.pkl')
    filez = np.load('freq_last_first.txt')
    freq = filez['vs_array']
    last = filez['lp_array']
    first = filez['fp_array']
    sorted_first = np.argsort(first)
    sorted_last = np.argsort(last)
    cp.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port':80})
    cp.quickstart(Main())

The issue is when I'm calling /getUserPath in the javascript via jQuery, it is returning a 404 error saying /getUserPath doesn't exist, which doesn't make sense because everything is exposed and going to the actual url

www.serverurlhere.com/getUserPath?website=http://otherurlhere.com/

shows there is a payload returning and the payload is valid and correct. The Javascript is 100% correct because the only file I changed in between when it was working and when it wasn't was this file. Why is a 404 coming up? This doesn't make any sense to me because all I did was add a single method to this file and it broke (the swap method). The website shows up, everything else works, but the /getUserPath part is just broken. Is there a limit to the number of methods in a cherrypy server? I'm very ignorant when it comes to cherrypy, and it could very well be a limitation with cherrypy. I googled around and couldn't find anything else like this... I just don't understand what could have happened here...

Thanks,

F


Solution

  • The answer to this question is to have the same argument name for the method signature with the query string parameter that was send from javascript. CherryPy cares about the argument name and the parameter that receives.

    From the comments on the question.

    I figured it out! Thanks for your help! Turns out it was a really stupid bug. Everything is working fine but i changed the name of the variable being passed into getUserPath to the name "website" from the name "input" and when the POST request was happening, cherrypy 404's when it receives something other than the exact variable name.