Search code examples
python-2.7google-app-enginegoogle-cloud-endpointswebapp2requesthandler

How to call a webapp2 method from Cloud endpoint api?


I have written a GAE application using Python.

The application has a mobile component that is being built in Android. I am using custom credentials and not using Google OAuth for authentication.

I have created a Cloudendpoint API so the application has login, using the ideas described here - Is there a way to secure Google cloud endpoints proto datastore?

Now from the Cloudendpoint API I would like to call a method from a class in GAE. Can you please help me how to structure this?

My Class / Method in the GAE is this

class GetProgramListHandler(basehandler.BaseHandler):   

    field1 = "none"
    field2 = "none"
    field3 = "none"

def date_handler(obj):
        return obj.isoformat() if hasattr(obj, 'isoformat') else obj
def post(self):
    logging.info(self.request.body)
    data_received = json.loads(self.request.body)

    field1 = data_received['field1']
    field12 = data_received['field2']
    field3 = data_received['field3']

    data_sent_obj, program_data_obj = self.get_program_list(current_center_admin_email_id, current_center_name_sent, current_user_email_id)

    return_data = []
    return_data = json.dumps({'data_sent': dict(data_sent_obj),
        'program_data':  [dict(p.to_dict()) for p in program_data_obj]},default = date_handler)

    self.response.headers['content-type']=("application/json;charset=UTF-8")
    self.response.out.write(return_data)


@classmethod
def get_program_list(request,field1,field2,field3) :
    field1 = field1
    field2 = field2
    field3 = field3 

My GAE application is a web application. My main.py has this

app = webapp2.WSGIApplication([

    webapp2.Route('/getprogramlist', getprogramlist.GetProgramListHandler, name='getprogramlist'),
], debug=True, config=config.config)

and this works fine.

The Basehandler is webapp2 RequestHanlder

import time
import webapp2_extras.appengine.auth.models
from webapp2_extras import security

class BaseHandler(webapp2.RequestHandler):
    @webapp2.cached_property
    def auth(self):
        """Shortcut to access the auth instance as a property."""
        return auth.get_auth()

My Cloudendpoint API code is this -

@endpoints.api(
    name='cloudendpoint', 
    version='v1')   
class LoginApi(remote.Service):

    MULTIPLY_METHOD_RESOURCE = endpoints.ResourceContainer(API_L_value_request)

    @endpoints.method(MULTIPLY_METHOD_RESOURCE, 
        API_L_value_response,
        path='hellogreeting', 
        http_method='POST',
        name='loginvalue.getloginvalue')
    def login_single(self, request):


        try:
            l_children_user_admin_pair_array = []
            program_list = []

            user_type_data = { 
                'user_type': "error",
                'user_email_id': "error",
                'user_check_flag': "errors"}

            if (user_type = "maskvalue"):       


                pass_credential_flag = "y"

                if pass_credential_flag == 'y':

                    # If the user_type is "super_admin" do this
                    if (user_type_data["user_type"] == "super-admin"):
                        field1 = l_children_user_admin_pair_array[0]["field1"]
                        field2 = l_children_user_admin_pair_array[0]["field2"]
                        field3 = user_type_data["field3"]

                        program_data = []

                        # program_data_obj = HOW DO I CALL get_program_list on GetProgramListHandler?

I would like to call get_program_list on GetProgramListHandler inside the CloudApi(right at the end of posted code).The Stackoverflow question here - AssertionError: Request global variable is not set seems to indicate I need to initialize the Webapp2RequestHandler. How do I do this?

Once I am inside the CloudAPI(that belongs to my Application) how do I access other class /methods that belong to the web application? Do I need to do inheritance of the Webapp Class inside my CloudAPI?


Solution

  • Sounds like your method should be decoupled from the web handler so that it can be executed from both contexts. If you cannot do that for some reason, this is how to initialize an empty webapp2 request so you can avoid some of those errors.

    # app is an instance of your webapp2.WSGIApplication
    req = webapp2.Request.blank('/')
    req.app = app
    app.set_globals(app=app, request=req)