diff --git a/README.md b/README.md new file mode 100644 index 0000000..8cabe19 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Alex API Intro ![python](https://img.shields.io/badge/python-3.7-blue.svg) + +Introduction to using OSU's APIs + +## Configuration + +1. Register an application on [OSU Developer Portal](https://developer.oregonstate.edu/) +2. Get `client_id` and `client_secret` from your app, then copy [configuration-example.json](./configuration-example.json) as `configuration.json` and fill in the oauth2 section: + + ```json + "oauth2": { + "auth_api_url": "https://api.oregonstate.edu/oauth2/token", + "client_id": "your_client_id", + "client_secret": "your_client_secret" + } + ``` + +## Usage + +1. Install dependencies via pip: + + ```shell + $ pip3 install -r requirements.txt + ``` +2. Run the script: + + ```shell + $ python3 api_intro.py path/to/configuration.json + ``` \ No newline at end of file diff --git a/api_intro.py b/api_intro.py index aac1ce8..71fabe5 100644 --- a/api_intro.py +++ b/api_intro.py @@ -1,39 +1,110 @@ # api_intro.py # authorize and send requests using OSU's API +import json +import sys + import requests -personsUrl = "https://api.oregonstate.edu/v1/persons" -authUrl = "https://api.oregonstate.edu/oauth2/token" -# Request access_token from osu api -# Read in consumer key and consumer secret from user -def get_access_token(): - key = input("Enter Consumer Key: ") - secret = input("Enter Consumer Secret: ") +def get_access_token(authUrl, id, secret): + """Request access_token from osu api + Read in consumer key and consumer secret from user""" - data = {"client_id": key, "client_secret": secret, "grant_type": "client_credentials"} + data = {'client_id': id, 'client_secret': secret, + 'grant_type': 'client_credentials'} request = requests.post(authUrl, data=data) response = request.json() - return response["access_token"] + try: + response['access_token'] + return response['access_token'] + except KeyError: + if request.status_code != 200: + print('Client Id or Client Secret invalid. ' + f'Please check your configuration.json ' + f'file and try again.') + else: + print('Unknown error occurred.') + exit() -# Make get request for information about a person at osu -# Read in ONID from user -# requires access_token retrieved in get_access_token() -def get_person(access_token): - onid = input("Enter Person's ONID: ") - params = {'onid': onid} - headers = {"Content-Type": "application/json", "Authorization": "Bearer " + access_token} +def get_person(access_token, api_url): + """Make get request for information about a person at osu + Read in ONID from user + requires access_token retrieved in get_access_token()""" - request = requests.get(personsUrl, params=params, headers=headers) - response = request.json() - return response["data"] + while True: + onid = input('Enter Person\'s ONID: ') + + params = {'onid': onid} + headers = {'Content-Type': 'application/json', + 'Authorization': f'Bearer {access_token}'} + + request = requests.get(api_url, params=params, headers=headers) + if not check_request_errors(request): + response = request.json() + response_data = response['data'] + if response_data: + return response_data + else: + print(f'No data found for \"{onid}\". ' + f'Please try a different search query.') + + +def get_directory(access_token, apiUrl): + """Requests OSU directory information using api + requires an access token and api url to be passed in + asks for search query from user + returns data if the search query finds some. + If no data is found the user is asked again to enter a query""" + + while True: + query = input('Enter Directory Search Query: ') + + params = {'q': query} + headers = {'Content-Type': 'application/json', + 'Authorization': f'Bearer {access_token}'} + + request = requests.get(apiUrl, params=params, headers=headers) + if not check_request_errors(request): + response = request.json() + response_data = response['data'] + if response_data: + return response['data'] + else: + print(f'No data found for \"{query}\". ' + f'Please try a different search query.') + + +def check_request_errors(request): + """Checks if a request has returned with an error + returns False if the status code is equal to 200, otherwise returns True""" + + error = True + + if request.status_code == 200: + error = False + else: + print(request.json()['userMessage']) + + return error + + +if __name__ == '__main__': + CONFIG_API = 'api' + CONFIG_OAUTH = 'oauth2' + + config_path = sys.argv[1] + with open(config_path, 'r') as configFile: + config = json.load(configFile) + persons_url = config[CONFIG_API]['persons_url'] + directory_url = config[CONFIG_API]['directory_url'] + auth_url = config[CONFIG_OAUTH]['auth_api_url'] + client_id = config[CONFIG_OAUTH]['client_id'] + client_secret = config[CONFIG_OAUTH]['client_secret'] + access_token = get_access_token(auth_url, client_id, client_secret) + directory_data = get_directory(access_token, directory_url) -if __name__ == "__main__": - access_token = get_access_token() - personData = get_person(access_token) - - for person in personData: - print("Person's Name: " + person["attributes"]["firstName"]) \ No newline at end of file + for directory in directory_data: + print(directory['attributes']['firstName']) diff --git a/configuration-example.json b/configuration-example.json new file mode 100644 index 0000000..b4aa35b --- /dev/null +++ b/configuration-example.json @@ -0,0 +1,11 @@ +{ + "api": { + "directory_url": "https://api.oregonstate.edu/v1/directory", + "persons_url": "https://api.oregonstate.edu/v1/persons" + }, + "oauth2": { + "auth_api_url": "https://api.oregonstate.edu/oauth2/token", + "client_id": "your_client_id", + "client_secret": "your_client_secret" + } +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e20605c --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests==2.22.0 \ No newline at end of file