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.Column definitions 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 /auth and 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 update json() after adding columns.

  • 404 on new endpoint
    Ensure you called api.add_resource(...) in app.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.