Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Google Apps <3 Python?

Google Apps <3 Python?

Slides of talk by Simone Dalla on GData Python Client at EuroPython 2012 - Florence, July 4.

https://www.youtube.com/watch?v=jZj7K3r9s3k

Simone Dalla

June 18, 2014
Tweet

More Decks by Simone Dalla

Other Decks in Programming

Transcript

  1. Google Apps <3 Python? Can we put a new appointment

    on our Google Calendar with Python script? Yes, we can. Can we get the list of our Google Documents with Python script? Yes, we can. Can we create filters and labels on our Gmail account with Python script? Yes, we can. Can we add a web page to our Google Site with Python script? Yes, we can. Can we add, delete, modify users of our Goole Apps with Python script? Yes, we can. Can we integrate our Python, Django projects with Google Apps? Yes, we can. Go to show how Pyhton and Gdata library can afford to do and if Google Apps really loves Python…
  2. Simone Dalla Responsabile dei Servizi Informatici del Comune di Zola

    Predosa (BO). Programmatore Python e Django da 6 anni. Uso Python per...TUTTO! Dalle attività sistemistiche, script fino allo sviluppo di applicazioni web a 360°. Quest'anno abbiamo "migrato" il nostro sistema di groupware interno scegliendo le "Google Apps for Business" ed in questi mesi mi sono occupato delle integrazioni tra alcune nostre applicazioni interne e diverse Google Apps.
  3. Concetti di base • Google Apps (Gmail, Docs, Calendar, Sites...)

    • Api di Google • HTTP, REST, XML, AtomPub, Json • Python ;-)
  4. API di Google Molti servizi di Google offrono un accesso

    esterno ai relativi dati e funzionalità. Questo attraverso delle API basate su tecnologie REST-inspired, per leggere, scrivere e modificare informazioni "sul" web. Queste API prendono il nome di Google Apps Application APIs e Google Apps Administrative APIs (nuove) e Google Data APIs ("vecchie e deprecate"). https://developers.google.com/google-apps/
  5. GData Python Client Libreria che ci permetterà di accedere e

    utilizzare le API di Google. In pratica è una sorta di "wrapper" che ci rende "trasparente" il loro utilizzo, rispetto al tipo e versione di API e protocollo utilizzato. http://code.google.com/p/gdata-python-client/
  6. Google Apps Application APIs • Calendar API (Gdata Python Client)

    • Task API (no Gdata Python Client) • Gmail API, Email Settings (Gdata Python Client) • Contacts API (Gdata Python Client) • Documents List API (Gdata Python Client) • Spreadsheets API (Gdata Python Client) • Sites API (Gdata Python Client)
  7. Google Apps Administrative APIs Permettono di gestire i Google Apps

    Domain per migrare e/o interagire con l'esistente infrastruttura IT, gestire utenti, profili, settaggi e molto altro. • Admin Settings API (no Gdata Python Client) • Admin Audit API (no Gdata Python Client) • Email Audit API ( Gdata Python Client) • Email Migration API (Gdata Python Client) • Email Settings API (Gdata Python Client) • Provisioning API (Gdata Python Client) • User Profiles API (Gdata Python Client)
  8. Autenticazione Ci sono diversi metodi di autenticazione supportati dalle API

    di Google. Non tutte le specifiche API (in base anche alla versione) supportano però tutti i metodi. • ClientLogin ("semplice" username e password con eventuale "two step verification") • Oauth • Oauth2 (API versione 3) • AuthSub
  9. Diamo un occhio all'autenticazione... 56 provisioning_client = gdata.apps.client.AppsClient( 57 domain='example.com')

    58 provisioning_client.ClientLogin( 59 email='[email protected]', 60 password='password', 61 source='example_apps_business_source') 194 docs_client = gdata.docs.client.DocsClient() 196 docs_client.ClientLogin( 197 email='demo', 198 password='password', 199 source='example_app_source')
  10. Calendar API • elenco dei calendari • creazione, eliminazione, modifica

    di un calendario • creazione, eliminazione, modifica di una sottoscrizione ad un calendario esistente • ricerca di evento con diverse tipologie di query (tra cui full- text) • creazione (semplice), eliminazione, modifica di un evento • creazione con la modalità "quick add" di un evento • creazione di un evento ricorrente • creazione, eliminazione, modifica delle ACL degli eventi • gestione delle proprietà estese di un evento • gestione dei "reminders" e delle notifiche degli eventi
  11. Gmail API - Email Settings API Solo per utenti Google

    Apps for Business and Education. • gestione delle etichette • gestione dei filtri • gestione impostazione "Invia messaggio come" ("send-as") • gestione impostazioni di "Inoltro" ("forwarding") • gestione impostazioni di "Scarica come POP" ("POP Download") • gestione impostazione di "Accesso IMAP" ("IMAP Access") • gestione impostazioni del "Risponditore automatico" ("Out of Office AutoReply" - "Vacation Responder") • gestione impostazione della "Firma" ("Signature") • gestione impostazione della "Lingua" ("Language") • gestione impostazione di delegazione "Concedi l'accesso al tuo account" ("Grant access to your account" - "Delegation") • gestione impostazioni "Generali" ("General")
  12. Contacts API • creazione, eliminazione, modifica di un contatto •

    ricerca di contatti con diverse tipologie di query • creazione, eliminazione, modifica di un gruppo di contatti • ricerca di gruppi contatti con diverse tipologie di query • aggiunta ed eliminazione di contatti ai gruppi di contatti • gestione delle foto dei contatti
  13. Documents List API • creazione, eliminazione, "modifica" di documenti •

    upload e download di documenti • gestione dei metadati e delle revisioni dei documenti • creazione, eliminazione, "modifica" di cartelle • download di cartelle • organizzazione (creazione, spostamento, cancellazione) di documenti in cartelle • creazione, eliminazione, modifica delle ACL di documenti e cartelle • ricerca di documenti e cartelle con diverse tipologie di query tips: Documentazione ufficiale non aggiornata, guardare la documentazione dei sorgenti. Dove ogni documento è una "Resource" e ogni cartella un "Archive".
  14. Sites API • elenco, creazione, copia, "modifica" di siti e

    relativi metadati • elenco delle attività e delle revisioni dei contenuti dei siti • elenco, creazione, modifica di pagine e contenuti dei siti • ricerche di pagine e contenuti secondo la tipologia di pagina, "percorso", "full-text"... • upload e dowload di "attachment" su e dalla pagine. • creazione, eliminazione, modifica delle ACL dei siti a livello di singolo utente, gruppo o dominio
  15. Provisioning API Solo per utenti Google Apps for Business and

    Education. • elenco, creazione, aggiornamento, sospensione, riattivazione, eliminazione di utenti • elenco, creazione ed eliminazione di "nickname" • elenco, creazione, modifica di gruppi di utenti • gestione degli utenti nei relativi gruppi • gestione dell'organigramma del dominio, organizzato in "Organizations Unit"
  16. Importiamo il necessario... 2 import atom.data 3 import gdata.client 4

    import gdata.data 5 import gdata.acl.data 6 import gdata.apps.data 7 import gdata.apps.client 8 import gdata.apps.groups.client 9 import gdata.apps.groups.data 10 import gdata.apps.emailsettings.client 11 import gdata.calendar.client 12 import gdata.calendar.data 13 import gdata.docs.client 14 import gdata.docs.data 15 import gdata.sites.client 16 import gdata.sites.data
  17. Un pò di varibili... 18 GOOGLE_APPS_DOMAIN = 'comune.zolapredosa.bo.it' 19 GOOGLE_APPS_ADMIN_EMAIL

    = 'admin_test_glpy@%s' % GOOGLE_APPS_DOMAIN 21 GOOGLE_APPS_ADMIN_2STEP_CODE = 'xxxxxxxxxxxxx' 22 GOOGLE_APPS_APP_SOURCE = GOOGLE_APPS_DOMAIN + '.g_love_py' 25 GOOGLE_CALENDAR_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:00' 44 groups = ['helpdeskers', 'programmaers'] 45 users = [ 46 {'username': 'demo.glovepy.1', 'groups': ['helpdeskers', 'programmaers'], 47 'suspend': False}, 48 {'username': 'demo.glovepy.2', 'groups': ['helpdeskers',], 'suspend': True}, 49 {'username': 'demo.glovepy.3', 'groups': ['programmaers'], 'suspend': False}, ]
  18. Autentichiamoci... 56 provisioning_client = gdata.apps.client.AppsClient( 57 domain=GOOGLE_APPS_DOMAIN) 58 provisioning_client.ClientLogin( 59

    email=GOOGLE_APPS_ADMIN_EMAIL, 60 password=GOOGLE_APPS_ADMIN_2STEP_CODE, 61 source=GOOGLE_APPS_APP_SOURCE) 62 provisioning_client.ssl = True 63 64 group_client = gdata.apps.groups.client.GroupsProvisioningClient( 65 domain=GOOGLE_APPS_DOMAIN) 66 group_client.ClientLogin( 67 email=GOOGLE_APPS_ADMIN_EMAIL, 68 password=GOOGLE_APPS_ADMIN_2STEP_CODE, 69 source=GOOGLE_APPS_APP_SOURCE) 70 group_client.ssl = True 71 72 emailsetting_client = gdata.apps.emailsettings.client.EmailSettingsClient( 73 domain=GOOGLE_APPS_DOMAIN) 74 emailsetting_client.ClientLogin( 75 email=GOOGLE_APPS_ADMIN_EMAIL, 76 password=GOOGLE_APPS_ADMIN_2STEP_CODE, 77 source=GOOGLE_APPS_APP_SOURCE)
  19. Creiamo i gruppi... 79 for group in groups: 80 print

    "Creazione gruppo %s ..." % group 81 group_client.CreateGroup( 82 group, # group_id 83 group.capitalize() + ' Group', # group_name 84 'Description of ' + group.capitalize() + ' Group', # description 85 )
  20. Creiamo gli utenti... 88 for user in users: 89 print

    "Creazione utente %s ..." % user['username'] 90 provisioning_client.CreateUser( 91 user['username'], # username 92 user['username'].split('.')[0].capitalize(), # family_name 93 ' '.join(user['username'].split('.')[1:]).capitalize(), # given_name 94 user['username'] # password 95 ) 96 if user['suspend']: 97 print "Sospensione dell'utente %s ..." % user['username'] 98 user_entry = provisioning_client.RetrieveUser(user['username']) 99 user_entry.login.suspended = 'True' 100 provisioning_client.UpdateUser(user['username'], user_entry)
  21. Aggiungiamo gli utenti ai gruppi e creiamo etichette e filtri...

    102 for group in user['groups']: 103 print "Aggiunta dell'utente %s al gruppo %s..." % (group, 104 user['username']) 105 group_client.AddMemberToGroup(group, user['username']) 106 107 label = 'from %s' % group 108 print "Creazione etichetta '%s' all'utente %s" % (label, 109 user['username']) 110 emailsetting_client.CreateLabel(username=user['username'], 111 name=label) 112 print "Creazione filtro per l'utente %s" % (user['username']) 113 emailsetting_client.CreateFilter(username=user['username'], 114 from_address='%s@%s' % (group, GOOGLE_APPS_DOMAIN), 115 label=label)
  22. Creiamo un appuntamento sul calendario... 119 calendar_client = gdata.calendar.client.CalendarClient() 120

    calendar_client.ClientLogin( 121 email='%s@%s' % (users[0]['username'], GOOGLE_APPS_DOMAIN), 122 password=users[0]['username'], 123 source=GOOGLE_APPS_APP_SOURCE) 124 event = gdata.calendar.data.CalendarEventEntry() 125 event.title = atom.data.Title(text='Brainstorming') 126 event.content = atom.data.Content(text='Brainstorming for new application.') 127 for index in [1,2]: 128 event.who.append(gdata.data.Who( 129 email='%s@%s' % (users[index]['username'], GOOGLE_APPS_DOMAIN))) 130 start_time = datetime.datetime.now() + datetime.timedelta(days=1) 131 end_time = start_time + datetime.timedelta(minutes=60) 132 event.when.append(gdata.data.When( 133 start=start_time.strftime(GOOGLE_CALENDAR_DATETIME_FORMAT), 134 end=end_time.strftime(GOOGLE_CALENDAR_DATETIME_FORMAT))) 135 event.send_event_notifications = ( 136 gdata.calendar.data.SendEventNotificationsProperty( 137 value='true')) 138 event = calendar_client.InsertEvent(event)
  23. Creiamo un sito... 140 sites_client = gdata.sites.client.SitesClient(source=GOOGLE_APPS_APP_SOURCE) 141 sites_client.ClientLogin( 142

    GOOGLE_APPS_ADMIN_EMAIL, 143 GOOGLE_APPS_ADMIN_2STEP_CODE, 144 GOOGLE_APPS_APP_SOURCE) 145 sites_client.domain = GOOGLE_APPS_DOMAIN 146 147 site_name = "kno%s" % datetime.datetime.now().strftime("%M%S") 148 print "Creazione di un appuntamento sul calendatrio dell'utente %s" % ( 149 users[0]['username']) 150 entry = sites_client.CreateSite( 151 site_name, 152 description='Knowledge Management of Organization', 153 theme='slate') 154 sites_client.site = site_name
  24. Aggiungiamo un paio di pagine al sito... 155 uri =

    '%s?path=%s' % (sites_client.MakeContentFeedUri(), '/home/') 156 home_feed = sites_client.GetContentFeed(uri=uri) 157 entry = sites_client.CreatePage('webpage', 158 'Helpdesk', 159 html='Helpdesk Knowledge of bla bla', 160 page_name='helpdesk', 161 parent=home_feed.entry[0]) 162 entry = sites_client.CreatePage('webpage', 163 'Programming', 164 html='<b>Programming Knowledge</b> of bla bla', 165 page_name='programming', 166 parent=home_feed.entry[0])
  25. Impostiamo le ACL al sito... 168 scope = gdata.acl.data.AclScope( 169

    value='%s@%s' % (users[1]['username'],GOOGLE_APPS_DOMAIN), 170 type='user') 171 role = gdata.acl.data.AclRole(value='writer') 172 acl = gdata.sites.data.AclEntry(scope=scope, role=role) 173 acl_entry = sites_client.Post(acl, sites_client.MakeAclFeedUri()) 174 175 scope = gdata.acl.data.AclScope( 176 value='%s@%s' % ('programmaers',GOOGLE_APPS_DOMAIN), 177 type='group') 178 role = gdata.acl.data.AclRole(value='reader') 179 acl = gdata.sites.data.AclEntry(scope=scope, role=role) 180 acl_entry = sites_client.Post(acl, sites_client.MakeAclFeedUri())
  26. Creiamo delle cartelle in Docs... 182 for user in users:

    183 print "Creazione cartella per l'utente '%s' ..." % user['username'] 184 docs_client = gdata.docs.client.DocsClient( 185 domain=GOOGLE_APPS_DOMAIN) 186 docs_client.ClientLogin( 187 email='%s@%s' % (user['username'], GOOGLE_APPS_DOMAIN), 188 password=user['username'], 189 source=GOOGLE_APPS_APP_SOURCE) 190 col = gdata.docs.data.Resource(type='folder', title='Cartella di Esempio') 191 col = docs_client.CreateResource(col)
  27. Creiamo un documento in Docs... 233 import StringIO 234 docs_client

    = gdata.docs.client.DocsClient( 235 domain=GOOGLE_APPS_DOMAIN) 236 docs_client.ClientLogin( 237 email=GOOGLE_APPS_ADMIN_EMAIL, 238 password=GOOGLE_APPS_ADMIN_2STEP_CODE, 239 source=GOOGLE_APPS_APP_SOURCE) 240 docs_client.ssl = True 241 data = 'Vademecum del perfetto operatore di helpdesk.' 242 ms = gdata.data.MediaSource(file_handle=StringIO.StringIO(data), 243 content_type='text/plain', 244 content_length=len(data)) 245 246 print "Creazione di un documento per l'utente '%s'" % GOOGLE_APPS_ADMIN_EMAIL 247 doc = docs_client.CreateResource( 248 gdata.docs.data.Resource(type=gdata.docs.data.DOCUMENT_LABEL, 249 title="vademecum_for_helpdesk"), 250 ms)
  28. ...e condividiamolo a livello di dominio... 212 print "Condivisione del

    documento in lettura per l'intero dominio '%s'" %\ 213 GOOGLE_APPS_DOMAIN 214 acl_entry = gdata.docs.data.AclEntry( 215 scope=gdata.acl.data.AclScope(value=GOOGLE_APPS_DOMAIN, type='domain'), 216 role=gdata.acl.data.AclRole(value='reader'), 217 ) 218 acl_entry = docs_client.AddAclEntry(doc, acl_entry) 219
  29. ...a livello di gruppo e utente... 220 print "Condivisione del

    documento in scrittura per il gruppo '%s'" %\ 221 'helpdeskers' 222 acl_entry = gdata.docs.data.AclEntry( 223 scope=gdata.acl.data.AclScope( 224 value="%s@%s" % ('helpdeskers', GOOGLE_APPS_DOMAIN), 225 type='group'), 226 role=gdata.acl.data.AclRole(value='writer'), 227 ) 228 acl_entry = docs_client.AddAclEntry(doc, acl_entry) 229 230 print "Assegnameno della proprieta' del documento all'utente '%s'"%\ 231 users[0]['username'] 232 acl_entry = gdata.docs.data.AclEntry( 233 scope=gdata.acl.data.AclScope( 234 value="%s@%s" % (users[0]['username'], GOOGLE_APPS_DOMAIN), 235 type='user'), 236 role=gdata.acl.data.AclRole(value='owner'), 237 ) 238 acl_entry = docs_client.AddAclEntry(doc, acl_entry)
  30. Ed infine eliminiamo gli utenti... 30 for user in users:

    31 try: 32 print "Eliminazione utente %s ..." % user['username'] 33 provisioning_client.DeleteUser(user['username']) 34 except gdata.client.RequestError as re: 35 print re 36 37 for group in groups: 38 try: 39 print "Eliminazione gruppo %s ..." % group 40 group_client.DeleteGroup(group) 41 except gdata.client.RequestError as re: 42 print re
  31. Riferimenti Gdata Pyhon Client: http://code.google.com/p/gdata-python-client/ Gdata Pyhon Client PyDocs: http://gdata-python-client.googlecode.com/hg/pydocs/

    Esempi dal sorgente della Gdata Pyhon Client: https://code.google.com/p/gdata-python-client/source/browse/#hg%2Fsamples Goole Apps Platform su Google Developers https://developers.google.com/google-apps/