Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StayHub API

Repository name: python-booking
Project name: StayHub API — a property rental and booking backend inspired by platforms like Airbnb.

StayHub is a REST API backend for a property rental and booking website. Guests can search listings, save favorites, book stays, and leave reviews. Hosts can publish properties and manage booking requests. Admins can inspect users, bookings, and platform statistics.

The codebase is intentionally small and readable: FastAPI routers handle HTTP, Pydantic schemas validate input/output, SQLAlchemy models define persistence, and service functions hold booking and auth business logic.


Why two names?

Name Where it appears Purpose
python-booking GitHub repository Generic, searchable repo name for portfolio and job applications
StayHub API Documentation, Swagger UI, project branding Describes what the system actually does

The internal code still uses stayfinder in a few places (database filename, logger name) from an earlier working title. Functionality is unchanged — only the public project name was refined for clarity.


Architecture & codebase mindset

This project follows a thin router, fat service pattern common in production FastAPI apps.

HTTP Request
    │
    ▼
Router (app/routers/)     ← routing, auth dependencies, status codes
    │
    ▼
Service (app/services/)   ← business rules, validation, pricing, overlap checks
    │
    ▼
Model (app/models/)       ← SQLAlchemy ORM entities and relationships
    │
    ▼
Database (SQLite / PostgreSQL)

Layer responsibilities

Layer Role Example
Routers Map URLs to handlers; never embed complex logic POST /bookings calls booking_service.create_booking()
Schemas Request/response contracts with Pydantic BookingCreate, PropertyRead, pagination wrappers
Services Domain rules isolated from HTTP Date overlap detection, nightly price calculation, role checks
Models Database tables and relationships User, Property, Booking, Review, Favorite
Dependencies Reusable auth (get_current_user, require_host, require_admin) JWT Bearer token → current user
Exceptions Typed errors → consistent JSON responses ConflictError → HTTP 409

Design decisions

  • Half-open date ranges — stays use [check_in, check_out), so checkout day does not block the next guest's check-in.
  • Server-side pricing — clients send dates and guest count; the API computes nights × price_per_night.
  • Role-based access — three roles (guest, host, admin) enforced via FastAPI dependencies, not scattered if checks in routers.
  • Active booking lock — only pending and confirmed bookings block availability; cancelled and completed stays free the calendar.
  • Database portability — SQLite for local dev and tests; PostgreSQL supported via DATABASE_URL for production-style setups.

Project structure

python-booking/
├── app/
│   ├── main.py              # FastAPI app, CORS, global exception handlers
│   ├── config.py            # Settings from .env (Pydantic Settings)
│   ├── database.py          # SQLAlchemy engine and session
│   ├── dependencies.py      # JWT auth and role guards
│   ├── exceptions.py        # AppError hierarchy → HTTP status codes
│   ├── models/              # SQLAlchemy ORM models
│   ├── schemas/             # Pydantic request/response models
│   ├── routers/             # API route modules by domain
│   └── services/            # Business logic (auth, booking, property)
├── tests/                   # Pytest suite (in-memory SQLite)
├── alembic/                 # Database migrations
├── seed.py                  # Sample users, properties, bookings, reviews
├── requirements.txt
├── .env.example
└── README.md

Features

  • JWT authentication with bcrypt password hashing
  • Role-based access for guests, hosts, and admins
  • Property search with filters, sorting, and pagination
  • Favorite listings
  • Availability checks with date-overlap detection
  • Booking creation, cancellation, and host confirmation workflow
  • Automatic nightly price calculation
  • Reviews after completed stays (one review per guest per property)
  • Admin user list, booking list, and dashboard statistics
  • Alembic migrations and a sample data seed script

Technology stack

  • Python 3.11+
  • FastAPI
  • SQLAlchemy 2.x
  • PostgreSQL (SQLite supported locally)
  • Pydantic v2
  • JWT (python-jose)
  • Pytest
  • Alembic
  • Uvicorn
  • Passlib / bcrypt

Installation

Requires Python 3.11 or newer.

Clone the project

git clone https://github.com/web-master00/python-booking.git
cd python-booking

Create a virtual environment

Linux / macOS:

python -m venv venv
source venv/bin/activate

Windows:

python -m venv venv
venv\Scripts\activate

Install dependencies

pip install -r requirements.txt

Configure environment variables

cp .env.example .env

The default .env uses SQLite:

DATABASE_URL=sqlite:///./stayfinder.db
SECRET_KEY=change_this_secret_key_to_a_long_random_value
ACCESS_TOKEN_EXPIRE_MINUTES=60

To use PostgreSQL, set DATABASE_URL to a connection string such as:

DATABASE_URL=postgresql+psycopg2://postgres:postgres@localhost:5432/stayfinder

Change SECRET_KEY before deploying.

Run database migrations

alembic upgrade head

Seed sample data

python seed.py

This creates an admin, two hosts, several guests, 10 properties, bookings, and reviews.

All seeded accounts use the password Password123!.

Email Role
admin@stayfinder.com admin
maria.host@stayfinder.com host
james.host@stayfinder.com host
emma.guest@stayfinder.com guest
liam.guest@stayfinder.com guest
sophia.guest@stayfinder.com guest
noah.guest@stayfinder.com guest

Run the API

uvicorn app.main:app --reload

Open API documentation

Swagger UI:

http://127.0.0.1:8000/docs

ReDoc:

http://127.0.0.1:8000/redoc

Use the Authorize button in Swagger and paste a Bearer token returned by POST /auth/login.


Running tests

pytest

Tests use an in-memory SQLite database and cover registration, login, property permissions, booking validation, and date conflicts.


API endpoints

Authentication

Method Endpoint Description
POST /auth/register Register a guest or host
POST /auth/login Log in and receive a JWT
GET /auth/me Return the authenticated user

Users

Method Endpoint Description
GET /users/me Get the current profile
PUT /users/me Update name or email

Properties

Method Endpoint Description
GET /properties Search, filter, sort, and paginate listings
GET /properties/{property_id} Property details, host info, and ratings
POST /properties Create a listing (host or admin)
PUT /properties/{property_id} Update a listing (owner or admin)
DELETE /properties/{property_id} Delete a listing (owner or admin)
GET /properties/{property_id}/availability Check date availability

Query parameters for GET /properties include search, city, country, property_type, min_price, max_price, guests, min_bedrooms, sort (price_low, price_high, newest), page, and page_size.

Favorites

Method Endpoint Description
GET /favorites List saved properties
POST /favorites/{property_id} Add a favorite
DELETE /favorites/{property_id} Remove a favorite

Bookings

Method Endpoint Description
POST /bookings Create a booking
GET /bookings/me List the current user's bookings
GET /bookings/{booking_id} Booking details
PUT /bookings/{booking_id}/cancel Cancel a booking as the guest

Reviews

Method Endpoint Description
GET /properties/{property_id}/reviews List reviews for a property
POST /properties/{property_id}/reviews Create a review after a completed stay
PUT /reviews/{review_id} Update a review (owner)
DELETE /reviews/{review_id} Delete a review (owner or admin)

Host

Method Endpoint Description
GET /host/bookings Bookings for the host's properties
PUT /host/bookings/{booking_id}/confirm Confirm a pending request
PUT /host/bookings/{booking_id}/cancel Reject or cancel a request
PUT /host/bookings/{booking_id}/complete Mark a confirmed stay as completed

Admin

Method Endpoint Description
GET /admin/users Paginated user list
GET /admin/bookings All bookings, with optional status filter
GET /admin/statistics Platform totals

Health

Method Endpoint Description
GET /health Liveness check

Booking rules

  • Check-in must be before check-out and cannot be in the past.
  • Guest count must be at least 1 and cannot exceed the listing's max_guests.
  • Total price is number_of_nights × price_per_night. Clients do not send a price.
  • Pending and confirmed bookings block overlapping dates.
  • Cancelled and completed bookings do not block availability.
  • Date ranges are half-open: a stay ending on the 15th does not block a new stay starting on the 15th.

Roles

Role Capabilities
guest Search, favorite, book, cancel own bookings, review completed stays
host Everything a guest can do, plus create and manage listings and booking requests
admin Platform-wide user, booking, and statistics access

Admin accounts cannot be created through public registration. Use the seed script or insert one directly in the database.

Error handling

The API returns JSON {"detail": "..."} with these status codes:

Code Meaning
400 Invalid request (for example past dates or too many guests)
401 Missing or invalid token
403 Authenticated but not allowed
404 Resource not found
409 Conflict (duplicate email, overlapping booking, duplicate favorite)
422 Validation error
500 Unexpected server error

Author

Built and maintained by codemaster — @web-master00


License

This project is provided as a demonstration example for portfolio and learning purposes.

About

Production-style FastAPI REST API for property rental and booking — listings, reservations, favorites, reviews, and role-based access for guests, hosts, and admins.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages