Fixes an issue where the organization home page would throw a 505 when no projects...
[Melange.git] / thirdparty / google_appengine / google / appengine / api / apiproxy_rpc.py
blob4470b283fe5041a98dd7f9462d58d3d0b282a2b5
1 #!/usr/bin/env python
3 # Copyright 2007 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 """Base class for implementing RPC of API proxy stubs."""
24 import sys
27 class RPC(object):
28 """Base class for implementing RPC of API proxy stubs.
30 To implement a RPC to make real asynchronous API call:
31 - Extend this class.
32 - Override _MakeCallImpl and/or _WaitImpl to do a real asynchronous call.
33 """
35 IDLE = 0
36 RUNNING = 1
37 FINISHING = 2
39 def __init__(self, package=None, call=None, request=None, response=None,
40 callback=None, deadline=None, stub=None):
41 """Constructor for the RPC object.
43 All arguments are optional, and simply set members on the class.
44 These data members will be overriden by values passed to MakeCall.
46 Args:
47 package: string, the package for the call
48 call: string, the call within the package
49 request: ProtocolMessage instance, appropriate for the arguments
50 response: ProtocolMessage instance, appropriate for the response
51 callback: callable, called when call is complete
52 deadline: A double specifying the deadline for this call as the number of
53 seconds from the current time. Ignored if non-positive.
54 stub: APIProxyStub instance, used in default _WaitImpl to do real call
55 """
56 self.__exception = None
57 self.__state = RPC.IDLE
58 self.__traceback = None
60 self.package = package
61 self.call = call
62 self.request = request
63 self.response = response
64 self.callback = callback
65 self.deadline = deadline
66 self.stub = stub
68 def MakeCall(self, package=None, call=None, request=None, response=None,
69 callback=None, deadline=None):
70 """Makes an asynchronous (i.e. non-blocking) API call within the
71 specified package for the specified call method.
73 It will call the _MakeRealCall to do the real job.
75 Args:
76 Same as constructor; see __init__.
78 Raises:
79 TypeError or AssertionError if an argument is of an invalid type.
80 AssertionError or RuntimeError is an RPC is already in use.
81 """
82 self.callback = callback or self.callback
83 self.package = package or self.package
84 self.call = call or self.call
85 self.request = request or self.request
86 self.response = response or self.response
87 self.deadline = deadline or self.deadline
89 assert self.__state is RPC.IDLE, ('RPC for %s.%s has already been started' %
90 (self.package, self.call))
91 assert self.callback is None or callable(self.callback)
92 self._MakeCallImpl()
94 def Wait(self):
95 """Waits on the API call associated with this RPC."""
96 rpc_completed = self._WaitImpl()
98 assert rpc_completed, ('RPC for %s.%s was not completed, and no other ' +
99 'exception was raised ' % (self.package, self.call))
101 def CheckSuccess(self):
102 """If there was an exception, raise it now.
104 Raises:
105 Exception of the API call or the callback, if any.
107 if self.exception and self.__traceback:
108 raise self.exception.__class__, self.exception, self.__traceback
109 elif self.exception:
110 raise self.exception
112 @property
113 def exception(self):
114 return self.__exception
116 @property
117 def state(self):
118 return self.__state
120 def _MakeCallImpl(self):
121 """Override this method to implement a real asynchronous call rpc."""
122 self.__state = RPC.RUNNING
124 def _WaitImpl(self):
125 """Override this method to implement a real asynchronous call rpc.
127 Returns:
128 True if the async call was completed successfully.
130 try:
131 try:
132 self.stub.MakeSyncCall(self.package, self.call,
133 self.request, self.response)
134 except Exception, e:
135 self.__exception = e
136 finally:
137 self.__state = RPC.FINISHING
138 self.__Callback()
140 return True
142 def __Callback(self):
143 if self.callback:
144 try:
145 self.callback()
146 except:
147 exc_class, self.__exception, self.__traceback = sys.exc_info()
148 self.__exception._appengine_apiproxy_rpc = self
149 raise