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
225 changes: 225 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,234 @@
from api.database import Base, engine
from api import models
from api.routes import router
import requests
from typing import List, Dict, Any

# Create tables
Base.metadata.create_all(bind=engine)

app = FastAPI()
app.include_router(router)

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

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
username (str): The username for the new user.
password (str): The password for the new user.

Returns:
requests.Response: The response object from the API call.
"""
url = f"{base_url}/register"
headers = {"Content-Type": "application/json"}
payload = {"username": username, "password": password}

try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status() # Raise an exception for HTTP errors
return response
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
return None


def get_paginated_polls(base_url: str, skip: int = 0, limit: int = 10) -> List[Dict[str, Any]] | None:
"""
Fetches paginated poll data from the API.

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
skip (int): The number of items to skip (for pagination).
limit (int): The maximum number of items to return.

Returns:
List[Dict[str, Any]] | None: A list of dictionaries representing poll data, or None if an error occurs.
"""
url = f"{base_url}/polls"
params = {"skip": skip, "limit": limit}

try:
response = requests.get(url, params=params)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
return None


def cast_vote(base_url: str, poll_id: int, option_id: int, access_token: str) -> Dict[str, Any] | None:
"""
Casts a vote on an existing poll.

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
poll_id (int): The ID of the poll to vote on.
option_id (int): The ID of the option to vote for.
access_token (str): The JWT access token for authentication.

Returns:
Dict[str, Any] | None: A dictionary representing the vote confirmation, or None if an error occurs.
"""
url = f"{base_url}/polls/{poll_id}/vote"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
}
payload = {"option_id": option_id}

try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
except requests.exceptions.RequestException as e:
print(f"An error occurred while casting vote: {e}")
return None


def get_poll_results(base_url: str, poll_id: int) -> Dict[str, Any] | None:
"""
Retrieves the results for a specific poll.

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
poll_id (int): The ID of the poll to retrieve results for.

Returns:
Dict[str, Any] | None: A dictionary containing the poll results, or None if an error occurs.
"""
url = f"{base_url}/polls/{poll_id}/results"

try:
response = requests.get(url)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
except requests.exceptions.RequestException as e:
print(f"An error occurred while fetching poll results: {e}")
return None


def create_poll(base_url: str, question: str, options: List[str], access_token: str) -> Dict[str, Any] | None:
"""
Creates a new poll.

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
question (str): The question for the poll.
options (List[str]): A list of strings, each representing an option for the poll.
Requires a minimum of two options.
access_token (str): The JWT access token for authentication.

Returns:
Dict[str, Any] | None: A dictionary representing the created poll, or None if an error occurs.
"""
if len(options) < 2:
print("Error: A poll must have at least two options.")
return None

url = f"{base_url}/polls"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
}
payload = {"question": question, "options": options}

try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
except requests.exceptions.RequestException as e:
print(f"An error occurred while creating poll: {e}")
return None


def login_user(base_url: str, username: str, password: str) -> Dict[str, Any] | None:
"""
Logs in a user and retrieves an access token.

Args:
base_url (str): The base URL of the API (e.g., "http://127.0.0.1:8000").
username (str): The username of the user.
password (str): The password of the user.

Returns:
Dict[str, Any] | None: A dictionary containing the access token and token type,
or None if an error occurs.
"""
url = f"{base_url}/login"
headers = {"Content-Type": "application/x-www-form-urlencoded"} # FastAPI expects form data for login
payload = {"username": username, "password": password}

try:
response = requests.post(url, data=payload, headers=headers)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
except requests.exceptions.RequestException as e:
print(f"An error occurred during login: {e}")
return None


if __name__ == "__main__":
BASE_URL = "http://127.0.0.1:8000" # Replace with your API's base URL if different

# --- Authentication and Poll Creation Example ---
USERNAME = "example_user"
PASSWORD = "example_password"

# 1. Register a user (if not already registered)
print(f"\n--- Registering user: {USERNAME} ---")
register_response = register_user(BASE_URL, USERNAME, PASSWORD)
if register_response and register_response.status_code == 200:
print("User registered successfully.")
elif register_response and register_response.status_code == 409: # 409 Conflict if user already exists
print("User already registered (skipping registration).")
else:
print("User registration failed.")
# Exit if registration failed and we can't proceed
exit()

# 2. Login the user to get an access token
print(f"\n--- Logging in user: {USERNAME} ---")
login_data = login_user(BASE_URL, USERNAME, PASSWORD)
access_token = None
if login_data and "access_token" in login_data:
access_token = login_data["access_token"]
print("Login successful. Access Token obtained.")
else:
print("Login failed. Cannot proceed with creating polls.")
exit()

# 3. Create a poll (requires authentication)
if access_token:
print("\n--- Creating a new poll ---")
poll_question = "What's your favorite programming language?"
poll_options = ["Python", "JavaScript", "Java", "C++", "Rust"]
new_poll = create_poll(BASE_URL, poll_question, poll_options, access_token)

if new_poll:
print("Poll created successfully:")
print(f" Poll ID: {new_poll['id']}")
print(f" Question: {new_poll['question']}")
print(" Options:")
for option in new_poll['options']:
print(f" - {option['text']} (ID: {option['id']})")
else:
print("Failed to create poll.")
else:
print("No access token available. Skipping poll creation.")


# --- Previous Poll Results Display Example (uncomment to use) ---
# poll_id_to_display = 1 # Replace with an actual poll_id from your database
# results = get_poll_results(BASE_URL, poll_id_to_display)

# if results:
# print(f"\n--- Results for Poll ID: {results['poll_id']} ---")
# print(f"Question: {results['question']}")
# print("Options:")
# for option_result in results['results']:
# print(f" - {option_result['text']} (Votes: {option_result['vote_count']})")
# else:
# print(f"Failed to retrieve results for Poll ID {poll_id_to_display}.")
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ sqlalchemy
pydantic
passlib[bcrypt]
jwt
python-dotenv
python-jose
python-dotenv
requests