================================================================================ TOKEN ACCESS SETUP GUIDE - xlwings Lite Secure Data Downloader ================================================================================ This guide helps set up secure token access for downloading private files from Dropbox, Google Drive, or GitHub into xlwings Lite. Everything needed is in this one document - instructions, scripts, and troubleshooting. No external references required. ================================================================================ SECTION A: INSTRUCTIONS FOR AI ASSISTANTS ================================================================================ The text below is meant to be copied and pasted to an AI assistant (Claude, ChatGPT, etc.) by users who need help setting up token access. --- COPY EVERYTHING FROM HERE TO END OF DOCUMENT --- You are helping a user set up secure token access for xlwings Lite. This allows downloading private files from cloud storage (Dropbox, Google Drive, or GitHub) directly into Excel. IMPORTANT GUIDELINES FOR YOU (THE AI): 1. The user may be completely new to this. Guide them gently, one or two steps at a time. Do not overwhelm with too many steps at once. 2. Ask the user which provider they want to set up first: - Dropbox - Google Drive - GitHub They may want to set up all three or just one. 3. Encourage the user to share screenshots if they get stuck. Many users are doing this for the first time and may not know where to click or what to enter. With a screenshot, you can point them to exactly where to click and what to type. 4. For running the Python scripts: - Ask the user if they want to run the script themselves, or if they want you to run it for them. - If the user wants to run it themselves: Guide them on what values to change in the script (APP_KEY, APP_SECRET, etc.) and how to run it. - If the user wants you to run it: Ask them to provide the credentials (App Key, App Secret, Client ID, etc.) so you can run the script. 5. The complete Python scripts are included at the end of this document in SECTION PY-1 (Dropbox) and SECTION PY-2 (Google Drive). GitHub does not need a script - just a Personal Access Token. 6. After getting the tokens, guide the user to add them to xlwings Lite: - Click hamburger menu (three horizontal lines) - Go to Environment Variables - Add the required variables - Save 7. Be patient. If something fails, help troubleshoot. Common issues are listed in SECTION H at the end. ================================================================================ SECTION B: QUICK REFERENCE - WHAT IS NEEDED FOR EACH PROVIDER ================================================================================ DROPBOX (3 items needed): DROPBOX.APP_KEY .......... from Dropbox Developer Console DROPBOX.APP_SECRET ....... from Dropbox Developer Console DROPBOX.REFRESH_TOKEN .... generated by running the script after OAuth GOOGLE DRIVE (3 items needed): GDRIVE.CLIENT_ID ......... from Google Cloud Console GDRIVE.CLIENT_SECRET ..... from Google Cloud Console GDRIVE.REFRESH_TOKEN ..... generated by running the script after OAuth GITHUB (1 item needed): GITHUB.PAT ............... Personal Access Token from GitHub Settings ================================================================================ SECTION C: DROPBOX SETUP (Step by Step) ================================================================================ OVERVIEW: Create a Dropbox app, get credentials, run script to get refresh token. STEP 1: Create Dropbox App - Go to: https://www.dropbox.com/developers/apps - Click "Create app" - Choose: "Scoped access" - Choose: "Full Dropbox" (access to all files) - Give the app a name (example: "xlwings-data-access") - Click "Create app" STEP 2: Get App Key and App Secret - After creating the app, the Settings page appears - Copy the "App key" (looks like: zexbaceerer9ngz) - Copy the "App secret" (click "Show" first, looks like: 6uacewxag1jpvz2) - Save these somewhere safe STEP 3: Run the Refresh Token Script - Use the script in SECTION PY-1 below - Update APP_KEY and APP_SECRET with the values from Step 2 - Run: python get_dropbox_refresh_token.py - The script opens the browser automatically STEP 4: Authorize in Browser - Browser opens to Dropbox authorization page - Log in to Dropbox if needed - Click "Allow" to authorize the app - Dropbox shows an authorization code - Copy that code STEP 5: Paste Code in Terminal - Go back to the terminal/command window - Paste the authorization code when prompted - Press Enter - The script displays the REFRESH_TOKEN STEP 6: Add to xlwings Lite Environment Variables - In xlwings Lite, click the hamburger menu (three lines icon) - Go to "Environment Variables" - Add these three variables: DROPBOX.APP_KEY = (the app key from Step 2) DROPBOX.APP_SECRET = (the app secret from Step 2) DROPBOX.REFRESH_TOKEN = (the token from Step 5) - Save DONE! Dropbox is now ready for use in the TOKEN_ACCESS sheet. ================================================================================ SECTION D: GOOGLE DRIVE SETUP (Step by Step) ================================================================================ OVERVIEW: Create Google Cloud project, enable Drive API, create OAuth credentials, run script to get refresh token. NOTE: This works with free Gmail accounts. No payment required. STEP 1: Go to Google Cloud Console - Go to: https://console.cloud.google.com/ - Sign in with a Google account - Accept terms if this is the first time STEP 2: Create a New Project - Click the project dropdown at the top (may say "Select a project") - Click "New Project" - Name it something like "xlwings-gdrive" - Click "Create" - Wait for it to be created, then select it STEP 3: Enable Google Drive API - Go to: https://console.cloud.google.com/apis/library - Search for "Google Drive API" - Click on it - Click "Enable" STEP 4: Configure OAuth Consent Screen - Go to: https://console.cloud.google.com/apis/credentials/consent - Choose "External" (unless using Google Workspace) - Click "Create" - Fill in required fields: App name: xlwings-gdrive (or any name) User support email: (user's email) Developer contact email: (user's email) - Leave everything else blank/default - Click "Save and Continue" - On Scopes page: just click "Save and Continue" - On Test Users page: Add the user's email address, then "Save and Continue" - Click "Back to Dashboard" STEP 5: Create OAuth Credentials - Go to: https://console.cloud.google.com/apis/credentials - Click "Create Credentials" at the top - Choose "OAuth client ID" - Application type: "Desktop app" - Name: xlwings-gdrive (or any name) - Click "Create" - A popup shows Client ID and Client Secret - Click "Download JSON" to save them (or copy them now) STEP 6: Run the Refresh Token Script - Use the script in SECTION PY-2 below - Update CLIENT_ID and CLIENT_SECRET with values from Step 5 - Run: python get_gdrive_refresh_token.py - The script displays a URL (does NOT auto-open browser) STEP 7: Authorize in Browser - Copy the URL shown in the terminal - Paste it in a browser (use incognito to choose a specific account) - Log in with the Google account that has the files - May see "Google hasn't verified this app" - click "Continue" - Click "Allow" to grant access - Browser shows "Authorization Successful!" STEP 8: Get the Refresh Token - The script automatically receives the callback - It displays the REFRESH_TOKEN in the terminal STEP 9: Add to xlwings Lite Environment Variables - In xlwings Lite, click the hamburger menu (three lines icon) - Go to "Environment Variables" - Add these three variables: GDRIVE.CLIENT_ID = (the client ID from Step 5) GDRIVE.CLIENT_SECRET = (the client secret from Step 5) GDRIVE.REFRESH_TOKEN = (the token from Step 8) - Save DONE! Google Drive is now ready for use in the TOKEN_ACCESS sheet. ================================================================================ SECTION E: GITHUB SETUP (Step by Step) ================================================================================ OVERVIEW: Create a Personal Access Token (PAT) with repo access. No script needed for GitHub - just create a token in GitHub settings. NOTE: Use Classic token, not Fine-grained. Classic is simpler and works better. STEP 1: Go to GitHub Token Settings - Go to: https://github.com/settings/tokens - Or: Click profile picture then Settings then Developer settings then Personal access tokens then Tokens (classic) STEP 2: Generate New Token (Classic) - Click "Generate new token" dropdown - Choose "Generate new token (classic)" - May need to confirm password STEP 3: Configure the Token - Note: Give it a name like "xlwings-data-access" - Expiration: Choose based on needs (90 days, 1 year, or No expiration) - Scopes: Check "repo" (this gives full access to private repositories) - Scroll down and click "Generate token" STEP 4: Copy the Token IMMEDIATELY - GitHub shows the token ONLY ONCE - Copy it immediately (starts with ghp_...) - Save it somewhere safe - If lost, a new one must be created STEP 5: Add to xlwings Lite Environment Variables - In xlwings Lite, click the hamburger menu (three lines icon) - Go to "Environment Variables" - Add this variable: GITHUB.PAT = ghp_xxxxxxxxxxxxxxxxxxxx (the token from Step 4) - Save DONE! GitHub is now ready for use. FOR PRIVATE REPOS ONLY: - Also need an Auth Proxy URL in cell B7 of TOKEN_ACCESS sheet - Example: https://github-proxy-auth.your-domain.workers.dev ================================================================================ SECTION F: USING TOKEN ACCESS IN XLWINGS LITE ================================================================================ After setting up environment variables: 1. Open the TOKEN_ACCESS sheet in the workbook 2. In cell B5, select the provider from dropdown: - Dropbox - Google Drive - GitHub 3. In cell B6, enter the file path or ID: - Dropbox: /folder/subfolder/filename.parquet (path starts with /) - Google Drive: 1AbCdEfGhIjKlMnOp... (file ID from URL) - GitHub: https://github.com/owner/repo/releases/download/v1.0/file.parquet 4. For GitHub private repos only, enter Auth Proxy URL in B7 5. Run the import_data_token script ================================================================================ SECTION G: HOW TO GET FILE PATH/ID FOR EACH PROVIDER ================================================================================ DROPBOX FILE PATH: - Open Dropbox in browser - Navigate to the file - The path is shown in the URL or breadcrumb - Format: /FolderName/SubFolder/filename.parquet - Must start with / GOOGLE DRIVE FILE ID: - Open Google Drive in browser - Right-click the file and choose "Get link" or look at URL when file is open - URL looks like: https://drive.google.com/file/d/1AbCdEfGhIjKlMnOp/view - The file ID is: 1AbCdEfGhIjKlMnOp (the part between /d/ and /view) GITHUB FILE URL: - For releases: https://github.com/owner/repo/releases/download/tag/filename - For raw files: https://raw.githubusercontent.com/owner/repo/branch/path/file ================================================================================ SECTION H: TROUBLESHOOTING ================================================================================ DROPBOX ERRORS: - "File not found": Check path starts with / and matches exactly - "Authentication failed": Refresh token may have expired, regenerate it GOOGLE DRIVE ERRORS: - "No refresh token received": Go to https://myaccount.google.com/permissions Remove the app, then run the script again - "Permission denied": Make sure authorized with the account that owns the file GITHUB ERRORS: - "401 Unauthorized": PAT is invalid or expired - "403 Forbidden": PAT does not have 'repo' scope - "404 Not Found": Check URL is correct, or repo is truly accessible ================================================================================ SECTION PY-1: DROPBOX REFRESH TOKEN SCRIPT ================================================================================ Save this as: get_dropbox_refresh_token.py Requires: pip install requests Before running: Update APP_KEY and APP_SECRET with values from Dropbox app. -------------------------------------------------------------------------------- """ Dropbox OAuth2 Refresh Token Generator Run this script locally to get a refresh token for xlwings Lite Dropbox integration. The refresh token is permanent (until revoked) and can be used to get new access tokens. Usage: python get_dropbox_refresh_token.py """ import requests import webbrowser # UPDATE THESE WITH YOUR DROPBOX APP CREDENTIALS APP_KEY = "YOUR_APP_KEY_HERE" APP_SECRET = "YOUR_APP_SECRET_HERE" def main(): print("=" * 60) print("Dropbox OAuth2 Refresh Token Generator") print("=" * 60) # Step 1: Open browser for authorization # token_access_type=offline is required to get a refresh token auth_url = ( f"https://www.dropbox.com/oauth2/authorize" f"?client_id={APP_KEY}" f"&response_type=code" f"&token_access_type=offline" ) print("\n[Step 1] Opening browser for Dropbox authorization...") print(f"URL: {auth_url}\n") try: webbrowser.open(auth_url) print("Browser opened. Please authorize the app in your browser.") except Exception as e: print(f"Could not open browser automatically: {e}") print(f"Please open this URL manually:\n{auth_url}") # Step 2: Get the authorization code from user print("\n[Step 2] After authorizing, Dropbox will show you an authorization code.") auth_code = input("Paste the authorization code here: ").strip() if not auth_code: print("ERROR: No authorization code provided.") return # Step 3: Exchange code for tokens print("\n[Step 3] Exchanging authorization code for tokens...") response = requests.post( "https://api.dropbox.com/oauth2/token", data={ "code": auth_code, "grant_type": "authorization_code", "client_id": APP_KEY, "client_secret": APP_SECRET }, timeout=30 ) if response.status_code != 200: print(f"ERROR: Failed to get tokens. Status: {response.status_code}") print(f"Response: {response.text}") return data = response.json() # Step 4: Display results print("\n" + "=" * 60) print("SUCCESS! Here are your tokens:") print("=" * 60) refresh_token = data.get("refresh_token") access_token = data.get("access_token") print(f"\nREFRESH_TOKEN (permanent, save this!):") print(f" {refresh_token}") print(f"\nACCESS_TOKEN (expires in ~4 hours, for testing):") print(f" {access_token[:50]}...") print("\n" + "=" * 60) print("Add these to xlwings Lite environment variables:") print("=" * 60) print(f" DROPBOX.APP_KEY = {APP_KEY}") print(f" DROPBOX.APP_SECRET = {APP_SECRET}") print(f" DROPBOX.REFRESH_TOKEN = {refresh_token}") print("\n") if __name__ == "__main__": main() -------------------------------------------------------------------------------- ================================================================================ SECTION PY-2: GOOGLE DRIVE REFRESH TOKEN SCRIPT ================================================================================ Save this as: get_gdrive_refresh_token.py Requires: pip install requests Before running: Update CLIENT_ID and CLIENT_SECRET with values from Google Cloud. -------------------------------------------------------------------------------- """ Google Drive OAuth2 Refresh Token Generator Run this script locally to get a refresh token for xlwings Lite Google Drive integration. The refresh token is permanent (until revoked) and can be used to get new access tokens. Usage: python get_gdrive_refresh_token.py NOTE: This script does NOT auto-open the browser. Copy the URL and paste it in your desired browser (e.g., incognito with work account). """ import requests import urllib.parse from http.server import HTTPServer, BaseHTTPRequestHandler import threading # UPDATE THESE WITH YOUR GOOGLE CLOUD OAUTH CREDENTIALS CLIENT_ID = "YOUR_CLIENT_ID_HERE.apps.googleusercontent.com" CLIENT_SECRET = "YOUR_CLIENT_SECRET_HERE" REDIRECT_URI = "http://localhost:8080/callback" # Scopes for Google Drive read access SCOPES = "https://www.googleapis.com/auth/drive.readonly" # Global to store the authorization code auth_code = None server_should_stop = False class OAuthCallbackHandler(BaseHTTPRequestHandler): """Handle the OAuth callback from Google.""" def do_GET(self): global auth_code, server_should_stop # Parse the callback URL for the authorization code parsed = urllib.parse.urlparse(self.path) params = urllib.parse.parse_qs(parsed.query) if 'code' in params: auth_code = params['code'][0] self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(b"""
You can close this window and return to the terminal.
""") server_should_stop = True elif 'error' in params: self.send_response(400) self.send_header('Content-type', 'text/html') self.end_headers() error = params.get('error', ['Unknown'])[0] self.wfile.write(f"""Error: {error}
""".encode()) server_should_stop = True else: self.send_response(404) self.end_headers() def log_message(self, format, *args): # Suppress HTTP server logs pass def main(): global auth_code, server_should_stop print("=" * 60) print("Google Drive OAuth2 Refresh Token Generator") print("=" * 60) # Build the authorization URL # access_type=offline is required to get a refresh token # prompt=consent forces consent screen to always show (ensures refresh token) auth_params = { "client_id": CLIENT_ID, "redirect_uri": REDIRECT_URI, "response_type": "code", "scope": SCOPES, "access_type": "offline", "prompt": "consent" } auth_url = f"https://accounts.google.com/o/oauth2/auth?{urllib.parse.urlencode(auth_params)}" print("\n[Step 1] Copy this URL and paste it in your browser:") print(" (Use incognito if you want to use a specific account)") print() print("-" * 60) print(auth_url) print("-" * 60) print() # Start local server to receive callback print("[Step 2] Starting local server to receive callback...") print(" Waiting for authorization at http://localhost:8080/callback") print() server = HTTPServer(('localhost', 8080), OAuthCallbackHandler) server.timeout = 1 # Check every second if we should stop # Wait for the callback while not server_should_stop: server.handle_request() server.server_close() if not auth_code: print("ERROR: No authorization code received.") return print(f" Authorization code received!") # Step 3: Exchange code for tokens print("\n[Step 3] Exchanging authorization code for tokens...") response = requests.post( "https://oauth2.googleapis.com/token", data={ "code": auth_code, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": REDIRECT_URI, "grant_type": "authorization_code" }, timeout=30 ) if response.status_code != 200: print(f"ERROR: Failed to get tokens. Status: {response.status_code}") print(f"Response: {response.text}") return data = response.json() # Step 4: Display results print("\n" + "=" * 60) print("SUCCESS! Here are your tokens:") print("=" * 60) refresh_token = data.get("refresh_token") access_token = data.get("access_token") if refresh_token: print(f"\nREFRESH_TOKEN (permanent, save this!):") print(f" {refresh_token}") else: print("\nWARNING: No refresh token received!") print("This can happen if you've already authorized this app before.") print("Go to https://myaccount.google.com/permissions and remove the app,") print("then run this script again.") print(f"\nACCESS_TOKEN (expires in ~1 hour, for testing):") print(f" {access_token[:50]}...") print("\n" + "=" * 60) print("Add these to xlwings Lite environment variables:") print("=" * 60) print(f" GDRIVE.CLIENT_ID = {CLIENT_ID}") print(f" GDRIVE.CLIENT_SECRET = {CLIENT_SECRET}") if refresh_token: print(f" GDRIVE.REFRESH_TOKEN = {refresh_token}") print("\n") if __name__ == "__main__": main() -------------------------------------------------------------------------------- ================================================================================ END OF DOCUMENT ================================================================================