Skip to content

Commit

Permalink
api: Exclude None values from request payload in Endpoint class.
Browse files Browse the repository at this point in the history
Refactored the Endpoint class to exclude parameters with None values
from the request payload. This ensures cleaner API interactions and avoids
unintended behavior, improving code reliability and aligning with best
practices.
  • Loading branch information
pransh62390 committed Jan 16, 2025
1 parent 8c27331 commit 3460d01
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 44 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ module = [
"feedparser.*",
"gitlint.*",
"googleapiclient.*",
"google_api_python_client.*",
"google_auth_httplib2.*",
"google_auth_oauthlib.*",
"irc.*",
"mercurial.*",
"nio.*",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ types-pytz
types-requests
gitlint>=0.13.0
-r ./zulip/integrations/bridge_with_matrix/requirements.txt
-r ./zulip/integrations/google/requirements.txt
56 changes: 39 additions & 17 deletions zulip/integrations/google/get-google-credentials
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,32 @@
import argparse
import os

from oauth2client import client, tools
from oauth2client.file import Storage
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
flags = argparse.ArgumentParser(description="Google Calendar Bot")
flags.add_argument(
"--noauth_local_webserver",
action="store_true",
help="Run OAuth flow in console instead of opening a web browser.",
)
args = flags.parse_args()

# If modifying these scopes, delete your previously saved credentials
# at zulip/bots/gcal/
# NOTE: When adding more scopes, add them after the previous one in the same field, with a space
# seperating them.
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
# This file contains the information that google uses to figure out which application is requesting
# this client's data.
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
APPLICATION_NAME = "Zulip Calendar Bot"
HOME_DIR = os.path.expanduser("~")
CREDENTIALS_PATH = os.path.join(HOME_DIR, "google-credentials.json")


def get_credentials() -> client.Credentials:
def get_credentials() -> Credentials:
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
Expand All @@ -29,18 +37,32 @@ def get_credentials() -> client.Credentials:
Credentials, the obtained credential.
"""

credential_path = os.path.join(HOME_DIR, "google-credentials.json")

store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES)
flow.user_agent = APPLICATION_NAME
# This attempts to open an authorization page in the default web browser, and asks the user
# to grant the bot access to their data. If the user grants permission, the run_flow()
# function returns new credentials.
credentials = tools.run_flow(flow, store, flags)
print("Storing credentials to " + credential_path)
creds = None

# Check if the credentials file exists
if os.path.exists(CREDENTIALS_PATH):
creds = Credentials.from_authorized_user_file(CREDENTIALS_PATH, SCOPES)

# If there are no valid credentials, initiate the OAuth flow
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES
)
if args.noauth_local_webserver:
creds = flow.run_console()
else:
creds = flow.run_local_server(port=0)

# Save the credentials for future use
with open(CREDENTIALS_PATH, "w") as token_file:
token_file.write(creds.to_json())

print("Storing credentials to " + CREDENTIALS_PATH)

return creds


get_credentials()
52 changes: 27 additions & 25 deletions zulip/integrations/google/google-calendar
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,16 @@ import time
from typing import List, Optional, Set, Tuple

import dateutil.parser
import httplib2
import pytz
from oauth2client import client
from oauth2client.file import Storage

try:
from googleapiclient import discovery
except ImportError:
logging.exception("Install google-api-python-client")
sys.exit(1)
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

sys.path.append(os.path.join(os.path.dirname(__file__), "../../"))
import zulip

SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
APPLICATION_NAME = "Zulip"
HOME_DIR = os.path.expanduser("~")
Expand Down Expand Up @@ -88,33 +83,40 @@ if not options.zulip_email:
zulip_client = zulip.init_from_options(options)


def get_credentials() -> client.Credentials:
def get_credentials() -> Credentials:
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
an exception is thrown and the user is informed to run the script in this directory to get
credentials.
the user will be prompted to authenticate.
Returns:
Credentials, the obtained credential.
"""
try:
credential_path = os.path.join(HOME_DIR, "google-credentials.json")
credential_path = os.path.join(HOME_DIR, "google-credentials.json")
creds = None

# Load credentials from file if they exist
if os.path.exists(credential_path):
creds = Credentials.from_authorized_user_file(credential_path, SCOPES)

# If there are no (valid) credentials available, prompt the user to log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
creds = flow.run_local_server(port=0)

# Save the credentials for the next run
with open(credential_path, "w") as token:
token.write(creds.to_json())

store = Storage(credential_path)
return store.get()
except client.Error:
logging.exception("Error while trying to open the `google-credentials.json` file.")
sys.exit(1)
except OSError:
logging.error("Run the get-google-credentials script from this directory first.")
sys.exit(1)
return creds


def populate_events() -> Optional[None]:
credentials = get_credentials()
creds = credentials.authorize(httplib2.Http())
service = discovery.build("calendar", "v3", http=creds)
service = build("calendar", "v3", credentials=credentials)

now = datetime.datetime.now(pytz.utc).isoformat()
feed = (
Expand Down
5 changes: 3 additions & 2 deletions zulip/integrations/google/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
httplib2>=0.22.0
oauth2client>=4.1.3
google-api-python-client>=2.157.0
google-auth-httplib2>=0.2.0
google-auth-oauthlib>=1.2.1

0 comments on commit 3460d01

Please sign in to comment.