Operational Notes and Troubleshooting
This section guides you through safely extending and maintaining your Flask-based library API. It covers model updates, resource registration, JWT protection, and database schema changes. Follow these best practices to avoid runtime errors and data loss.
Extending the API Safely
To add new features without breaking existing endpoints:
- Add or modify models under
PYTHON/models/. - Create corresponding resources under
PYTHON/resources/. - Register new resources in
app.py. - Secure endpoints with JWT where needed.
- Handle schema changes mindfully.
Adding New Models and Fields 🛠️
When introducing new domain entities or fields:
- Create a new Python module in
PYTHON/models/. - Define a SQLAlchemy model subclassing
db.Model. - Add
db.Columndefinitions for each attribute. - Update the
json()method to control output.
# PYTHON/models/author.py
from db import db
class AuthorModel(db.Model):
__tablename__ = 'authors'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
bio = db.Column(db.Text)
def __init__(self, name, bio):
self.name = name
self.bio = bio
def json(self):
return {
'id': self.id,
'name': self.name,
'bio': self.bio
}
The
json()method shapes API responses. Always include new fields here .
Registering New Resources 🔗
Every model needs a matching RESTful resource:
- Create a module in
PYTHON/resources/. - Subclass
flask_restful.Resource. - Implement HTTP methods (
get,post,put,delete).
# PYTHON/resources/author.py
from flask_restful import Resource, reqparse
from models.author import AuthorModel
class Author(Resource):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, help="Name cannot be blank.")
parser.add_argument('bio', type=str)
def get(self, id):
author = AuthorModel.query.get(id)
if author:
return author.json()
return {'message': 'Author not found'}, 404
def post(self):
data = Author.parser.parse_args()
author = AuthorModel(**data)
author.save_to_db()
return author.json(), 201
Then register it in app.py:
# PYTHON/app.py
api.add_resource(Author, '/author/<int:id>')
This mirrors the existing registration of books and stores .
Securing Endpoints with JWT 🔒
Protect sensitive routes with JWT authentication:
-
Import the decorator:
from flask_jwt import jwt_required -
Apply it to resource methods that require auth:
class Author(Resource): @jwt_required() def post(self): # Protected creation logic ... -
Ensure clients obtain tokens via
/authand include:Authorization: JWT <access_token>
This pattern matches the Book resource protection .
{
"title": "Authentication Tip",
"content": "Always test protected endpoints with and without a valid JWT."
}
Database Schema Changes 🗄️
SQLite does not support automatic migrations. When you change models:
- Backup your data file.
- Delete the existing database:
rm data.db - Recreate tables on next run:
python app.py - For production, consider integrating Alembic or Flask-Migrate.
| Action | Command | Note |
|---|---|---|
| Delete DB file | rm data.db |
Backup first! |
| Recreate tables | python app.py |
Uses @app.before_first_request hook |
| Integrate migrations | pip install Flask-Migrate |
Out of tutorial scope |
{
"title": "Migration Warning",
"content": "Deleting the DB clears all data. Backup before running this step."
}
Troubleshooting Common Issues
-
Missing fields in JSON
You forgot to updatejson()after adding columns. -
404 on new endpoint
Ensure you calledapi.add_resource(...)inapp.py. -
Unauthorized errors
Verify@jwt_required()decorates the correct methods and that tokens are valid. -
“no such column” errors
The SQLite schema is stale. Recreate or migrate the database.
{
"title": "Pro Tip",
"content": "Use `db.session.rollback()` in exception blocks to prevent stale sessions."
}
By following these guidelines, you’ll maintain a robust, secure, and extendable API.