Pregunta

Tengo decorador:

http = httplib2.Http()
service = discovery.build('gmail', 'v1', http=http)
# Creating decorator for OAuth2 account.
decorator = appengine.oauth2decorator_from_clientsecrets(
    CLIENT_SECRETS,
    scope='https://www.googleapis.com/auth/gmail.readonly',
    message=MISSING_CLIENT_SECRETS_MESSAGE)

y clase que lo usan:

class CSVGeneratorHandler(webapp2.RedirectHandler):
    @decorator.oauth_required
    def get(self):
        http = decorator.http()
        first_messages = service.users().messages().list(userId='me').execute(http=http)
        template = JINJA_ENVIRONMENT.get_template('templates/success.html')
        self.response.write(template.render({}))

que funciona muy bien.

Pero cuando intento mover la solicitud de API service.users (). Mensajes (). Lista (UserID= 'yo'). Ejecutar (http= http) a la tarea (con diferidos.diferir (get_mails)) Tengo un error: "Iniciar sesión requerido".

Entiendo que la función Get_mails debe recibir contexto o credenciales del programa principal.Pero no entiendo cómo hacer eso.

¿Puede alguien ayudarme?

¿Fue útil?

Solución

Después de unas pocas horas encontré la respuesta.

En primer lugar, necesita guardar las credenciales en algún lugar.Porque nosotros, gae, tenemos un tipo de campo especial para ello:

from oauth2client.appengine import StorageByKeyName  
from google.appengine.ext import db

class CredentialsModel(db.Model):
  credentials = CredentialsProperty()

El siguiente paso es configurar autenticación sin decorador y solo después de esa tarea de enviar a la cola:

    user = users.get_current_user()
    flow = flow_from_clientsecrets(os.path.join(os.path.dirname(os.path.realpath(__file__)), CLIENT_SECRETS),
                           scope='https://www.googleapis.com/auth/gmail.readonly',
                           redirect_uri='http://127.0.0.1:8080/success')
    auth_uri = str(flow.step1_get_authorize_url())
    code = self.request.get('code')
    if not code:
        return self.redirect(auth_uri)
    credentials = flow.step2_exchange(code)

    storage = StorageByKeyName(CredentialsModel, user.user_id(), 'credentials')
    storage.put(credentials)

    deferred.defer(get_mails, user.user_id())

¡No se olvide de obtener credenciales en la función diferida!

def get_mails(user_id):
    storage = StorageByKeyName(CredentialsModel, user_id, 'credentials')
    credentials = storage.get()

    http = httplib2.Http()
    http = credentials.authorize(http)

    all_messages = []
    service = discovery.build('gmail', 'v1', http=http)
    first_messages = service.users().messages().list(userId='me').execute()

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top