studio holidays google create python google-calendar-api google-api-python-client

holidays - Google Calendar API v3: cómo obtener un token de actualización(Python)



google calendar holidays api (4)

Las respuestas parecen estar obsoletas a partir del 2017-06-16 .

  • prospección de approval_prompt está en desuso
  • prompt=force no es valido

Aquí hay un ejemplo de trabajo:

from oauth2client.client import OAuth2WebServerFlow flow = OAuth2WebServerFlow( client_id=CLIEN_ID, client_secret=CLIENT_SECRET, scope=SCOPES, redirect_uri=''http://localhost/gdrive_auth'', access_type=''offline'', prompt=''consent'', ) print(flow.step1_get_authorize_url())

Estoy tratando de escribir una aplicación Django que crea eventos en un calendario específico de Google. Hasta ahora he tenido éxito. Solo hay un pequeño problema:

No sé cómo obtener un token de actualización con el cliente de Google Python.

El resultado es que después de que mi token caduque, la aplicación no funciona y tengo que crear un token nuevo. Si entiendo la documentación correcta, ahí es donde entra el token de actualización .

Los tokens de acceso tienen una duración limitada y, en algunos casos, una aplicación necesita acceder a una API de Google más allá de la duración de un token de acceso único. Cuando este es el caso, su aplicación puede obtener lo que se llama un token de actualización. Un token de actualización permite que su aplicación obtenga nuevos tokens de acceso.

Documentación de Google (ver "Pasos básicos", Sección 4)

Mi código

import gflags import httplib2 from apiclient.discovery import build from oauth2client.file import Storage from oauth2client.client import OAuth2WebServerFlow from oauth2client.tools import run FLAGS = gflags.FLAGS FLOW = OAuth2WebServerFlow( client_id=GOOGLE_API_CLIENT_ID, client_secret=GOOGLE_API_CLIENT_SECRET, scope=GOOGLE_API_CALENDAR_SCOPE, user_agent=GOOGLE_API_USER_AGENT) storage = Storage(GOOGLE_API_CREDENTIAL_PATH) credentials = storage.get() if credentials is None or credentials.invalid == True: credentials = run(FLOW, storage) http = httplib2.Http() http = credentials.authorize(http) service = build(serviceName=''calendar'', version=''v3'', http=http, developerKey=GOOGLE_API_DEVELOPER_KEY) event = { [... Dictionary with all the necessary data here ...] } created_event = service.events().insert(calendarId=GOOGLE_API_CALENDAR_ID, body=event).execute()

Esto es más o menos el ejemplo de la documentación de Google. Lo interesante es el almacenamiento . Es un archivo donde se guardan algunos datos de credenciales.

Contenido de mi archivo de almacenamiento:

{ "_module": "oauth2client.client", "_class": "OAuth2Credentials", "access_token": [redacted], "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": true, "client_id": [redacted], "client_secret": [redacted], "token_expiry": "2011-12-17T16:44:15Z", "refresh_token": null, "user_agent": [redacted] }

Debería haber un token de actualización allí, pero en su lugar es nulo . Así que me imagino que de alguna manera puedo solicitar un token de actualización .

Agradecería cualquier ayuda sobre cómo puedo hacer que esto funcione. Si necesitas más información, por favor dímelo.


No sé cómo hacer esto con el Cliente de Python o la API de Calendario (solo estoy usando una biblioteca OAuth2 de ruby ​​para acceder a la API de Contactos), pero descubrí que necesitaba solicitar el acceso "sin conexión" del usuario.

Esto se hace agregando el parámetro "access_type" con el valor "fuera de línea" a la url de autorización (a la que redirige al usuario para que haga clic en "Quiero permitir que esta aplicación acceda a mis datos").

Si haces esto, obtendrás un refresh_token en tu respuesta JSON cuando pidas tokens de acceso a google. De lo contrario, solo obtienes el token de acceso (que es válido por una hora).

Aparentemente, este requisito se agregó recientemente (y puede no estar maravillosamente documentado).

Solía ​​obtener un token de actualización sin tener que obtener un permiso específico "sin conexión".

Espero que esto te apunte en la dirección correcta.


Por lo tanto, si ya ha aceptado el consentimiento sin configurar access_type=''offline'' , debe forzar al usuario a que acepte su aplicación con acceso offline también aprobando approval_prompt=''force'' .

self.flow = OAuth2WebServerFlow( client_id=self.client_id, client_secret=self.client_secret, scope=self.SCOPE, user_agent=user_agent, redirect_uri=''urn:ietf:wg:oauth:2.0:oob'', access_type=''offline'', # This is the default approval_prompt=''force'' )

Luego puede eliminar el aviso de forzado / configurarlo en auto después de recibir el token de actualización.


Si sigue este manual https://developers.google.com/identity/protocols/OAuth2WebServer y no puede recibir refresh_token , intente agregar prompt = ''consent'' aquí:

authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type=''offline'', prompt=''consent'', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes=''true'')

Here se describe por qué puede suceder.