auth.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. from google_auth_oauthlib.flow import InstalledAppFlow
  2. from google.auth.transport.requests import Request
  3. from google.oauth2 import service_account
  4. import os
  5. import pickle
  6. import json
  7. # OAuth 2.0 scopes
  8. SCOPES = ["https://www.googleapis.com/auth/youtube.readonly"]
  9. def get_service_account_token():
  10. """Authenticate using service account (no user interaction needed)."""
  11. service_account_file = "service_account.json"
  12. if not os.path.exists(service_account_file):
  13. print(f"Service account file {service_account_file} not found.")
  14. print("To use service account authentication:")
  15. print("1. Go to Google Cloud Console")
  16. print("2. Navigate to IAM & Admin > Service Accounts")
  17. print("3. Create a new service account")
  18. print("4. Download the JSON key file as 'service_account.json'")
  19. return None
  20. try:
  21. creds = service_account.Credentials.from_service_account_file(
  22. service_account_file, scopes=SCOPES)
  23. print("Service account authentication successful!")
  24. return creds
  25. except Exception as e:
  26. print(f"Service account authentication failed: {e}")
  27. return None
  28. def get_token_interactive():
  29. """Perform OAuth authentication with user interaction."""
  30. creds = None
  31. token_file = "youtube_token.pickle"
  32. # Check if token file exists
  33. if os.path.exists(token_file):
  34. with open(token_file, "rb") as token:
  35. creds = pickle.load(token)
  36. # If no valid credentials, authenticate user
  37. if not creds or not creds.valid:
  38. if creds and creds.expired and creds.refresh_token:
  39. try:
  40. creds.refresh(Request())
  41. print("Token refreshed successfully!")
  42. except Exception as e:
  43. print(f"Token refresh failed: {e}")
  44. creds = None
  45. if not creds:
  46. print("Starting interactive authentication...")
  47. flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", SCOPES)
  48. creds = flow.run_local_server(port=8080)
  49. # Save the credentials to a file
  50. with open(token_file, "wb") as token:
  51. pickle.dump(creds, token)
  52. print(f"Token saved to {token_file}")
  53. else:
  54. print("Token already exists and is valid.")
  55. return creds
  56. def get_token_non_interactive():
  57. """Try non-interactive authentication methods first."""
  58. # Try service account first
  59. creds = get_service_account_token()
  60. if creds:
  61. return creds
  62. # Try existing saved token
  63. token_file = "youtube_token.pickle"
  64. if os.path.exists(token_file):
  65. try:
  66. with open(token_file, "rb") as token:
  67. creds = pickle.load(token)
  68. if creds and creds.valid:
  69. print("Using existing valid token.")
  70. return creds
  71. elif creds and creds.expired and creds.refresh_token:
  72. try:
  73. creds.refresh(Request())
  74. print("Token refreshed successfully!")
  75. # Save refreshed token
  76. with open(token_file, "wb") as token:
  77. pickle.dump(creds, token)
  78. return creds
  79. except Exception as e:
  80. print(f"Token refresh failed: {e}")
  81. except Exception as e:
  82. print(f"Error loading saved token: {e}")
  83. print("No valid non-interactive authentication method available.")
  84. print("Run with --interactive flag or set up service account authentication.")
  85. return None
  86. def get_token():
  87. """Main authentication function - tries non-interactive first."""
  88. return get_token_non_interactive()
  89. if __name__ == "__main__":
  90. import sys
  91. if "--interactive" in sys.argv:
  92. creds = get_token_interactive()
  93. else:
  94. creds = get_token_non_interactive()
  95. if not creds:
  96. print("\nTo authenticate interactively, run: python3 auth.py --interactive")
  97. if creds:
  98. print("Authentication successful!")
  99. else:
  100. print("Authentication failed!")
  101. sys.exit(1)