1

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?

Community
  • 1
  • 1
Jack tileman
  • 813
  • 2
  • 11
  • 26

1 Answers1

1

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)
Josh J
  • 6,813
  • 3
  • 25
  • 47
  • Thanks Josh. that's exactly what I ended up doing. I moved the method GetProgramList outside Webapp2, so it can be accessed by both Cloudendpoint and the Webapp2 application. – Jack tileman Dec 13 '15 at 18:35
  • In another [thread](http://stackoverflow.com/a/7461868/1010947) @moraes says: > Never use set_globals() outside of tests. Is it safe? I have the same situation and want to interact with an webapp2 class. – Rafael Soares - tuelho Jan 04 '16 at 11:12
  • Ok, the context there was unit tests. But the approach here seems to be the same. – Rafael Soares - tuelho Jan 04 '16 at 11:18
  • @Tuelho if you need to call something from a `webapp2` handler from somewhere outside of `webapp2`, then that should be a red flag telling you to decouple the code from `webapp2`. – Josh J Jan 04 '16 at 14:44
  • 1
    Yep! In my case I would like to use `webapp2.uri_for()` utility inside my endpoint. – Rafael Soares - tuelho Jan 04 '16 at 16:06
  • @Tuelho Is this another question? If so you should make a new post about it. – Josh J Jan 04 '16 at 17:41