Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added Polly-API
Empty file.
183 changes: 183 additions & 0 deletions api/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
'''
Client-side functions for interacting with the Polly-API.

Each function raises `requests.exceptions.HTTPError` on non-2xx status codes.
'''
import requests
import json
import time

def get_polls(skip: int = 0, limit: int = 10, base_url: str = "http://localhost:8000"):
'''
Fetches paginated poll data from the API.

Args:
skip (int, optional): Number of items to skip. Defaults to 0.
limit (int, optional): Max number of items to return. Defaults to 10.
base_url (str, optional): The base URL of the API.
Defaults to "http://localhost:8000".

Returns:
list: A list of polls.

Raises:
requests.exceptions.HTTPError: For non-2xx status codes.
'''
url = f"{base_url}/polls"
params = {"skip": skip, "limit": limit}

response = requests.get(url, params=params)
response.raise_for_status()

return response.json()

def register_user(username, password, base_url="http://localhost:8000"):
"""
Registers a new user with the Polly-API.

Args:
username (str): The username to register.
password (str): The password for the user.
base_url (str, optional): The base URL of the API.
Defaults to "http://localhost:8000".

Returns:
dict: The JSON response from the API.

Raises:
requests.exceptions.HTTPError: For non-2xx status codes.
"""
url = f"{base_url}/register"
user_data = {"username": username, "password": password}

response = requests.post(url, json=user_data)
response.raise_for_status()

return response.json()

def login(username, password, base_url="http://localhost:8000"):
"""
Logs in a user and returns a JWT token.

Args:
username (str): The username to login with.
password (str): The password for the user.
base_url (str, optional): The base URL of the API.
Defaults to "http://localhost:8000".

Returns:
dict: A dictionary containing the access token and token type.

Raises:
requests.exceptions.HTTPError: For non-2xx status codes.
"""
url = f"{base_url}/login"
data = {"username": username, "password": password}
headers = {"Content-Type": "application/x-www-form-urlencoded"}

response = requests.post(url, data=data, headers=headers)
response.raise_for_status()

return response.json()

def cast_vote(poll_id: int, option_id: int, token: str, base_url: str = "http://localhost:8000"):
"""
Casts a vote on a poll.

Args:
poll_id (int): The ID of the poll to vote on.
option_id (int): The ID of the option to vote for.
token (str): The JWT token for authentication.
base_url (str, optional): The base URL of the API.
Defaults to "http://localhost:8000".

Returns:
dict: The JSON response from the API.

Raises:
requests.exceptions.HTTPError: For non-2xx status codes.
"""
url = f"{base_url}/polls/{poll_id}/vote"
headers = {"Authorization": f"Bearer {token}"}
data = {"option_id": option_id}

response = requests.post(url, headers=headers, json=data)
response.raise_for_status()

return response.json()

def get_poll_results(poll_id: int, base_url: str = "http://localhost:8000"):
"""
Retrieves the results for a specific poll.

Args:
poll_id (int): The ID of the poll.
base_url (str, optional): The base URL of the API.
Defaults to "http://localhost:8000".

Returns:
dict: The poll results.

Raises:
requests.exceptions.HTTPError: For non-2xx status codes.
"""
url = f"{base_url}/polls/{poll_id}/results"
response = requests.get(url)
response.raise_for_status()
return response.json()

# Example usage:
if __name__ == "__main__":
# Use a unique username to avoid conflicts
new_username = f"testuser_{int(time.time())}"
new_password = "testpassword"

try:
# 1. Register a new user
print(f"Registering user: {new_username}")
registration_response = register_user(new_username, new_password)
print("Registration successful:", registration_response)

# 2. Log in to get a token
print("Logging in...")
login_response = login(new_username, new_password)
token = login_response.get("access_token")
if not token:
raise Exception("Failed to get access token from login response.")
print("Login successful.")

# 3. Fetch polls
print("Fetching polls...")
polls = get_polls(limit=1)
if not polls:
print("No polls found. Cannot proceed with voting example.")
else:
example_poll = polls[0]
example_poll_id = example_poll.get("id")
if not example_poll_id:
raise Exception("Poll has no ID.")

if example_poll.get("options"):
example_option = example_poll["options"][0]
example_option_id = example_option.get("id")
if not example_option_id:
raise Exception("Option has no ID.")

# 4. Cast a vote
print(f"Casting vote on poll {example_poll_id}, option {example_option_id}...")
vote_response = cast_vote(example_poll_id, example_option_id, token)
print("Vote cast successfully:", vote_response)

# 5. Get poll results
print(f"Fetching results for poll {example_poll_id}...")
results = get_poll_results(example_poll_id)
print("Poll results:", results)
else:
print(f"Poll {example_poll_id} has no options to vote on.")

except requests.exceptions.RequestException as e:
print(f"An API error occurred: {e}")
if e.response:
print(f"Response body: {e.response.text}")
except Exception as e:
print(f"An unexpected error occurred: {e}")