From da1b13279b9665d66b241c4cf78b22fc5752ea8a Mon Sep 17 00:00:00 2001 From: garrettAdmin Date: Mon, 30 Jun 2025 20:36:27 +0000 Subject: [PATCH] initial commit to upload to move to public repository --- unwrap_challenge.py | 165 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 unwrap_challenge.py diff --git a/unwrap_challenge.py b/unwrap_challenge.py new file mode 100644 index 0000000..72401d6 --- /dev/null +++ b/unwrap_challenge.py @@ -0,0 +1,165 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from typing import List +from datetime import date +from uuid import uuid4 + +app = FastAPI() + + + +class Book(BaseModel): + title: str + author: str + isbn: str + copies: int + +class BookResponse(Book): + available_copies: int + +class Customer(BaseModel): + name: str + email: str + customer_id: str + +class CheckoutRequest(BaseModel): + isbn: str + customer_id: str + due_date: str + +class CheckoutResponse(BaseModel): + checkout_id: str + isbn: str + title: str + customer_id: str + checkout_date: str + due_date: str + +class ReturnRequest(BaseModel): + isbn: str + customer_id: str + + + +books = {} +customers = {} +checkouts = [] + + + +def get_book(isbn: str): + if isbn not in books: + raise HTTPException(status_code=404, detail="Book not found") + return books[isbn] + +def get_customer(customer_id: str): + if customer_id not in customers: + raise HTTPException(status_code=404, detail="Customer not found") + return customers[customer_id] + +def enforce_business_rules(customer_id: str, isbn: str): + customer_books = [c for c in checkouts if c["customer_id"] == customer_id] + if len(customer_books) >= 5: + raise HTTPException(status_code=400, detail="Customer has too many books checked out") + if books[isbn]["available_copies"] <= 0: + raise HTTPException(status_code=400, detail="No copies available") + + + +@app.post("/api/books", response_model=BookResponse, status_code=201) +def add_book(book: Book): + if book.isbn in books: + raise HTTPException(status_code=400, detail="Book already exists") + books[book.isbn] = book.dict() + books[book.isbn]["available_copies"] = book.copies + return books[book.isbn] + +@app.get("/api/books/{isbn}", response_model=BookResponse) +def get_book_details(isbn: str): + return get_book(isbn) + + + +@app.post("/api/customers", response_model=Customer, status_code=201) +def create_customer(customer: Customer): + if customer.customer_id in customers: + raise HTTPException(status_code=400, detail="Customer already exists") + customers[customer.customer_id] = customer.dict() + return customer + + +@app.get("/api/customers/{customer_id}", response_model=Customer) +def get_customer_details(customer_id: str): + return get_customer(customer_id) + + + +@app.post("/api/checkouts", response_model=CheckoutResponse, status_code=201) +def checkout_book(request: CheckoutRequest): + book = get_book(request.isbn) + get_customer(request.customer_id) + enforce_business_rules(request.customer_id, request.isbn) + + checkout_id = "CKO" + uuid4().hex[:6].upper() + checkout_date = date.today().isoformat() + + books[request.isbn]["available_copies"] -= 1 + checkout = { + "checkout_id": checkout_id, + "isbn": request.isbn, + "title": book["title"], + "customer_id": request.customer_id, + "checkout_date": checkout_date, + "due_date": request.due_date + } + checkouts.append(checkout) + return checkout + + + + + +@app.post("/api/returns") +def return_book(request: ReturnRequest): + for i, c in enumerate(checkouts): + if c["isbn"] == request.isbn and c["customer_id"] == request.customer_id: + checkouts.pop(i) + books[request.isbn]["available_copies"] += 1 + return { + "message": "Book returned successfully", + "isbn": request.isbn, + "customer_id": request.customer_id, + "return_date": date.today().isoformat() + } + raise HTTPException(status_code=404, detail="Borrow record not found") + + + + +@app.get("/api/customers/{customer_id}/books") +def get_customer_books(customer_id: str): + get_customer(customer_id) + return [ + { + "isbn": c["isbn"], + "title": c["title"], + "author": books[c["isbn"]]["author"], + "checkout_date": c["checkout_date"], + "due_date": c["due_date"] + } + for c in checkouts if c["customer_id"] == customer_id + ] + + + + + + + + +@app.post("/api/reset") +def reset_system(): + books.clear() + customers.clear() + checkouts.clear() + return {"message": "System reset successful"}