DEV Community

Emmanuel Buah-Kwofie
Emmanuel Buah-Kwofie

Posted on

Introducing Flask-Nova: Zero-Boilerplate APIs with Docs & Type Safety

Flask is celebrated for its simplicity and flexibility, but let's be honest, building a modern API with features like authentication, validation, and comprehensive documentation often becomes a repetitive chore.

That's why I created Flask-Novaβ€”a modern extension for Flask designed to accelerate API development. It comes with automatic OpenAPI documentation and type-safe input models built right in, so you can focus on what matters: your application's logic.

πŸ”— PyPI: https://pypi.org/project/flask-nova/

πŸ’» GitHub: https://github.com/manitreasure1/flasknova

πŸ“˜ Example App: https://github.com/manitreasure1/flask-nova-tutorials

πŸ”₯ Key Features

  • βœ… Auto-generated Swagger docs (/docs): Get interactive API documentation, enabled with a single line of code and easily customizable.
  • βœ… Typed route inputs using Pydantic-style models: Ensure data integrity with clear, concise type hints.
  • βœ… Decorator-based routing with zero boilerplate: Define your routes cleanly and efficiently.
  • βœ… Built-in HTTPException for clean error handling: Manage API errors gracefully.
  • βœ… status helpers (e.g., status.CREATED): Use semantic HTTP status codes easily.
  • βœ… Depend() for clean dependency injection: Organize your code with reusable components.
  • βœ… Extensible and Pythonic design: Enjoy a familiar and flexible development experience.
  • βœ… Compatible with native Flask: Seamlessly integrate with your existing Flask projects.

πŸš€ Installation
pip install flask-nova

Code Examples
Basic Route with Type-Safe Input
This example shows how to define a route that automatically validates incoming request data based on a Pydantic-style model.

from flask_nova import FlakNova, NovaBlueprint
app = FlaskNova(__name__)
route = NovaBlueprint("dev",__name__)
class RegisterData(RequestModel):
    username: str
    email: str
@route.post("/register")
def register(data: RegisterData):
    return {"msg": "User registered", "data": data.model_dump()}

# Register the blueprint (assuming 'app' is your FlaskNova instance)
app.register_blueprint(route)

# To run this minimal example:
# if __name__ == "__main__":
#     app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

This endpoint automatically validates the incoming request, and its JSON schema is included in the auto-generated API documentation.

Dependecy Injection
Leverage Depend() to inject dependencies into your route functions, making your code modular and testable.

from flask_nova import Depend,FlaskNova NovaBlueprint

app = FlaskNova(__name__) # Use Flask for the base app
route = NovaBlueprint("dev", __name__)

def get_current_user():
    # In a real app, this would fetch the authenticated user
    return {"id": 1, "username": "admin"}

@route.get("/me")
def me(user=Depend(get_current_user)):
    return {"user": user}

# Register the blueprint
app.register_blueprint(route)

# if __name__ == "__main__":
#     app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

Route Metadata: Summary, Description, and Response Model
Enhance your API documentation by adding a summary, description, response_model, and tags to your routes.

from flask_nova import FlaskNova NovaBlueprint
from pydantic import BaseModel

app = FlaskNova(__name__) 
auth_bp = NovaBlueprint("auth", __name__)

class LoginInput(BaseModel):
    username: str
    password: str

class LoginOut(BaseModel):
    access_token: str
    refresh_token: str

@auth_bp.route(
    "/login",
    methods=["POST"],
    summary="Login user",
    description="Authenticate user and return JWT access and refresh tokens.",
    response_model=LoginOut,
    tags=["Auth"]
)
def login(data: LoginInput):
    # In a real application, this would handle user authentication
    return {"access_token": "abc.123.xyz", "refresh_token": "def.456.uvw"}

# Register the blueprint
app.register_blueprint(auth_bp)

# if __name__ == "__main__":
#     app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

Error Handling with HTTPException and status Helpers

from flask_nova import route, FlaskNova, NovaBlueprint, HTTPException, status

app = FlaskNova(__name__)
api = NovaBlueprint("api", __name__)

items = {
    1: {"id": 1, "name": "Item One"},
    2: {"id": 2, "name": "Item Two"}
}

@api.route("/items/<int:item_id>", methods=["GET"])
def get_item(item_id: int):
    item = items.get(item_id)
    if not item:
        raise HTTPException(
            status_code=status.NOT_FOUND,
            detail=f"Item {item_id} not found",
            title="Not Found"
        )
    return item

@api.route("/items", methods=["POST"])
def create_item():
    new_id = max(items.keys()) + 1
    item = {"id": new_id, "name": f"Item {new_id}"}
    items[new_id] = item
    return item, status.CREATED

app.register_blueprint(api)

# if __name__ == "__main__":
#     app.run(debug=True)

Enter fullscreen mode Exit fullscreen mode

Common status Codes
Flask-Nova includes a status module for easy access to common HTTP status codes.

from flask_nova import status

print(status.OK)                  # 200
print(status.CREATED)             # 201
print(status.NO_CONTENT)          # 204
print(status.BAD_REQUEST)         # 400
print(status.UNAUTHORIZED)        # 401
print(status.FORBIDDEN)           # 403
print(status.NOT_FOUND)           # 404
print(status.CONFLICT)            # 409
print(status.UNPROCESSABLE_ENTITY)# 422
print(status.INTERNAL_SERVER_ERROR) # 500
Enter fullscreen mode Exit fullscreen mode

Built-in logging
Flask-Nova integrates a simple, colorful logging system for better development feedback.

from flask_nova import get_flasknova_logger
log = get_flasknova_logger()
#or simply: from flask_nova import logger
Enter fullscreen mode Exit fullscreen mode
  • βœ… This endpoint is automatically validated
  • βœ… JSON schema is included in the docs
  • βœ… Swagger UI available at /docs

Why Flask-Nova?
As a Flask developer, I deeply appreciate its flexibility. However, I consistently found myself repeating the same setup tasks across every project:

  1. Manually parsing request data.
  2. Writing input validators from scratch.
  3. Setting up Swagger UI.
  4. Implementing JWT authentication logic.
  5. Documenting routes by hand.

I built Flask-Nova to eliminate this friction. Now, I can:

  • Focus on writing real features
  • Get fully-documented APIs out of the box
  • Maintain a Pythonic and type-safe codebase.

Configuration Tips
Flask-Nova allows easy customization of your API environment:

Enable and Customize Swagger UI
To make your API documentation available at /docs (or a custom route), you need to call app.setup_swagger(). This method also allows you to customize the API's title, description, version, and other important metadata.

if __name__ == '__main__':
    app.setup_swagger(info={
        "title": "FlaskNova API test",
        "version": "1.2.3",
        "description": "Beautiful API for modern apps.",
        "termsOfService": "https://example.com/terms",
        "contact": {
            "name": "Team FlaskNova",
            "url": "https://github.com/flasknova",
            "email": "support@flasknova.dev"
        },
        "license": {
            "name": "MIT",
            "url": "https://opensource.org/licenses/MIT"
        }
    })
    # app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

Change Swagger UI Route
By default, your API documentation is served at /docs. You can change this by setting the following environment variable:

FLASKNOVA_SWAGGER_ROUTE=/api-docs
Now your docs will be available at /api-docs instead.

Disable Docs in Production

To prevent exposing internal documentation in production, simply disable the Swagger UI with:
FLASKNOVA_SWAGGER_ENABLED=False

This will hide the auto-generated docs while keeping your API fully functional.

πŸ§ͺ Example App
If you want to see Flask-Nova in action, check out this simple example app repository:
πŸ‘‰ Flask-Nova Example App on GitHub
https://github.com/manitreasure1/flask-nova-tutorials.git

πŸ™ Feedback & Contributions Welcome
Flask-Nova is an open-source passion project, and I'd love your help to make it even better!

If you:

  • Like the idea β†’ Please ⭐ the GitHub repo
  • Found a bug β†’ Open an issue
  • Have an idea β†’ Let's discuss! Want to contribute β†’ Pull Requests are always welcome!

GitHub: https://github.com/manitreasure1/flasknova

PyPI: https://pypi.org/project/flask-nova/

Top comments (0)