Table of contents
- About
- Quick start (local)
- Configuration
- Running the app
- API overview
- Authentication
- Example requests
- Development
- Tests
- Project structure
- Contributing
- License
Bookly (aka BookClub API) is a Django REST Framework backend that powers a social reading/book-exchange platform. It provides user authentication (email + Google OAuth), profile management, book management, genres, and an exchange/book-request flow.
This README was generated from an analysis of the repository code and aims to provide a concise, actionable reference for local development and integration.
Prerequisites
- Python 3.8+
- pip
- (Optional) virtualenv
- Clone the repository
git clone https://github.com/Kiprotich-Code/bookly.git
cd bookly- Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate- Install dependencies
If requirements.txt exists in your root, install it. If not, install the common dependencies used by the project:
pip install django djangorestframework djangorestframework-simplejwt django-cors-headers django-allauth dj-rest-auth- Apply migrations and create a superuser
python manage.py migrate
python manage.py createsuperuser- Run the development server
python manage.py runserverThe API will be available at http://127.0.0.1:8000/ by default.
The project stores Django settings in bookclub_api/settings.py. Relevant configuration items:
AUTH_USER_MODEL = 'accounts.User'— custom user model.REST_FRAMEWORKuses TokenAuthentication and SessionAuthentication.INSTALLED_APPSincludesrest_framework,rest_framework.authtoken,corsheaders,allauth,dj_rest_auth, and the local appsaccounts,books,copies.
Environment variables and secrets (e.g., SECRET_KEY, GOOGLE_CLIENT_ID) are expected to be provided in your environment or a .env file (not included).
Start the server locally
python manage.py runserverAccess the Django admin at /admin/ after creating a superuser.
Root mounting points (from bookclub_api/urls.py):
/admin/— Django admin/books/— Books and genres API (viewsets)/exchange/— Book exchange / requests (viewsets)/accounts/— Authentication and user profile endpoints
Accounts endpoints (accounts/urls.py):
POST /accounts/auth/register/— register (returnstoken,user_id,email,is_profile_complete)POST /accounts/auth/login/— login (supportstype: 'email'ortype: 'google'; returnstoken,user_id,email,is_google,is_profile_complete)POST /accounts/auth/logout/— logout (requires auth)POST /accounts/auth/password/reset/— start password reset flowPOST /accounts/auth/link-account/— link Google account to authenticated userGET /accounts/user/profile/— get current authenticated user's profile (returnsuserobject andtoken)
Books endpoints (router at /books/):
GET /books/books/— list booksPOST /books/books/— create book (authenticated)GET /books/books/{id}/— retrieve bookPUT/PATCH/DELETE /books/books/{id}/— update/delete (owner-only)GET /books/books/my_books/— list books belonging to authenticated userGET /books/genres/— list/create genres
Exchange endpoints (router at /exchange/):
- Resource registered at root of the app (see
copies.views.BookRequestViewSet) for creating and managing book requests.
This project uses Token Authentication by default. When a user registers or logs in, the API returns a token. Include it in requests with the header:
Authorization: Token <token>
Example: fetch current user's profile
GET /accounts/user/profile/
Authorization: Token b42cb92f8851c1aa7320d53fc9fce2318f7dccfeResponse shape (abridged):
{
"user": {
"id": 2,
"username": "James",
"email": "[email protected]",
"name": "James",
"bio": "Test bio!",
"location": "Nairobi, Kenya",
"favorite_genres": ["Fiction","Non-Fiction","Science Fiction","Fantasy","Mystery"],
"profile_picture": null,
"member_since": "2025-07-05T18:12:57.227096Z",
"privacy_settings": {"show_email": true, "show_location": true, "show_reading_stats": true},
"reading_goal": 12,
"books_read": 0,
"total_swaps": 0,
"average_rating": 0
},
"token": "b42cb92f8851c1aa7320d53fc9fce2318f7dccfe"
}Register (email):
curl -X POST http://127.0.0.1:8000/accounts/auth/register/ \
-H "Content-Type: application/json" \
-d '{"username":"james","email":"[email protected]","password":"securepass"}'Login (email):
curl -X POST http://127.0.0.1:8000/accounts/auth/login/ \
-H "Content-Type: application/json" \
-d '{"type":"email","email":"[email protected]","password":"securepass"}'Get profile (JS fetch example):
fetch('/accounts/user/profile/', {
headers: { 'Authorization': `Token ${token}` }
})
.then(r => r.json())
.then(console.log)- Code is organized into Django apps:
accounts,books,copies. - Custom user model lives at
accounts.models.Userand usesemailas theUSERNAME_FIELD. accounts.serializers.UserProfileSerializercontrols the profile representation returned by/accounts/user/profile/.
Recommended development workflow
- Create a branch
- Run tests
- Open a PR with a clear description and linked issue
Run Django tests with:
python manage.py testbookclub_api/ # Django project
accounts/ # custom user, auth, profile
books/ # book and genre models, viewsets
copies/ # exchange / request flow
manage.py
db.sqlite3 # local sqlite DB (development)
Contributions are welcome. Please open issues for bugs or feature requests and submit pull requests for fixes.
This project is licensed under the MIT License — see LICENSE for details.