<p align="center">
<img src="./images/fastblocks-logo.png" alt="FastBlocks Logo">
</p>
> **FastBlocks Documentation**: [Main](./README.md) | [Core Features](./fastblocks/README.md) | [Actions](./fastblocks/actions/README.md) | [Adapters](./fastblocks/adapters/README.md)
# FastBlocks
[](https://github.com/lesleslie/crackerjack)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/BSD-3-Clause)
## What is FastBlocks?
FastBlocks is an asynchronous web application framework, inspired by FastAPI and built on Starlette, specifically designed for the rapid delivery of server-side rendered HTMX/Jinja template blocks. It combines modern Python async capabilities with server-side rendering to create dynamic, interactive web applications with minimal JavaScript.
Unlike monolithic frameworks or micro-frameworks that require extensive configuration, FastBlocks offers a modular, component-based architecture that provides batteries-included functionality while maintaining exceptional flexibility. Its adapter pattern allows for seamless component swapping, cloud provider migrations, and tailored customizations without extensive code changes.
## Key Concepts
If you're new to FastBlocks, here are the key concepts to understand:
1. **Server-Side Rendering**: Unlike frameworks that rely heavily on JavaScript for interactivity, FastBlocks renders HTML on the server and sends only what's needed to the browser.
2. **HTMX**: A lightweight JavaScript library that allows you to access modern browser features directly from HTML, without writing JavaScript. FastBlocks is built with HTMX in mind.
3. **Template Blocks**: Small pieces of HTML that can be rendered independently and injected into the page, enabling dynamic updates without full page reloads.
4. **Adapters**: Pluggable components that provide standardized interfaces to different implementations (templates, authentication, admin interfaces, etc.). This architecture facilitates seamless provider switching, multi-cloud deployments, and targeted customizations without restructuring your application.
5. **Dependency Injection**: A pattern that automatically provides components to your functions when needed, reducing boilerplate code.
6. **Asynchronous Architecture**: Built on Python's async/await syntax for high performance and efficient handling of concurrent requests.
## Key Features
- **Starlette Foundation**: Built on the [Starlette](https://www.starlette.io/) ASGI framework for high performance, extending its application class and middleware system
- **HTMX Integration**: First-class support for HTMX to create dynamic interfaces with server-side rendering
- **Asynchronous Architecture**: Built on [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb), providing dependency injection, configuration management, and pluggable components
- **Template-Focused**: Advanced asynchronous Jinja2 template system with fragments and partials support using `[[` and `]]` delimiters
- **Modular Design**: Pluggable adapters for authentication, admin interfaces, routing, templates, and sitemap generation
- **Cloud Flexibility**: Easily switch between cloud providers or create hybrid deployments by swapping adapters
- **Performance Optimized**: Built-in caching system, Brotli compression, and HTML/CSS/JS minification
- **Type Safety**: Leverages Pydantic v2 for validation and type safety throughout
- **Admin Interface**: Integrated SQLAlchemy Admin support for database management
- **Dependency Injection**: Robust dependency injection system with automatic resolution
- **Batteries Included, But Replaceable**: Comprehensive defaults with the ability to customize or replace any component
## Why Choose FastBlocks?
FastBlocks stands out from other Python web frameworks through its unique combination of server-side rendering focus, component-based architecture, and hybrid cloud capabilities. Here's how FastBlocks compares to other popular frameworks:
### FastBlocks vs. FastAPI
While FastAPI excels at API development, FastBlocks is specifically designed for server-side rendered applications with HTMX:
| Aspect | FastBlocks | FastAPI |
|--------|------------|---------|
| **Primary Focus** | Server-side rendering + HTMX | JSON APIs + OpenAPI |
| **Template System** | Built-in async Jinja2 with HTMX support | External template engines required |
| **Component Architecture** | Pluggable adapters for all components | Manual dependency injection setup |
| **Cloud Flexibility** | Built-in adapter system for multi-cloud | Cloud integration requires custom solutions |
| **Frontend Approach** | HTMX for dynamic interfaces | Requires separate frontend framework |
| **Development Speed** | Rapid HTML-first development | Fast API development, slower frontend integration |
| **SEO Support** | Native server-side rendering | Requires additional SSR setup |
| **Learning Curve** | Simple HTML + Python | API design + frontend framework |
**Choose FastBlocks when:** You want to build interactive web applications with server-side rendering, need rapid development of admin interfaces, or prefer keeping business logic on the server.
**Choose FastAPI when:** You're building APIs for mobile apps, need extensive OpenAPI documentation, or are creating microservices.
### FastBlocks vs. FastHTML
FastHTML focuses on Python-in-HTML, while FastBlocks uses a traditional template-based approach:
| Aspect | FastBlocks | FastHTML |
|--------|------------|----------|
| **Template Approach** | Jinja2 templates with custom delimiters | Python functions generate HTML |
| **Separation of Concerns** | Clear separation of logic and presentation | Logic and presentation mixed |
| **Designer Collaboration** | HTML/CSS designers can work directly | Requires Python knowledge for frontend |
| **Template Ecosystem** | Full Jinja2 ecosystem and tooling | Limited to Python HTML generation |
| **Component Reusability** | Template blocks and inheritance | Python function composition |
| **Infrastructure Flexibility** | Adapter pattern for all components | Monolithic approach |
| **Cloud Deployment** | Built-in multi-cloud support | Manual cloud configuration |
| **Performance** | Async template caching and optimization | Runtime HTML generation |
**Choose FastBlocks when:** You work with designers, need template reusability, want infrastructure flexibility, or prefer traditional template-based development.
**Choose FastHTML when:** You prefer Python-only development, want inline HTML generation, or are building simple prototypes.
### FastBlocks vs. FastHX
FastHX provides HTMX utilities for FastAPI, while FastBlocks is a complete framework built around HTMX:
| Aspect | FastBlocks | FastHX |
|--------|------------|--------|
| **Framework Scope** | Complete web framework | HTMX utilities for FastAPI |
| **Template Integration** | Built-in async template system | Requires separate template setup |
| **Component Architecture** | Full adapter system | Limited to HTMX helpers |
| **Cloud Deployment** | Built-in multi-cloud adapters | Relies on FastAPI deployment |
| **Development Workflow** | Integrated HTMX + templates | Add-on to existing FastAPI |
| **Performance Optimization** | Built-in caching, compression, minification | Manual optimization required |
| **Admin Interface** | Integrated admin system | External admin interface needed |
| **Configuration Management** | ACB-based configuration system | FastAPI configuration |
**Choose FastBlocks when:** You want a complete HTMX-focused framework, need built-in admin interfaces, or want comprehensive infrastructure adapters.
**Choose FastHX when:** You have an existing FastAPI application and want to add HTMX capabilities incrementally.
### FastBlocks vs. FastHTMX
FastHTMX is another HTMX integration library, while FastBlocks is a complete framework:
| Aspect | FastBlocks | FastHTMX |
|--------|------------|----------|
| **Architecture** | Complete framework with adapters | HTMX integration library |
| **Template System** | Advanced async Jinja2 with fragments | Basic template integration |
| **Infrastructure** | Pluggable adapters for everything | Manual infrastructure setup |
| **Cloud Support** | Built-in multi-cloud capabilities | External cloud configuration |
| **Development Tools** | Full CLI, project generation, testing | Limited tooling |
| **Performance Features** | Caching, compression, minification | Basic HTMX support |
| **Admin Interface** | Integrated SQLAlchemy admin | No admin interface |
| **Dependency Injection** | ACB-based DI system | Manual dependency management |
**Choose FastBlocks when:** You want a batteries-included framework, need enterprise-grade features, or want rapid application development.
**Choose FastHTMX when:** You need a lightweight HTMX integration for an existing application.
### FastBlocks vs. Litestar
Litestar is a modern FastAPI alternative with native HTMX support, while FastBlocks focuses on server-side rendering:
| Aspect | FastBlocks | Litestar |
|--------|------------|----------|
| **Primary Focus** | Server-side rendering + HTMX | High-performance APIs |
| **Template System** | Built-in async templates with HTMX | External template engines |
| **HTMX Support** | Built-in HTMX integration | Native HTMX support |
| **Component Architecture** | Adapter pattern for flexibility | Plugin system |
| **Cloud Deployment** | Built-in multi-cloud adapters | Manual cloud integration |
| **Performance** | Optimized for SSR and HTMX | Optimized for API throughput |
| **Frontend Integration** | HTMX-first approach | API-first, frontend agnostic |
| **Development Experience** | HTML-first rapid development | Type-safe API development |
| **Infrastructure Flexibility** | Adapter-based infrastructure | Plugin-based extensions |
**Choose FastBlocks when:** You're building traditional web applications, need HTMX integration, or want infrastructure flexibility through adapters.
**Choose Litestar when:** You need high-performance APIs, want extensive type safety, or are building API-first applications.
### Key Advantages of FastBlocks
#### 🧩 **Component-Based Architecture**
- **Batteries Included, But Customizable**: Comprehensive defaults for rapid development, with every component easily replaceable
- **Pluggable Adapters**: Every component (auth, admin, templates, storage, cache) can be swapped without code changes
- **Consistent Interfaces**: Standardized APIs across all adapters ensure predictable behavior
- **Independent Evolution**: Update or replace individual components without affecting the entire application
- **Zero Lock-in**: Unlike monolithic frameworks, you're never locked into specific implementations
#### 🌐 **Multi-Cloud & Hybrid Deployment Ready**
- **Cloud Provider Flexibility**: Switch between AWS, Azure, GCP, or on-premise with configuration changes
- **Vendor Lock-in Prevention**: Abstract cloud-specific APIs behind adapter interfaces
- **Hybrid Strategies**: Mix and match services from different providers in the same application
- **Infrastructure as Code**: Configuration-driven infrastructure decisions
#### 🚀 **Server-Side Rendering Excellence**
- **HTMX-Native**: Built specifically for HTMX patterns and server-side rendering
- **Template Block Rendering**: Render specific template fragments for dynamic updates
- **SEO Optimized**: Full server-side rendering ensures search engine visibility
- **Progressive Enhancement**: Start with functional HTML, enhance with HTMX
#### ⚡ **Performance Optimized**
- **Async Everything**: Fully asynchronous template loading, caching, and rendering
- **Built-in Caching**: Redis-based template and response caching with configurable rules
- **Compression**: Brotli compression reduces payload sizes
- **Minification**: Built-in HTML, CSS, and JS minification
#### 🛠 **Developer Experience**
- **Rapid Development**: HTML-first approach with powerful template system
- **Full CLI**: Project generation, development server, testing, and deployment tools
- **Type Safety**: Pydantic-based configuration and validation throughout
- **Testing Support**: Comprehensive testing utilities and mocking framework
#### 🏢 **Enterprise Ready**
- **Configuration Management**: Multi-environment configuration with secrets management
- **Security Built-in**: CSRF protection, secure headers, session management
- **Admin Interface**: Integrated SQLAlchemy admin for database management
- **Monitoring**: Built-in integration with Sentry and Logfire
- **Deployment Options**: Docker, traditional servers, and cloud platforms
### When to Choose FastBlocks
FastBlocks is the ideal choice for:
- **Traditional Web Applications**: Where server-side rendering and SEO matter
- **Admin Dashboards**: Complex business logic with moderate UI complexity
- **Content Management Systems**: Where initial load performance is critical
- **Internal Tools**: Rapid development and maintenance are prioritized
- **Multi-Cloud Environments**: Organizations needing infrastructure flexibility
- **Team Collaboration**: Designers can work with HTML/CSS while developers handle Python logic
- **Prototype to Production**: Rapid prototyping that scales to enterprise needs
FastBlocks combines the development speed of modern frameworks with the infrastructure flexibility needed for enterprise deployment. Unlike monolithic frameworks that lock you into specific implementations, FastBlocks provides comprehensive defaults (batteries included) while maintaining the flexibility to customize or replace any component to suit your specific needs. This makes it an excellent choice for teams that want to move fast without sacrificing long-term flexibility or architectural control.
## Table of Contents
- [Why Choose FastBlocks?](#why-choose-fastblocks)
- [Key Concepts](#key-concepts)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Common Patterns](#common-patterns)
- [Architecture Overview](#architecture-overview)
- [Core Components](#core-components)
- [Templates](#templates)
- [Routing](#routing)
- [Middleware](#middleware)
- [HTMX Integration](#htmx-integration)
- [Adapters](#adapters)
- [Actions](#actions)
- [Configuration](#configuration)
- [Command-Line Interface (CLI)](#command-line-interface-cli)
- [Creating a New Project](#creating-a-new-project)
- [Running Your Application](#running-your-application)
- [CLI Options](#cli-options)
- [Migration Guide](#migration-guide)
- [Examples](#examples)
- [Documentation](#documentation)
- [License](#license)
- [Acknowledgements](#acknowledgements)
## Installation
Install FastBlocks using [pdm](https://pdm.fming.dev):
```bash
pdm add fastblocks
```
### Requirements
- Python 3.13 or higher
### Optional Dependencies
FastBlocks supports various optional dependencies for different features:
| Feature Group | Components | Installation Command |
|---------------|------------|----------------------|
| Admin | SQLAlchemy Admin interface | `pdm add "fastblocks[admin]"` |
| Sitemap | Automatic sitemap generation | `pdm add "fastblocks[sitemap]"` |
| Monitoring | Sentry and Logfire integration | `pdm add "fastblocks[monitoring]"` |
| Complete | All dependencies | `pdm add "fastblocks[admin,sitemap,monitoring]"` |
| Development | Development tools | `pdm add -G dev "fastblocks"` |
You can also install FastBlocks using pip:
```bash
pip install fastblocks
```
For optional dependencies with pip:
```bash
pip install "fastblocks[admin,sitemap,monitoring]"
```
## Quick Start
Let's build a simple FastBlocks application step by step:
### 1. Create Your Application File
Create a file named `myapp.py` with the following code:
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
# Import adapters - these are pluggable components that FastBlocks uses
# The Templates adapter handles rendering Jinja2 templates
# The App adapter provides the FastBlocks application instance
Templates = import_adapter("templates") # Get the configured template adapter
App = import_adapter("app") # Get the configured app adapter
# Define a route handler for the homepage
# The @depends.inject decorator automatically provides dependencies
@depends.inject
async def homepage(request, templates: Templates = depends()):
# Render a template and return the response
# This is similar to Flask's render_template but async
return await templates.app.render_template(
request, "index.html", context={"title": "FastBlocks Demo"}
)
# Define your application routes
routes = [
Route("/", endpoint=homepage) # Map the root URL to the homepage function
]
# Create a counter endpoint that demonstrates HTMX functionality
# This will handle both GET and POST requests
@depends.inject
async def counter_block(request, templates: Templates = depends()):
# Get the current count from the session or default to 0
count = request.session.get("count", 0)
# If this is a POST request, increment the counter
if request.method == "POST":
count += 1
request.session["count"] = count
# Render just the counter block with the current count
return await templates.app.render_template(
request, "blocks/counter.html", context={"count": count}
)
# Add the counter route
routes.append(Route("/block/counter", endpoint=counter_block, methods=["GET", "POST"]))
# Get the FastBlocks application instance
# This is pre-configured based on your settings
app = depends.get(App)
```
### 2. Create a Basic Template
Create a directory named `templates` and add a file named `index.html`:
```html
<!DOCTYPE html>
<html>
<head>
<title>[[ title ]]</title> <!-- FastBlocks uses [[ ]] instead of {{ }} for variables -->
<!-- Include HTMX for interactivity without writing JavaScript -->
<script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous"></script>
</head>
<body>
<h1>[[ title ]]</h1>
<!--
HTMX attributes explained:
- hx-get: The URL to fetch when the element loads
- hx-trigger: When to trigger the request (on load in this case)
-->
<div hx-get="/block/counter" hx-trigger="load">
Loading counter...
</div>
<!--
- hx-post: Send a POST request to this URL when clicked
- hx-target: Update the previous div with the response
-->
<button hx-post="/block/counter" hx-target="previous div">
Increment
</button>
</body>
</html>
```
### 3. Create a Template Block
Create a directory named `templates/blocks` and add a file named `counter.html`:
```html
<div>
<!-- This simple template will be rendered and returned for both GET and POST requests -->
<h2>Counter: [[ count ]]</h2>
</div>
```
### 4. Create a Configuration File
Create a directory named `settings` and add a file named `app.yml`:
```yaml
app:
name: "MyFastBlocksApp"
title: "My First FastBlocks App"
debug: true
# Configure session middleware
session:
secret_key: "your-secret-key-here" # In production, use a secure random key
max_age: 14400 # Session timeout in seconds (4 hours)
```
### 5. Run Your Application
Run your application with Uvicorn:
```bash
uvicorn myapp:app --reload
```
Now visit http://localhost:8000 in your browser. You should see your page with a counter and an increment button. When you click the button, the counter will increment without a page reload - that's HTMX and FastBlocks working together!
## Common Patterns
Here are some common patterns and examples that will help you get started with FastBlocks:
### 1. Rendering Template Blocks for HTMX
One of the most common patterns in FastBlocks is rendering specific template blocks for HTMX requests:
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def user_profile_block(request, templates: Templates = depends()):
user_id = request.path_params["user_id"]
# Fetch user data (in a real app, this would come from a database)
user = {"id": user_id, "name": f"User {user_id}", "email": f"user{user_id}@example.com"}
# Render just the user profile block
return await templates.app.render_template_block(
request,
"users/profile.html", # Template file
"profile_block", # Block name within the template
context={"user": user}
)
routes = [
Route("/users/{user_id}/profile", endpoint=user_profile_block)
]
```
Template (`templates/users/profile.html`):
```html
{% block profile_block %}
<div class="user-profile">
<h2>[[ user.name ]]</h2>
<p>Email: [[ user.email ]]</p>
</div>
{% endblock %}
```
HTML with HTMX:
```html
<!-- Load user profile when button is clicked -->
<button hx-get="/users/123/profile" hx-target="#profile-container">
Load Profile
</button>
<div id="profile-container"></div>
```
### 2. Form Submission with HTMX
Handling form submissions with HTMX is straightforward in FastBlocks:
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def contact_form(request, templates: Templates = depends()):
if request.method == "POST":
# Get form data
form_data = await request.form()
name = form_data.get("name")
email = form_data.get("email")
message = form_data.get("message")
# In a real app, you would save this to a database
# For this example, we'll just return a success message
# Return just the success message block
return await templates.app.render_template_block(
request,
"contact/form.html",
"success_block",
context={"name": name}
)
# For GET requests, render the form
return await templates.app.render_template(
request,
"contact/form.html",
context={}
)
routes = [
Route("/contact", endpoint=contact_form, methods=["GET", "POST"])
]
```
Template (`templates/contact/form.html`):
```html
<!-- Main template content -->
<h1>Contact Us</h1>
<!-- Form that submits via HTMX -->
<form hx-post="/contact" hx-swap="outerHTML">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
</div>
<button type="submit">Send Message</button>
</form>
<!-- Success message block that will replace the form -->
{% block success_block %}
<div class="success-message">
<h2>Thank you, [[ name ]]!</h2>
<p>Your message has been sent successfully.</p>
<button hx-get="/contact" hx-target="this" hx-swap="outerHTML">Send Another Message</button>
</div>
{% endblock %}
```
### 3. Using Dependency Injection
FastBlocks leverages ACB's dependency injection system to make components easily accessible:
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
from acb.config import Config
# Import adapters using the new direct import pattern
Templates = import_adapter("templates")
Cache = import_adapter("cache")
@depends.inject
async def dashboard(request,
templates: Templates = depends(),
cache: Cache = depends(),
config: Config = depends()):
# Get cached data or compute it
cache_key = "dashboard_stats"
stats = await cache.get(cache_key)
if not stats:
# In a real app, you would fetch this from a database
stats = {
"users": 1250,
"posts": 5432,
"comments": 15876
}
# Cache the stats for 5 minutes
await cache.set(cache_key, stats, ttl=300)
# Get app name from configuration
app_name = config.app.name
return await templates.app.render_template(
request,
"dashboard.html",
context={
"app_name": app_name,
"stats": stats
}
)
routes = [
Route("/dashboard", endpoint=dashboard)
]
```
**Note**: This example uses the new v0.13.2+ import patterns. The template system automatically handles dependency resolution with fallbacks, so if cache is unavailable, the function will still work correctly.
## Architecture Overview
### Relationship with Starlette
FastBlocks is built directly on top of [Starlette](https://www.starlette.io/), extending its capabilities for server-side rendered applications:
- **Class Extension**: The `FastBlocks` class extends Starlette's `Starlette` application class, inheriting all its core functionality
- **Enhanced Request Handling**: Extends Starlette's request handling with HTMX-specific features through the `HtmxRequest` class
- **Middleware Extensions**: Adds specialized middleware components on top of Starlette's middleware system
- **Template Integration**: Enhances Starlette with advanced template rendering capabilities
- **Error Handling**: Extends Starlette's exception handling with template-aware error responses
This approach allows FastBlocks to leverage Starlette's robust ASGI implementation while adding specialized features for server-side rendering and HTMX integration.
### Relationship with ACB
FastBlocks is built on top of [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb), which provides the foundational architecture. The relationship can be summarized as:
- **Foundation vs. Framework**: ACB provides the core infrastructure (dependency injection, configuration, adapters pattern) while FastBlocks is a web application framework built on this foundation.
- **Dependency Chain**: User Application → FastBlocks → Starlette + ACB → Python Standard Library
- **Component Architecture**: FastBlocks extends ACB's component architecture with web-specific components like templates, routing, and HTMX integration.
- **Adapter Pattern**: FastBlocks uses ACB's adapter pattern to create pluggable components for authentication, admin interfaces, templates, etc.
#### Direct ACB Integration (v0.13.2+)
Recent improvements include simplified dependency management through direct ACB imports:
```python
# Direct ACB imports for better performance
from acb.adapters import import_adapter
from acb.depends import depends
from acb.config import Config
# Get adapters directly from ACB
Templates = import_adapter("templates")
App = import_adapter("app")
# Access configuration and dependencies
config = depends.get(Config)
```
**Benefits of Direct Integration:**
- **Performance**: Eliminates wrapper overhead for faster adapter access
- **Type Safety**: Better type annotations and IDE support
- **Error Handling**: Enhanced error recovery with automatic fallbacks
- **Maintainability**: Aligned with ACB patterns for easier maintenance
- **Future-Proof**: Direct compatibility with ACB framework evolution
This separation allows FastBlocks to focus on web application concerns while leveraging ACB's robust component architecture for the underlying infrastructure.
### Server-Side Rendering with HTMX
FastBlocks is particularly well-suited for modern server-side rendering applications that use HTMX, offering several advantages over traditional approaches:
- **Reduced Complexity**: Avoid complex client-side state management and JavaScript frameworks
- **Improved Performance**: Server-side rendering can deliver faster initial page loads and smaller payloads
- **SEO-Friendly**: Fully rendered HTML content for better search engine optimization
- **Progressive Enhancement**: Start with functional HTML and enhance with HTMX for interactivity
- **Simplified Architecture**: Keep business logic on the server where it belongs
- **Reduced Development Time**: Use HTML templates and simple endpoints instead of complex API design
The combination of FastBlocks' templating system and HTMX offers a modern alternative to complex SPA frameworks, particularly for:
- **Admin dashboards**: Where business logic complexity outweighs UI complexity
- **Content management systems**: Where SEO and initial load performance are critical
- **Internal tools**: Where development speed and maintainability are prioritized over cutting-edge UIs
- **Applications with complex business logic**: Where keeping logic on the server simplifies testing and validation
### Project Structure
FastBlocks follows a component-based architecture with automatic discovery and registration of modules:
```
fastblocks/
├── actions/ # Utility functions (minify)
├── adapters/ # Integration modules for external systems
│ ├── app/ # Application configuration
│ ├── auth/ # Authentication adapters
│ ├── admin/ # Admin interface adapters
│ ├── routes/ # Routing adapters
│ ├── sitemap/ # Sitemap generation
│ └── templates/ # Template engine adapters
├── applications.py # FastBlocks application class
├── middleware.py # ASGI middleware components
└── ...
```
## Core Components
### Templates
FastBlocks uses an enhanced asynchronous Jinja2 template system designed specifically for HTMX integration and server-side rendering.
#### Key Features
- **Async Template Loading**: Load templates asynchronously from file system, cloud storage, or Redis
- **Template Fragments**: Render specific blocks of templates for HTMX partial updates
- **Custom Delimiters**: Uses `[[` and `]]` for variables instead of `{{` and `}}` to avoid conflicts with JavaScript frameworks
- **Bytecode Caching**: Redis-based bytecode caching for improved performance
- **Built-in Filters**: Includes filters for minification, URL encoding, and more
- **Null Safety**: Enhanced dependency resolution with automatic fallbacks for missing components
- **Error Recovery**: Graceful handling of cache, storage, and dependency failures
#### Basic Template Usage
```python
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def homepage(request, templates: Templates = depends()):
# Render a full template
return await templates.app.render_template(
request,
"index.html", # Template file path relative to templates directory
context={"title": "FastBlocks Demo", "user": {"name": "John"}}
)
```
#### Template Structure
FastBlocks templates use Jinja2 syntax with custom delimiters:
```html
<!DOCTYPE html>
<html>
<head>
<title>[[ title ]]</title> <!-- Note the [[ ]] delimiters instead of {{ }} -->
</head>
<body>
<h1>Welcome, [[ user.name ]]!</h1>
{% block content %}
<p>This is the default content.</p>
{% endblock %}
</body>
</html>
```
#### Template Inheritance
You can use Jinja2's template inheritance:
```html
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>[[ title ]]</title>
<link rel="stylesheet" href="/static/css/style.css">
{% block head %}{% endblock %}
</head>
<body>
<header>
<nav><!-- Navigation --></nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
© [[ current_year ]] FastBlocks Demo
</footer>
</body>
</html>
```
```html
<!-- templates/home.html -->
{% extends "base.html" %}
{% block head %}
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
{% endblock %}
{% block content %}
<h1>Welcome to [[ title ]]</h1>
<div id="counter-container" hx-get="/block/counter" hx-trigger="load">
Loading...
</div>
{% endblock %}
```
#### Template Blocks for HTMX
Create template blocks specifically for HTMX responses:
```html
<!-- templates/blocks/counter.html -->
{% block counter_block %}
<div class="counter">
<h2>Count: [[ count ]]</h2>
<button hx-post="/block/counter" hx-target="#counter-container">Increment</button>
</div>
{% endblock %}
```
```python
@depends.inject
async def counter_block(request, templates: Templates = depends()):
count = request.session.get("count", 0)
if request.method == "POST":
count += 1
request.session["count"] = count
# Render just the counter block
return await templates.app.render_template_block(
request,
"blocks/counter.html", # Template file
"counter_block", # Block name within the template
context={"count": count}
)
```
#### Custom Filters
FastBlocks includes several built-in filters and you can add your own:
```python
from acb.adapters import import_adapter
Templates = import_adapter("templates")
# Register a custom filter
@Templates.filter()
def capitalize_words(value: str) -> str:
return " ".join(word.capitalize() for word in value.split())
```
Usage in templates:
```html
<h1>[[ user.name | capitalize_words ]]</h1>
```
#### Built-in Filters
FastBlocks includes several useful filters:
- **minify_html**: Minifies HTML content
- **minify_js**: Minifies JavaScript content
- **minify_css**: Minifies CSS content
- **map_src**: URL-encodes strings for use in URLs
#### Enhanced Dependency Resolution
Version 0.13.2 introduces robust dependency resolution with automatic fallbacks:
```python
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def my_view(request, templates: Templates = depends()):
# FastBlocks automatically handles:
# 1. Primary dependency resolution via depends.get()
# 2. Fallback to get_adapter() if primary fails
# 3. Null safety checks throughout the template system
# 4. Graceful error handling for missing dependencies
return await templates.app.render_template(
request, "my_template.html", context={"data": "value"}
)
```
The template system now includes:
- **Automatic Fallbacks**: If cache or storage dependencies are unavailable, the system continues with file-based templates
- **Null Safety**: All operations check for null dependencies and provide sensible defaults
- **Error Recovery**: Template loading failures are handled gracefully with meaningful error messages
- **Dependency Order**: `depends.get()` is tried first, followed by `get_adapter()` fallback
### Routing
The routing system extends Starlette's routing with enhanced features for HTMX and server-side rendering.
#### Key Features
- **Automatic Route Discovery**: Routes are automatically discovered and registered
- **HTMX-Aware Endpoints**: Built-in support for HTMX requests and responses
- **Block Rendering**: Specialized endpoints for rendering template blocks
#### Basic Routing
FastBlocks supports Starlette's routing patterns with additional features:
```python
from starlette.routing import Route, Mount
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def homepage(request, templates: Templates = depends()):
return await templates.app.render_template(
request, "index.html", context={"title": "FastBlocks Demo"}
)
@depends.inject
async def about(request, templates: Templates = depends()):
return await templates.app.render_template(
request, "about.html", context={"title": "About Us"}
)
# Define your routes
routes = [
Route("/", endpoint=homepage),
Route("/about", endpoint=about),
Mount("/static", StaticFiles(directory="static"), name="static"),
]
```
#### Route Discovery
FastBlocks can automatically discover and register routes from your application:
```python
# routes.py
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def homepage(request, templates: Templates = depends()):
return await templates.app.render_template(
request, "index.html", context={"title": "FastBlocks Demo"}
)
# Export routes to be automatically discovered
routes = [
Route("/", endpoint=homepage),
]
```
#### Path Parameters
You can use path parameters in your routes:
```python
@depends.inject
async def user_profile(request, templates: Templates = depends()):
user_id = request.path_params["user_id"]
# Fetch user data...
return await templates.app.render_template(
request, "user/profile.html", context={"user_id": user_id}
)
routes = [
Route("/users/{user_id}", endpoint=user_profile),
]
```
#### HTMX-Specific Routes
Create routes specifically for HTMX interactions:
```python
@depends.inject
async def load_more_items(request, templates: Templates = depends()):
page = int(request.query_params.get("page", 1))
# Fetch items for the requested page...
items = [f"Item {i}" for i in range((page-1)*10, page*10)]
# Return just the items block for HTMX to insert
return await templates.app.render_template_block(
request,
"items.html",
"items_block",
context={"items": items, "page": page}
)
routes = [
Route("/api/items", endpoint=load_more_items),
]
```
### Middleware
FastBlocks includes several middleware components:
- **HTMX Middleware**: Adds HTMX-specific request information
- **CSRF Protection**: Built-in CSRF protection for forms
- **Session Middleware**: Cookie-based session management
- **Compression**: Brotli compression for reduced payload sizes
- **Secure Headers**: Security headers for production environments
- **Cache Middleware**: HTTP response caching with rule-based configuration
- **Cache Control Middleware**: Simplified management of cache control headers
- **Process Time Header Middleware**: Measures and logs request processing time
- **Current Request Middleware**: Makes the current request available via a context variable
#### Middleware Ordering
FastBlocks uses a position-based middleware system to ensure middleware components are executed in the correct order. The middleware execution flow follows the ASGI specification:
1. The last middleware in the list is the first to process the request
2. The first middleware in the list is the last to process the request
The actual execution flow is:
- ExceptionMiddleware (outermost - first to see request, last to see response)
- System middleware (ordered by MiddlewarePosition enum)
- User-provided middleware
- ServerErrorMiddleware (innermost - last to see request, first to see response)
#### Adding Custom Middleware
You can add custom middleware to your FastBlocks application in two ways:
1. **User Middleware**: Added to the user middleware stack
```python
# Add a middleware to the end of the user middleware stack
app.add_middleware(CustomMiddleware, option="value")
# Add a middleware at a specific position in the user middleware stack
app.add_middleware(CustomMiddleware, position=0, option="value")
```
2. **System Middleware**: Replace middleware at specific positions defined by the MiddlewarePosition enum
```python
from fastblocks.middleware import MiddlewarePosition
# Replace the compression middleware with a custom implementation
app.add_system_middleware(
CustomMiddleware,
position=MiddlewarePosition.COMPRESSION,
option="value"
)
```
#### Example: Custom Middleware
Here's a complete example of creating and adding custom middleware:
```python
from typing import Any
from starlette.types import ASGIApp, Receive, Scope, Send
from fastblocks import FastBlocks
from fastblocks.middleware import MiddlewarePosition
# Define a simple custom middleware
class CustomHeaderMiddleware:
"""A middleware that adds a custom header to responses."""
def __init__(self, app: ASGIApp, header_name: str, header_value: str) -> None:
self.app = app
self.header_name = header_name
self.header_value = header_value
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] != "http":
await self.app(scope, receive, send)
return
async def send_with_header(message: dict[str, Any]) -> None:
if message["type"] == "http.response.start":
headers = message.get("headers", [])
headers.append(
(self.header_name.encode(), self.header_value.encode())
)
message["headers"] = headers
await send(message)
await self.app(scope, receive, send_with_header)
# Create a FastBlocks application
app = FastBlocks()
# Add a custom middleware to the user middleware stack
app.add_middleware(
CustomHeaderMiddleware,
header_name="X-Custom-User",
header_value="User-defined"
)
# Replace the compression middleware with a custom implementation
app.add_system_middleware(
CustomHeaderMiddleware,
position=MiddlewarePosition.COMPRESSION,
header_name="X-Custom-Compression",
header_value="Replaced"
)
```
#### Middleware Positions
The `MiddlewarePosition` enum defines the positions of middleware in the system stack:
```python
class MiddlewarePosition(IntEnum):
# Core middleware (always present)
PROCESS_TIME = 0 # First middleware to see request, last to see response
CSRF = 1 # Security middleware should be early in the chain
SESSION = 2 # Session handling (if auth enabled)
HTMX = 3 # HTMX request processing
CURRENT_REQUEST = 4 # Request context tracking
COMPRESSION = 5 # Response compression
SECURITY_HEADERS = 6 # Security headers for responses
```
You can get a dictionary of middleware positions using the `get_middleware_positions()` function:
```python
from fastblocks.middleware import get_middleware_positions
positions = get_middleware_positions()
print(positions) # {'PROCESS_TIME': 0, 'CSRF': 1, ...}
```
### HTMX Integration
FastBlocks is designed to work seamlessly with HTMX, a lightweight JavaScript library that allows you to access modern browser features directly from HTML attributes.
#### Key HTMX Features in FastBlocks
- **HtmxRequest**: Extended request object with HTMX-specific attributes
- **Template Blocks**: Specialized endpoints for rendering template fragments
- **Push URL**: Automatic URL updates for browser history
- **Response Headers**: Helper methods for setting HTMX-specific response headers
#### Using HTMX Request Properties
FastBlocks extends Starlette's request object with HTMX-specific properties:
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def product_detail(request, templates: Templates = depends()):
product_id = request.path_params["product_id"]
# Check if this is an HTMX request
if request.htmx:
# Access HTMX-specific properties
is_boosted = request.htmx.boosted # True if hx-boost was used
trigger = request.htmx.trigger # ID of the element that triggered the request
target = request.htmx.target # ID of the target element
# For HTMX requests, render just the product details block
return await templates.app.render_template_block(
request,
"products/detail.html",
"product_detail_block",
context={"product_id": product_id}
)
# For regular requests, render the full page
return await templates.app.render_template(
request,
"products/detail.html",
context={"product_id": product_id}
)
routes = [
Route("/products/{product_id}", endpoint=product_detail)
]
```
#### Setting HTMX Response Headers
FastBlocks makes it easy to set HTMX-specific response headers:
```python
from starlette.responses import Response
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
Templates = import_adapter("templates")
@depends.inject
async def search_results(request, templates: Templates = depends()):
query = request.query_params.get("q", "")
# Render the search results
response = await templates.app.render_template_block(
request,
"search/results.html",
"results_block",
context={"query": query, "results": []}
)
# Set HTMX-specific headers
response.headers["HX-Push-Url"] = f"/search?q={query}" # Update browser URL
response.headers["HX-Trigger"] = "search-complete" # Trigger client-side events
return response
routes = [
Route("/search", endpoint=search_results)
]
```
#### Common HTMX Patterns
Here are some common HTMX patterns you can use with FastBlocks:
- **Click to Load**: `<button hx-get="/more" hx-target="#content">Load More</button>`
- **Form Submission**: `<form hx-post="/submit" hx-swap="outerHTML">...</form>`
- **Infinite Scroll**: `<div hx-get="/next-page" hx-trigger="revealed" hx-swap="afterend"></div>`
- **Active Search**: `<input type="text" name="q" hx-get="/search" hx-trigger="keyup changed delay:500ms" hx-target="#results">`
- **Confirmation Dialog**: `<button hx-delete="/item/1" hx-confirm="Are you sure?">Delete</button>`
## Adapters
FastBlocks uses a pluggable adapter system for various components:
- **App**: Application configuration and initialization
- **Auth**: Authentication providers (Basic, etc.)
- **Admin**: Admin interface providers (SQLAdmin)
- **Routes**: Route management and discovery
- **Templates**: Template engine adapters (Jinja2)
- **Sitemap**: Sitemap generation
#### Application Initialization Improvements (v0.13.2)
The FastBlocks application initialization process has been streamlined for better performance and reliability:
```python
from acb.adapters import import_adapter
from acb.depends import depends
# Get the application instance
App = import_adapter("app")
app = depends.get(App)
# The app is now pre-configured with:
# - Enhanced middleware stack management
# - Optimized dependency resolution
# - Improved error handling
# - Lazy loading for optional components
```
**Key Improvements:**
- **Faster Startup**: Lazy loading of non-critical components reduces initialization time
- **Better Error Handling**: Clear error messages for configuration issues and missing dependencies
- **Middleware Optimization**: Position-based middleware management with caching
- **Memory Efficiency**: Reduced memory footprint through optimized component loading
For more information about adapters, see the [Adapters Documentation](./fastblocks/adapters/README.md).
## Actions
Actions are utility functions that perform specific tasks:
- **Gather**: Discover and consolidate routes, templates, middleware, models, and application components
- **Sync**: Bidirectional synchronization of templates, settings, and cache across environments
- **Minify**: HTML, CSS, and JavaScript minification
For more information about actions, see the [Actions Documentation](./fastblocks/actions/README.md).
## Configuration
FastBlocks uses ACB's configuration system based on Pydantic, which provides a unified way to manage settings from multiple sources:
```python
from acb.config import Config
from acb.depends import depends
config = depends.get(Config)
# Access configuration values
secret_key = config.app.secret_key
debug_mode = config.debug.fastblocks
```
### Configuration Sources
- **YAML Files**: Environment-specific settings in YAML format (settings/app.yml, settings/debug.yml, etc.)
- **Secret Files**: Secure storage of sensitive information
- **Environment Variables**: Override configuration via environment variables
### FastBlocks-Specific Configuration
FastBlocks extends ACB's configuration system with web-specific settings for templates, routing, middleware, and more. These settings are automatically loaded and validated using Pydantic models.
## Command-Line Interface (CLI)
FastBlocks includes a powerful CLI tool to help you create and run applications.
### Installation
When you install FastBlocks, the CLI is automatically available:
```bash
python -m fastblocks --help
```
### Creating a New Project
Create a new FastBlocks project with the `create` command:
```bash
python -m fastblocks create
```
You'll be prompted for:
- **app_name**: Name of your application
- **style**: UI framework to use (bulma, webawesome, or custom)
- **domain**: Application domain
This will create a new directory with the following structure:
```
myapp/
├── __init__.py
├── .envrc
├── adapters/
│ └── __init__.py
├── actions/
│ └── __init__.py
├── main.py
├── models.py
├── pyproject.toml
├── routes.py
├── settings/
│ ├── adapters.yml
│ ├── app.yml
│ └── debug.yml
└── templates/
├── base/
│ └── blocks/
└── style/
├── blocks/
└── theme/
```
### Running Your Application
Run your application in development mode with hot-reloading:
```bash
python -m fastblocks dev
```
The development server includes enhanced features:
- **Optimized Logging**: Uvicorn logging is integrated with ACB's InterceptHandler for cleaner output
- **Smart Reloading**: Excludes `tmp/*`, `settings/*`, and `templates/*` directories from reload monitoring for better performance
- **Template Development**: Templates are excluded from reload to prevent unnecessary restarts during template development
Run your application in production mode:
```bash
python -m fastblocks run
```
Run your application with Granian (high-performance ASGI server):
```bash
python -m fastblocks dev --granian
```
Run your application in a Docker container:
```bash
python -m fastblocks run --docker
```
### CLI Options
#### Create Command
```bash
python -m fastblocks create --app-name myapp --style bulma --domain example.com
```
#### Dev Command
```bash
python -m fastblocks dev [--granian] [--host HOST] [--port PORT]
```
Running with hot-reloading enabled for development.
#### Run Command
```bash
python -m fastblocks run [--docker] [--granian] [--host HOST] [--port PORT]
```
Run in production mode.
#### Components Command
```bash
python -m fastblocks components
```
Show available FastBlocks components and their status.
## Migration Guide
### Updating from Version 0.13.1 to 0.13.2
Version 0.13.2 introduces simplified dependency management with direct ACB imports. While existing code will continue to work, we recommend updating to the new patterns for better performance and maintainability.
#### Import Pattern Changes
**Before (v0.13.1 and earlier):**
```python
# Old wrapper-based imports
from fastblocks.dependencies import Templates, App
from fastblocks.config import config
```
**After (v0.13.2+):**
```python
# Direct ACB imports (recommended)
from acb.adapters import import_adapter
from acb.depends import depends
from acb.config import Config
Templates = import_adapter("templates")
App = import_adapter("app")
config = depends.get(Config)
```
#### Route Handler Updates
**Before:**
```python
@depends.inject
async def homepage(request, templates=depends(Templates)):
return await templates.render_template(request, "index.html")
```
**After:**
```python
@depends.inject
async def homepage(request, templates: Templates = depends()):
return await templates.app.render_template(request, "index.html")
```
#### Benefits of the New Pattern
1. **Better Performance**: Direct ACB access eliminates wrapper overhead
2. **Improved Type Safety**: Explicit type annotations with adapters
3. **Enhanced Error Handling**: Built-in fallback mechanisms for missing dependencies
4. **Future Compatibility**: Aligned with ACB framework patterns
#### Template System Improvements
Version 0.13.2 includes enhanced null safety in template loaders:
- Automatic fallback when dependencies are unavailable
- Improved error messages for missing templates
- Better handling of cache and storage failures
- Enhanced dependency resolution order
#### CLI Enhancements
The CLI now includes:
- Optimized uvicorn logging configuration
- Template reload exclusions for better development experience
- Enhanced error reporting for configuration issues
## Examples
### Creating a Dynamic Counter with HTMX
```python
from starlette.routing import Route
from acb.adapters import import_adapter
from acb.depends import depends
# Import adapters
Templates = import_adapter("templates")
App = import_adapter("app")
counter = 0
@depends.inject
async def get_counter(request, templates: Templates = depends()):
return await templates.app.render_template(
request, "blocks/counter.html", context={"count": counter}
)
@depends.inject
async def increment_counter(request, templates: Templates = depends()):
global counter
counter += 1
return await templates.app.render_template(
request, "blocks/counter.html", context={"count": counter}
)
routes = [
Route("/block/counter", endpoint=get_counter, methods=["GET"]),
Route("/block/counter", endpoint=increment_counter, methods=["POST"]),
]
# Create the application
app = depends.get(App)
```
## Documentation
For more detailed documentation about FastBlocks components:
- [**Core Features**](./fastblocks/README.md): Applications, middleware, and core functionality
- [**Actions**](./fastblocks/actions/README.md): Utility functions like minification
- [**Adapters**](./fastblocks/adapters/README.md): Pluggable components for various features
- [**App Adapter**](./fastblocks/adapters/app/README.md): Application configuration
- [**Auth Adapter**](./fastblocks/adapters/auth/README.md): Authentication providers
- [**Admin Adapter**](./fastblocks/adapters/admin/README.md): Admin interface
- [**Routes Adapter**](./fastblocks/adapters/routes/README.md): Routing system
- [**Templates Adapter**](./fastblocks/adapters/templates/README.md): Template engine
- [**Sitemap Adapter**](./fastblocks/adapters/sitemap/README.md): Sitemap generation
- [**Running Tests**](./tests/TESTING.md): Comprehensive guide to testing FastBlocks components
## License
This project is licensed under the terms of the BSD 3-Clause license.
## Acknowledgements
Special thanks to the following open-source projects that power FastBlocks:
### Foundation
- [Starlette](https://www.starlette.io/) - The ASGI framework that FastBlocks directly extends, providing the web application foundation
- [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb) - The core infrastructure providing dependency injection, configuration, and component architecture
### Frontend & Templates
- [HTMX](https://htmx.org/) - The lightweight JavaScript library for dynamic interfaces
- [Jinja2](https://jinja.palletsprojects.com/) - The template engine
- [jinja2-async-environment](https://github.com/lesleslie/jinja2-async-environment) - Asynchronous Jinja2 environment
- [starlette-async-jinja](https://github.com/lesleslie/starlette-async-jinja) - Starlette integration for async Jinja2
### Data & Validation
- [Pydantic](https://pydantic-docs.helpmanual.io/) - Data validation and settings management
- [SQLAlchemy](https://www.sqlalchemy.org/) - SQL toolkit and ORM
Raw data
{
"_id": null,
"home_page": null,
"name": "fastblocks",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": "lesleslie <les@wedgwoodwebworks.com>",
"keywords": "htmx, httpx, jinja, pydantic, redis, sqladmin, sqlalchemy, sqlmodel, starlette",
"author": null,
"author_email": "lesleslie <les@wedgwoodwebworks.com>",
"download_url": "https://files.pythonhosted.org/packages/be/3f/e0f7dbe1b9cf2f959266d6a275cdc25fe1534240d2b11b1004332b03ae82/fastblocks-0.14.0.tar.gz",
"platform": null,
"description": "\n<p align=\"center\">\n<img src=\"./images/fastblocks-logo.png\" alt=\"FastBlocks Logo\">\n</p>\n\n> **FastBlocks Documentation**: [Main](./README.md) | [Core Features](./fastblocks/README.md) | [Actions](./fastblocks/actions/README.md) | [Adapters](./fastblocks/adapters/README.md)\n\n# FastBlocks\n\n[](https://github.com/lesleslie/crackerjack)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/BSD-3-Clause)\n\n\n## What is FastBlocks?\n\nFastBlocks is an asynchronous web application framework, inspired by FastAPI and built on Starlette, specifically designed for the rapid delivery of server-side rendered HTMX/Jinja template blocks. It combines modern Python async capabilities with server-side rendering to create dynamic, interactive web applications with minimal JavaScript.\n\nUnlike monolithic frameworks or micro-frameworks that require extensive configuration, FastBlocks offers a modular, component-based architecture that provides batteries-included functionality while maintaining exceptional flexibility. Its adapter pattern allows for seamless component swapping, cloud provider migrations, and tailored customizations without extensive code changes.\n\n## Key Concepts\n\nIf you're new to FastBlocks, here are the key concepts to understand:\n\n1. **Server-Side Rendering**: Unlike frameworks that rely heavily on JavaScript for interactivity, FastBlocks renders HTML on the server and sends only what's needed to the browser.\n\n2. **HTMX**: A lightweight JavaScript library that allows you to access modern browser features directly from HTML, without writing JavaScript. FastBlocks is built with HTMX in mind.\n\n3. **Template Blocks**: Small pieces of HTML that can be rendered independently and injected into the page, enabling dynamic updates without full page reloads.\n\n4. **Adapters**: Pluggable components that provide standardized interfaces to different implementations (templates, authentication, admin interfaces, etc.). This architecture facilitates seamless provider switching, multi-cloud deployments, and targeted customizations without restructuring your application.\n\n5. **Dependency Injection**: A pattern that automatically provides components to your functions when needed, reducing boilerplate code.\n\n6. **Asynchronous Architecture**: Built on Python's async/await syntax for high performance and efficient handling of concurrent requests.\n\n## Key Features\n\n- **Starlette Foundation**: Built on the [Starlette](https://www.starlette.io/) ASGI framework for high performance, extending its application class and middleware system\n- **HTMX Integration**: First-class support for HTMX to create dynamic interfaces with server-side rendering\n- **Asynchronous Architecture**: Built on [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb), providing dependency injection, configuration management, and pluggable components\n- **Template-Focused**: Advanced asynchronous Jinja2 template system with fragments and partials support using `[[` and `]]` delimiters\n- **Modular Design**: Pluggable adapters for authentication, admin interfaces, routing, templates, and sitemap generation\n- **Cloud Flexibility**: Easily switch between cloud providers or create hybrid deployments by swapping adapters\n- **Performance Optimized**: Built-in caching system, Brotli compression, and HTML/CSS/JS minification\n- **Type Safety**: Leverages Pydantic v2 for validation and type safety throughout\n- **Admin Interface**: Integrated SQLAlchemy Admin support for database management\n- **Dependency Injection**: Robust dependency injection system with automatic resolution\n- **Batteries Included, But Replaceable**: Comprehensive defaults with the ability to customize or replace any component\n\n## Why Choose FastBlocks?\n\nFastBlocks stands out from other Python web frameworks through its unique combination of server-side rendering focus, component-based architecture, and hybrid cloud capabilities. Here's how FastBlocks compares to other popular frameworks:\n\n### FastBlocks vs. FastAPI\n\nWhile FastAPI excels at API development, FastBlocks is specifically designed for server-side rendered applications with HTMX:\n\n| Aspect | FastBlocks | FastAPI |\n|--------|------------|---------|\n| **Primary Focus** | Server-side rendering + HTMX | JSON APIs + OpenAPI |\n| **Template System** | Built-in async Jinja2 with HTMX support | External template engines required |\n| **Component Architecture** | Pluggable adapters for all components | Manual dependency injection setup |\n| **Cloud Flexibility** | Built-in adapter system for multi-cloud | Cloud integration requires custom solutions |\n| **Frontend Approach** | HTMX for dynamic interfaces | Requires separate frontend framework |\n| **Development Speed** | Rapid HTML-first development | Fast API development, slower frontend integration |\n| **SEO Support** | Native server-side rendering | Requires additional SSR setup |\n| **Learning Curve** | Simple HTML + Python | API design + frontend framework |\n\n**Choose FastBlocks when:** You want to build interactive web applications with server-side rendering, need rapid development of admin interfaces, or prefer keeping business logic on the server.\n\n**Choose FastAPI when:** You're building APIs for mobile apps, need extensive OpenAPI documentation, or are creating microservices.\n\n### FastBlocks vs. FastHTML\n\nFastHTML focuses on Python-in-HTML, while FastBlocks uses a traditional template-based approach:\n\n| Aspect | FastBlocks | FastHTML |\n|--------|------------|----------|\n| **Template Approach** | Jinja2 templates with custom delimiters | Python functions generate HTML |\n| **Separation of Concerns** | Clear separation of logic and presentation | Logic and presentation mixed |\n| **Designer Collaboration** | HTML/CSS designers can work directly | Requires Python knowledge for frontend |\n| **Template Ecosystem** | Full Jinja2 ecosystem and tooling | Limited to Python HTML generation |\n| **Component Reusability** | Template blocks and inheritance | Python function composition |\n| **Infrastructure Flexibility** | Adapter pattern for all components | Monolithic approach |\n| **Cloud Deployment** | Built-in multi-cloud support | Manual cloud configuration |\n| **Performance** | Async template caching and optimization | Runtime HTML generation |\n\n**Choose FastBlocks when:** You work with designers, need template reusability, want infrastructure flexibility, or prefer traditional template-based development.\n\n**Choose FastHTML when:** You prefer Python-only development, want inline HTML generation, or are building simple prototypes.\n\n### FastBlocks vs. FastHX\n\nFastHX provides HTMX utilities for FastAPI, while FastBlocks is a complete framework built around HTMX:\n\n| Aspect | FastBlocks | FastHX |\n|--------|------------|--------|\n| **Framework Scope** | Complete web framework | HTMX utilities for FastAPI |\n| **Template Integration** | Built-in async template system | Requires separate template setup |\n| **Component Architecture** | Full adapter system | Limited to HTMX helpers |\n| **Cloud Deployment** | Built-in multi-cloud adapters | Relies on FastAPI deployment |\n| **Development Workflow** | Integrated HTMX + templates | Add-on to existing FastAPI |\n| **Performance Optimization** | Built-in caching, compression, minification | Manual optimization required |\n| **Admin Interface** | Integrated admin system | External admin interface needed |\n| **Configuration Management** | ACB-based configuration system | FastAPI configuration |\n\n**Choose FastBlocks when:** You want a complete HTMX-focused framework, need built-in admin interfaces, or want comprehensive infrastructure adapters.\n\n**Choose FastHX when:** You have an existing FastAPI application and want to add HTMX capabilities incrementally.\n\n### FastBlocks vs. FastHTMX\n\nFastHTMX is another HTMX integration library, while FastBlocks is a complete framework:\n\n| Aspect | FastBlocks | FastHTMX |\n|--------|------------|----------|\n| **Architecture** | Complete framework with adapters | HTMX integration library |\n| **Template System** | Advanced async Jinja2 with fragments | Basic template integration |\n| **Infrastructure** | Pluggable adapters for everything | Manual infrastructure setup |\n| **Cloud Support** | Built-in multi-cloud capabilities | External cloud configuration |\n| **Development Tools** | Full CLI, project generation, testing | Limited tooling |\n| **Performance Features** | Caching, compression, minification | Basic HTMX support |\n| **Admin Interface** | Integrated SQLAlchemy admin | No admin interface |\n| **Dependency Injection** | ACB-based DI system | Manual dependency management |\n\n**Choose FastBlocks when:** You want a batteries-included framework, need enterprise-grade features, or want rapid application development.\n\n**Choose FastHTMX when:** You need a lightweight HTMX integration for an existing application.\n\n### FastBlocks vs. Litestar\n\nLitestar is a modern FastAPI alternative with native HTMX support, while FastBlocks focuses on server-side rendering:\n\n| Aspect | FastBlocks | Litestar |\n|--------|------------|----------|\n| **Primary Focus** | Server-side rendering + HTMX | High-performance APIs |\n| **Template System** | Built-in async templates with HTMX | External template engines |\n| **HTMX Support** | Built-in HTMX integration | Native HTMX support |\n| **Component Architecture** | Adapter pattern for flexibility | Plugin system |\n| **Cloud Deployment** | Built-in multi-cloud adapters | Manual cloud integration |\n| **Performance** | Optimized for SSR and HTMX | Optimized for API throughput |\n| **Frontend Integration** | HTMX-first approach | API-first, frontend agnostic |\n| **Development Experience** | HTML-first rapid development | Type-safe API development |\n| **Infrastructure Flexibility** | Adapter-based infrastructure | Plugin-based extensions |\n\n**Choose FastBlocks when:** You're building traditional web applications, need HTMX integration, or want infrastructure flexibility through adapters.\n\n**Choose Litestar when:** You need high-performance APIs, want extensive type safety, or are building API-first applications.\n\n### Key Advantages of FastBlocks\n\n#### \ud83e\udde9 **Component-Based Architecture**\n- **Batteries Included, But Customizable**: Comprehensive defaults for rapid development, with every component easily replaceable\n- **Pluggable Adapters**: Every component (auth, admin, templates, storage, cache) can be swapped without code changes\n- **Consistent Interfaces**: Standardized APIs across all adapters ensure predictable behavior\n- **Independent Evolution**: Update or replace individual components without affecting the entire application\n- **Zero Lock-in**: Unlike monolithic frameworks, you're never locked into specific implementations\n\n#### \ud83c\udf10 **Multi-Cloud & Hybrid Deployment Ready**\n- **Cloud Provider Flexibility**: Switch between AWS, Azure, GCP, or on-premise with configuration changes\n- **Vendor Lock-in Prevention**: Abstract cloud-specific APIs behind adapter interfaces\n- **Hybrid Strategies**: Mix and match services from different providers in the same application\n- **Infrastructure as Code**: Configuration-driven infrastructure decisions\n\n#### \ud83d\ude80 **Server-Side Rendering Excellence**\n- **HTMX-Native**: Built specifically for HTMX patterns and server-side rendering\n- **Template Block Rendering**: Render specific template fragments for dynamic updates\n- **SEO Optimized**: Full server-side rendering ensures search engine visibility\n- **Progressive Enhancement**: Start with functional HTML, enhance with HTMX\n\n#### \u26a1 **Performance Optimized**\n- **Async Everything**: Fully asynchronous template loading, caching, and rendering\n- **Built-in Caching**: Redis-based template and response caching with configurable rules\n- **Compression**: Brotli compression reduces payload sizes\n- **Minification**: Built-in HTML, CSS, and JS minification\n\n#### \ud83d\udee0 **Developer Experience**\n- **Rapid Development**: HTML-first approach with powerful template system\n- **Full CLI**: Project generation, development server, testing, and deployment tools\n- **Type Safety**: Pydantic-based configuration and validation throughout\n- **Testing Support**: Comprehensive testing utilities and mocking framework\n\n#### \ud83c\udfe2 **Enterprise Ready**\n- **Configuration Management**: Multi-environment configuration with secrets management\n- **Security Built-in**: CSRF protection, secure headers, session management\n- **Admin Interface**: Integrated SQLAlchemy admin for database management\n- **Monitoring**: Built-in integration with Sentry and Logfire\n- **Deployment Options**: Docker, traditional servers, and cloud platforms\n\n### When to Choose FastBlocks\n\nFastBlocks is the ideal choice for:\n\n- **Traditional Web Applications**: Where server-side rendering and SEO matter\n- **Admin Dashboards**: Complex business logic with moderate UI complexity\n- **Content Management Systems**: Where initial load performance is critical\n- **Internal Tools**: Rapid development and maintenance are prioritized\n- **Multi-Cloud Environments**: Organizations needing infrastructure flexibility\n- **Team Collaboration**: Designers can work with HTML/CSS while developers handle Python logic\n- **Prototype to Production**: Rapid prototyping that scales to enterprise needs\n\nFastBlocks combines the development speed of modern frameworks with the infrastructure flexibility needed for enterprise deployment. Unlike monolithic frameworks that lock you into specific implementations, FastBlocks provides comprehensive defaults (batteries included) while maintaining the flexibility to customize or replace any component to suit your specific needs. This makes it an excellent choice for teams that want to move fast without sacrificing long-term flexibility or architectural control.\n\n## Table of Contents\n\n- [Why Choose FastBlocks?](#why-choose-fastblocks)\n- [Key Concepts](#key-concepts)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Common Patterns](#common-patterns)\n- [Architecture Overview](#architecture-overview)\n- [Core Components](#core-components)\n - [Templates](#templates)\n - [Routing](#routing)\n - [Middleware](#middleware)\n - [HTMX Integration](#htmx-integration)\n- [Adapters](#adapters)\n- [Actions](#actions)\n- [Configuration](#configuration)\n- [Command-Line Interface (CLI)](#command-line-interface-cli)\n - [Creating a New Project](#creating-a-new-project)\n - [Running Your Application](#running-your-application)\n - [CLI Options](#cli-options)\n- [Migration Guide](#migration-guide)\n- [Examples](#examples)\n- [Documentation](#documentation)\n- [License](#license)\n- [Acknowledgements](#acknowledgements)\n\n## Installation\n\nInstall FastBlocks using [pdm](https://pdm.fming.dev):\n\n```bash\npdm add fastblocks\n```\n\n### Requirements\n\n- Python 3.13 or higher\n\n### Optional Dependencies\n\nFastBlocks supports various optional dependencies for different features:\n\n| Feature Group | Components | Installation Command |\n|---------------|------------|----------------------|\n| Admin | SQLAlchemy Admin interface | `pdm add \"fastblocks[admin]\"` |\n| Sitemap | Automatic sitemap generation | `pdm add \"fastblocks[sitemap]\"` |\n| Monitoring | Sentry and Logfire integration | `pdm add \"fastblocks[monitoring]\"` |\n| Complete | All dependencies | `pdm add \"fastblocks[admin,sitemap,monitoring]\"` |\n| Development | Development tools | `pdm add -G dev \"fastblocks\"` |\n\nYou can also install FastBlocks using pip:\n\n```bash\npip install fastblocks\n```\n\nFor optional dependencies with pip:\n\n```bash\npip install \"fastblocks[admin,sitemap,monitoring]\"\n```\n\n## Quick Start\n\nLet's build a simple FastBlocks application step by step:\n\n### 1. Create Your Application File\n\nCreate a file named `myapp.py` with the following code:\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\n# Import adapters - these are pluggable components that FastBlocks uses\n# The Templates adapter handles rendering Jinja2 templates\n# The App adapter provides the FastBlocks application instance\nTemplates = import_adapter(\"templates\") # Get the configured template adapter\nApp = import_adapter(\"app\") # Get the configured app adapter\n\n# Define a route handler for the homepage\n# The @depends.inject decorator automatically provides dependencies\n@depends.inject\nasync def homepage(request, templates: Templates = depends()):\n # Render a template and return the response\n # This is similar to Flask's render_template but async\n return await templates.app.render_template(\n request, \"index.html\", context={\"title\": \"FastBlocks Demo\"}\n )\n\n# Define your application routes\nroutes = [\n Route(\"/\", endpoint=homepage) # Map the root URL to the homepage function\n]\n\n# Create a counter endpoint that demonstrates HTMX functionality\n# This will handle both GET and POST requests\n@depends.inject\nasync def counter_block(request, templates: Templates = depends()):\n # Get the current count from the session or default to 0\n count = request.session.get(\"count\", 0)\n\n # If this is a POST request, increment the counter\n if request.method == \"POST\":\n count += 1\n request.session[\"count\"] = count\n\n # Render just the counter block with the current count\n return await templates.app.render_template(\n request, \"blocks/counter.html\", context={\"count\": count}\n )\n\n# Add the counter route\nroutes.append(Route(\"/block/counter\", endpoint=counter_block, methods=[\"GET\", \"POST\"]))\n\n# Get the FastBlocks application instance\n# This is pre-configured based on your settings\napp = depends.get(App)\n```\n\n### 2. Create a Basic Template\n\nCreate a directory named `templates` and add a file named `index.html`:\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n <title>[[ title ]]</title> <!-- FastBlocks uses [[ ]] instead of {{ }} for variables -->\n\n <!-- Include HTMX for interactivity without writing JavaScript -->\n <script src=\"https://unpkg.com/htmx.org@1.9.10\" integrity=\"sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC\" crossorigin=\"anonymous\"></script>\n</head>\n<body>\n <h1>[[ title ]]</h1>\n\n <!--\n HTMX attributes explained:\n - hx-get: The URL to fetch when the element loads\n - hx-trigger: When to trigger the request (on load in this case)\n -->\n <div hx-get=\"/block/counter\" hx-trigger=\"load\">\n Loading counter...\n </div>\n\n <!--\n - hx-post: Send a POST request to this URL when clicked\n - hx-target: Update the previous div with the response\n -->\n <button hx-post=\"/block/counter\" hx-target=\"previous div\">\n Increment\n </button>\n</body>\n</html>\n```\n\n### 3. Create a Template Block\n\nCreate a directory named `templates/blocks` and add a file named `counter.html`:\n\n```html\n<div>\n <!-- This simple template will be rendered and returned for both GET and POST requests -->\n <h2>Counter: [[ count ]]</h2>\n</div>\n```\n\n### 4. Create a Configuration File\n\nCreate a directory named `settings` and add a file named `app.yml`:\n\n```yaml\napp:\n name: \"MyFastBlocksApp\"\n title: \"My First FastBlocks App\"\n debug: true\n\n# Configure session middleware\nsession:\n secret_key: \"your-secret-key-here\" # In production, use a secure random key\n max_age: 14400 # Session timeout in seconds (4 hours)\n```\n\n### 5. Run Your Application\n\nRun your application with Uvicorn:\n\n```bash\nuvicorn myapp:app --reload\n```\n\nNow visit http://localhost:8000 in your browser. You should see your page with a counter and an increment button. When you click the button, the counter will increment without a page reload - that's HTMX and FastBlocks working together!\n\n## Common Patterns\n\nHere are some common patterns and examples that will help you get started with FastBlocks:\n\n### 1. Rendering Template Blocks for HTMX\n\nOne of the most common patterns in FastBlocks is rendering specific template blocks for HTMX requests:\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def user_profile_block(request, templates: Templates = depends()):\n user_id = request.path_params[\"user_id\"]\n\n # Fetch user data (in a real app, this would come from a database)\n user = {\"id\": user_id, \"name\": f\"User {user_id}\", \"email\": f\"user{user_id}@example.com\"}\n\n # Render just the user profile block\n return await templates.app.render_template_block(\n request,\n \"users/profile.html\", # Template file\n \"profile_block\", # Block name within the template\n context={\"user\": user}\n )\n\nroutes = [\n Route(\"/users/{user_id}/profile\", endpoint=user_profile_block)\n]\n```\n\nTemplate (`templates/users/profile.html`):\n\n```html\n{% block profile_block %}\n<div class=\"user-profile\">\n <h2>[[ user.name ]]</h2>\n <p>Email: [[ user.email ]]</p>\n</div>\n{% endblock %}\n```\n\nHTML with HTMX:\n\n```html\n<!-- Load user profile when button is clicked -->\n<button hx-get=\"/users/123/profile\" hx-target=\"#profile-container\">\n Load Profile\n</button>\n<div id=\"profile-container\"></div>\n```\n\n### 2. Form Submission with HTMX\n\nHandling form submissions with HTMX is straightforward in FastBlocks:\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def contact_form(request, templates: Templates = depends()):\n if request.method == \"POST\":\n # Get form data\n form_data = await request.form()\n name = form_data.get(\"name\")\n email = form_data.get(\"email\")\n message = form_data.get(\"message\")\n\n # In a real app, you would save this to a database\n # For this example, we'll just return a success message\n\n # Return just the success message block\n return await templates.app.render_template_block(\n request,\n \"contact/form.html\",\n \"success_block\",\n context={\"name\": name}\n )\n\n # For GET requests, render the form\n return await templates.app.render_template(\n request,\n \"contact/form.html\",\n context={}\n )\n\nroutes = [\n Route(\"/contact\", endpoint=contact_form, methods=[\"GET\", \"POST\"])\n]\n```\n\nTemplate (`templates/contact/form.html`):\n\n```html\n<!-- Main template content -->\n<h1>Contact Us</h1>\n\n<!-- Form that submits via HTMX -->\n<form hx-post=\"/contact\" hx-swap=\"outerHTML\">\n <div class=\"form-group\">\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n </div>\n <div class=\"form-group\">\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n </div>\n <div class=\"form-group\">\n <label for=\"message\">Message:</label>\n <textarea id=\"message\" name=\"message\" required></textarea>\n </div>\n <button type=\"submit\">Send Message</button>\n</form>\n\n<!-- Success message block that will replace the form -->\n{% block success_block %}\n<div class=\"success-message\">\n <h2>Thank you, [[ name ]]!</h2>\n <p>Your message has been sent successfully.</p>\n <button hx-get=\"/contact\" hx-target=\"this\" hx-swap=\"outerHTML\">Send Another Message</button>\n</div>\n{% endblock %}\n```\n\n### 3. Using Dependency Injection\n\nFastBlocks leverages ACB's dependency injection system to make components easily accessible:\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\nfrom acb.config import Config\n\n# Import adapters using the new direct import pattern\nTemplates = import_adapter(\"templates\")\nCache = import_adapter(\"cache\")\n\n@depends.inject\nasync def dashboard(request,\n templates: Templates = depends(),\n cache: Cache = depends(),\n config: Config = depends()):\n # Get cached data or compute it\n cache_key = \"dashboard_stats\"\n stats = await cache.get(cache_key)\n\n if not stats:\n # In a real app, you would fetch this from a database\n stats = {\n \"users\": 1250,\n \"posts\": 5432,\n \"comments\": 15876\n }\n\n # Cache the stats for 5 minutes\n await cache.set(cache_key, stats, ttl=300)\n\n # Get app name from configuration\n app_name = config.app.name\n\n return await templates.app.render_template(\n request,\n \"dashboard.html\",\n context={\n \"app_name\": app_name,\n \"stats\": stats\n }\n )\n\nroutes = [\n Route(\"/dashboard\", endpoint=dashboard)\n]\n```\n\n**Note**: This example uses the new v0.13.2+ import patterns. The template system automatically handles dependency resolution with fallbacks, so if cache is unavailable, the function will still work correctly.\n\n## Architecture Overview\n\n### Relationship with Starlette\n\nFastBlocks is built directly on top of [Starlette](https://www.starlette.io/), extending its capabilities for server-side rendered applications:\n\n- **Class Extension**: The `FastBlocks` class extends Starlette's `Starlette` application class, inheriting all its core functionality\n\n- **Enhanced Request Handling**: Extends Starlette's request handling with HTMX-specific features through the `HtmxRequest` class\n\n- **Middleware Extensions**: Adds specialized middleware components on top of Starlette's middleware system\n\n- **Template Integration**: Enhances Starlette with advanced template rendering capabilities\n\n- **Error Handling**: Extends Starlette's exception handling with template-aware error responses\n\nThis approach allows FastBlocks to leverage Starlette's robust ASGI implementation while adding specialized features for server-side rendering and HTMX integration.\n\n### Relationship with ACB\n\nFastBlocks is built on top of [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb), which provides the foundational architecture. The relationship can be summarized as:\n\n- **Foundation vs. Framework**: ACB provides the core infrastructure (dependency injection, configuration, adapters pattern) while FastBlocks is a web application framework built on this foundation.\n\n- **Dependency Chain**: User Application \u2192 FastBlocks \u2192 Starlette + ACB \u2192 Python Standard Library\n\n- **Component Architecture**: FastBlocks extends ACB's component architecture with web-specific components like templates, routing, and HTMX integration.\n\n- **Adapter Pattern**: FastBlocks uses ACB's adapter pattern to create pluggable components for authentication, admin interfaces, templates, etc.\n\n#### Direct ACB Integration (v0.13.2+)\n\nRecent improvements include simplified dependency management through direct ACB imports:\n\n```python\n# Direct ACB imports for better performance\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\nfrom acb.config import Config\n\n# Get adapters directly from ACB\nTemplates = import_adapter(\"templates\")\nApp = import_adapter(\"app\")\n\n# Access configuration and dependencies\nconfig = depends.get(Config)\n```\n\n**Benefits of Direct Integration:**\n\n- **Performance**: Eliminates wrapper overhead for faster adapter access\n- **Type Safety**: Better type annotations and IDE support\n- **Error Handling**: Enhanced error recovery with automatic fallbacks\n- **Maintainability**: Aligned with ACB patterns for easier maintenance\n- **Future-Proof**: Direct compatibility with ACB framework evolution\n\nThis separation allows FastBlocks to focus on web application concerns while leveraging ACB's robust component architecture for the underlying infrastructure.\n\n### Server-Side Rendering with HTMX\n\nFastBlocks is particularly well-suited for modern server-side rendering applications that use HTMX, offering several advantages over traditional approaches:\n\n- **Reduced Complexity**: Avoid complex client-side state management and JavaScript frameworks\n- **Improved Performance**: Server-side rendering can deliver faster initial page loads and smaller payloads\n- **SEO-Friendly**: Fully rendered HTML content for better search engine optimization\n- **Progressive Enhancement**: Start with functional HTML and enhance with HTMX for interactivity\n- **Simplified Architecture**: Keep business logic on the server where it belongs\n- **Reduced Development Time**: Use HTML templates and simple endpoints instead of complex API design\n\nThe combination of FastBlocks' templating system and HTMX offers a modern alternative to complex SPA frameworks, particularly for:\n\n- **Admin dashboards**: Where business logic complexity outweighs UI complexity\n- **Content management systems**: Where SEO and initial load performance are critical\n- **Internal tools**: Where development speed and maintainability are prioritized over cutting-edge UIs\n- **Applications with complex business logic**: Where keeping logic on the server simplifies testing and validation\n\n### Project Structure\n\nFastBlocks follows a component-based architecture with automatic discovery and registration of modules:\n\n```\nfastblocks/\n\u251c\u2500\u2500 actions/ # Utility functions (minify)\n\u251c\u2500\u2500 adapters/ # Integration modules for external systems\n\u2502 \u251c\u2500\u2500 app/ # Application configuration\n\u2502 \u251c\u2500\u2500 auth/ # Authentication adapters\n\u2502 \u251c\u2500\u2500 admin/ # Admin interface adapters\n\u2502 \u251c\u2500\u2500 routes/ # Routing adapters\n\u2502 \u251c\u2500\u2500 sitemap/ # Sitemap generation\n\u2502 \u2514\u2500\u2500 templates/ # Template engine adapters\n\u251c\u2500\u2500 applications.py # FastBlocks application class\n\u251c\u2500\u2500 middleware.py # ASGI middleware components\n\u2514\u2500\u2500 ...\n```\n\n## Core Components\n\n### Templates\n\nFastBlocks uses an enhanced asynchronous Jinja2 template system designed specifically for HTMX integration and server-side rendering.\n\n#### Key Features\n\n- **Async Template Loading**: Load templates asynchronously from file system, cloud storage, or Redis\n- **Template Fragments**: Render specific blocks of templates for HTMX partial updates\n- **Custom Delimiters**: Uses `[[` and `]]` for variables instead of `{{` and `}}` to avoid conflicts with JavaScript frameworks\n- **Bytecode Caching**: Redis-based bytecode caching for improved performance\n- **Built-in Filters**: Includes filters for minification, URL encoding, and more\n- **Null Safety**: Enhanced dependency resolution with automatic fallbacks for missing components\n- **Error Recovery**: Graceful handling of cache, storage, and dependency failures\n\n#### Basic Template Usage\n\n```python\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def homepage(request, templates: Templates = depends()):\n # Render a full template\n return await templates.app.render_template(\n request,\n \"index.html\", # Template file path relative to templates directory\n context={\"title\": \"FastBlocks Demo\", \"user\": {\"name\": \"John\"}}\n )\n```\n\n#### Template Structure\n\nFastBlocks templates use Jinja2 syntax with custom delimiters:\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n <title>[[ title ]]</title> <!-- Note the [[ ]] delimiters instead of {{ }} -->\n</head>\n<body>\n <h1>Welcome, [[ user.name ]]!</h1>\n\n {% block content %}\n <p>This is the default content.</p>\n {% endblock %}\n</body>\n</html>\n```\n\n#### Template Inheritance\n\nYou can use Jinja2's template inheritance:\n\n```html\n<!-- templates/base.html -->\n<!DOCTYPE html>\n<html>\n<head>\n <title>[[ title ]]</title>\n <link rel=\"stylesheet\" href=\"/static/css/style.css\">\n {% block head %}{% endblock %}\n</head>\n<body>\n <header>\n <nav><!-- Navigation --></nav>\n </header>\n\n <main>\n {% block content %}{% endblock %}\n </main>\n\n <footer>\n © [[ current_year ]] FastBlocks Demo\n </footer>\n</body>\n</html>\n```\n\n```html\n<!-- templates/home.html -->\n{% extends \"base.html\" %}\n\n{% block head %}\n<script src=\"https://unpkg.com/htmx.org@1.9.10\"></script>\n{% endblock %}\n\n{% block content %}\n<h1>Welcome to [[ title ]]</h1>\n<div id=\"counter-container\" hx-get=\"/block/counter\" hx-trigger=\"load\">\n Loading...\n</div>\n{% endblock %}\n```\n\n#### Template Blocks for HTMX\n\nCreate template blocks specifically for HTMX responses:\n\n```html\n<!-- templates/blocks/counter.html -->\n{% block counter_block %}\n<div class=\"counter\">\n <h2>Count: [[ count ]]</h2>\n <button hx-post=\"/block/counter\" hx-target=\"#counter-container\">Increment</button>\n</div>\n{% endblock %}\n```\n\n```python\n@depends.inject\nasync def counter_block(request, templates: Templates = depends()):\n count = request.session.get(\"count\", 0)\n if request.method == \"POST\":\n count += 1\n request.session[\"count\"] = count\n\n # Render just the counter block\n return await templates.app.render_template_block(\n request,\n \"blocks/counter.html\", # Template file\n \"counter_block\", # Block name within the template\n context={\"count\": count}\n )\n```\n\n#### Custom Filters\n\nFastBlocks includes several built-in filters and you can add your own:\n\n```python\nfrom acb.adapters import import_adapter\n\nTemplates = import_adapter(\"templates\")\n\n# Register a custom filter\n@Templates.filter()\ndef capitalize_words(value: str) -> str:\n return \" \".join(word.capitalize() for word in value.split())\n```\n\nUsage in templates:\n\n```html\n<h1>[[ user.name | capitalize_words ]]</h1>\n```\n\n#### Built-in Filters\n\nFastBlocks includes several useful filters:\n\n- **minify_html**: Minifies HTML content\n- **minify_js**: Minifies JavaScript content\n- **minify_css**: Minifies CSS content\n- **map_src**: URL-encodes strings for use in URLs\n\n#### Enhanced Dependency Resolution\n\nVersion 0.13.2 introduces robust dependency resolution with automatic fallbacks:\n\n```python\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def my_view(request, templates: Templates = depends()):\n # FastBlocks automatically handles:\n # 1. Primary dependency resolution via depends.get()\n # 2. Fallback to get_adapter() if primary fails\n # 3. Null safety checks throughout the template system\n # 4. Graceful error handling for missing dependencies\n\n return await templates.app.render_template(\n request, \"my_template.html\", context={\"data\": \"value\"}\n )\n```\n\nThe template system now includes:\n\n- **Automatic Fallbacks**: If cache or storage dependencies are unavailable, the system continues with file-based templates\n- **Null Safety**: All operations check for null dependencies and provide sensible defaults\n- **Error Recovery**: Template loading failures are handled gracefully with meaningful error messages\n- **Dependency Order**: `depends.get()` is tried first, followed by `get_adapter()` fallback\n\n### Routing\n\nThe routing system extends Starlette's routing with enhanced features for HTMX and server-side rendering.\n\n#### Key Features\n\n- **Automatic Route Discovery**: Routes are automatically discovered and registered\n- **HTMX-Aware Endpoints**: Built-in support for HTMX requests and responses\n- **Block Rendering**: Specialized endpoints for rendering template blocks\n\n#### Basic Routing\n\nFastBlocks supports Starlette's routing patterns with additional features:\n\n```python\nfrom starlette.routing import Route, Mount\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def homepage(request, templates: Templates = depends()):\n return await templates.app.render_template(\n request, \"index.html\", context={\"title\": \"FastBlocks Demo\"}\n )\n\n@depends.inject\nasync def about(request, templates: Templates = depends()):\n return await templates.app.render_template(\n request, \"about.html\", context={\"title\": \"About Us\"}\n )\n\n# Define your routes\nroutes = [\n Route(\"/\", endpoint=homepage),\n Route(\"/about\", endpoint=about),\n Mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\"),\n]\n```\n\n#### Route Discovery\n\nFastBlocks can automatically discover and register routes from your application:\n\n```python\n# routes.py\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def homepage(request, templates: Templates = depends()):\n return await templates.app.render_template(\n request, \"index.html\", context={\"title\": \"FastBlocks Demo\"}\n )\n\n# Export routes to be automatically discovered\nroutes = [\n Route(\"/\", endpoint=homepage),\n]\n```\n\n#### Path Parameters\n\nYou can use path parameters in your routes:\n\n```python\n@depends.inject\nasync def user_profile(request, templates: Templates = depends()):\n user_id = request.path_params[\"user_id\"]\n # Fetch user data...\n return await templates.app.render_template(\n request, \"user/profile.html\", context={\"user_id\": user_id}\n )\n\nroutes = [\n Route(\"/users/{user_id}\", endpoint=user_profile),\n]\n```\n\n#### HTMX-Specific Routes\n\nCreate routes specifically for HTMX interactions:\n\n```python\n@depends.inject\nasync def load_more_items(request, templates: Templates = depends()):\n page = int(request.query_params.get(\"page\", 1))\n # Fetch items for the requested page...\n items = [f\"Item {i}\" for i in range((page-1)*10, page*10)]\n\n # Return just the items block for HTMX to insert\n return await templates.app.render_template_block(\n request,\n \"items.html\",\n \"items_block\",\n context={\"items\": items, \"page\": page}\n )\n\nroutes = [\n Route(\"/api/items\", endpoint=load_more_items),\n]\n```\n\n### Middleware\n\nFastBlocks includes several middleware components:\n\n- **HTMX Middleware**: Adds HTMX-specific request information\n- **CSRF Protection**: Built-in CSRF protection for forms\n- **Session Middleware**: Cookie-based session management\n- **Compression**: Brotli compression for reduced payload sizes\n- **Secure Headers**: Security headers for production environments\n- **Cache Middleware**: HTTP response caching with rule-based configuration\n- **Cache Control Middleware**: Simplified management of cache control headers\n- **Process Time Header Middleware**: Measures and logs request processing time\n- **Current Request Middleware**: Makes the current request available via a context variable\n\n#### Middleware Ordering\n\nFastBlocks uses a position-based middleware system to ensure middleware components are executed in the correct order. The middleware execution flow follows the ASGI specification:\n\n1. The last middleware in the list is the first to process the request\n2. The first middleware in the list is the last to process the request\n\nThe actual execution flow is:\n- ExceptionMiddleware (outermost - first to see request, last to see response)\n- System middleware (ordered by MiddlewarePosition enum)\n- User-provided middleware\n- ServerErrorMiddleware (innermost - last to see request, first to see response)\n\n#### Adding Custom Middleware\n\nYou can add custom middleware to your FastBlocks application in two ways:\n\n1. **User Middleware**: Added to the user middleware stack\n\n```python\n# Add a middleware to the end of the user middleware stack\napp.add_middleware(CustomMiddleware, option=\"value\")\n\n# Add a middleware at a specific position in the user middleware stack\napp.add_middleware(CustomMiddleware, position=0, option=\"value\")\n```\n\n2. **System Middleware**: Replace middleware at specific positions defined by the MiddlewarePosition enum\n\n```python\nfrom fastblocks.middleware import MiddlewarePosition\n\n# Replace the compression middleware with a custom implementation\napp.add_system_middleware(\n CustomMiddleware,\n position=MiddlewarePosition.COMPRESSION,\n option=\"value\"\n)\n```\n\n#### Example: Custom Middleware\n\nHere's a complete example of creating and adding custom middleware:\n\n```python\nfrom typing import Any\nfrom starlette.types import ASGIApp, Receive, Scope, Send\nfrom fastblocks import FastBlocks\nfrom fastblocks.middleware import MiddlewarePosition\n\n# Define a simple custom middleware\nclass CustomHeaderMiddleware:\n \"\"\"A middleware that adds a custom header to responses.\"\"\"\n\n def __init__(self, app: ASGIApp, header_name: str, header_value: str) -> None:\n self.app = app\n self.header_name = header_name\n self.header_value = header_value\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] != \"http\":\n await self.app(scope, receive, send)\n return\n\n async def send_with_header(message: dict[str, Any]) -> None:\n if message[\"type\"] == \"http.response.start\":\n headers = message.get(\"headers\", [])\n headers.append(\n (self.header_name.encode(), self.header_value.encode())\n )\n message[\"headers\"] = headers\n await send(message)\n\n await self.app(scope, receive, send_with_header)\n\n# Create a FastBlocks application\napp = FastBlocks()\n\n# Add a custom middleware to the user middleware stack\napp.add_middleware(\n CustomHeaderMiddleware,\n header_name=\"X-Custom-User\",\n header_value=\"User-defined\"\n)\n\n# Replace the compression middleware with a custom implementation\napp.add_system_middleware(\n CustomHeaderMiddleware,\n position=MiddlewarePosition.COMPRESSION,\n header_name=\"X-Custom-Compression\",\n header_value=\"Replaced\"\n)\n```\n\n#### Middleware Positions\n\nThe `MiddlewarePosition` enum defines the positions of middleware in the system stack:\n\n```python\nclass MiddlewarePosition(IntEnum):\n # Core middleware (always present)\n PROCESS_TIME = 0 # First middleware to see request, last to see response\n CSRF = 1 # Security middleware should be early in the chain\n SESSION = 2 # Session handling (if auth enabled)\n HTMX = 3 # HTMX request processing\n CURRENT_REQUEST = 4 # Request context tracking\n COMPRESSION = 5 # Response compression\n SECURITY_HEADERS = 6 # Security headers for responses\n```\n\nYou can get a dictionary of middleware positions using the `get_middleware_positions()` function:\n\n```python\nfrom fastblocks.middleware import get_middleware_positions\n\npositions = get_middleware_positions()\nprint(positions) # {'PROCESS_TIME': 0, 'CSRF': 1, ...}\n```\n\n### HTMX Integration\n\nFastBlocks is designed to work seamlessly with HTMX, a lightweight JavaScript library that allows you to access modern browser features directly from HTML attributes.\n\n#### Key HTMX Features in FastBlocks\n\n- **HtmxRequest**: Extended request object with HTMX-specific attributes\n- **Template Blocks**: Specialized endpoints for rendering template fragments\n- **Push URL**: Automatic URL updates for browser history\n- **Response Headers**: Helper methods for setting HTMX-specific response headers\n\n#### Using HTMX Request Properties\n\nFastBlocks extends Starlette's request object with HTMX-specific properties:\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def product_detail(request, templates: Templates = depends()):\n product_id = request.path_params[\"product_id\"]\n\n # Check if this is an HTMX request\n if request.htmx:\n # Access HTMX-specific properties\n is_boosted = request.htmx.boosted # True if hx-boost was used\n trigger = request.htmx.trigger # ID of the element that triggered the request\n target = request.htmx.target # ID of the target element\n\n # For HTMX requests, render just the product details block\n return await templates.app.render_template_block(\n request,\n \"products/detail.html\",\n \"product_detail_block\",\n context={\"product_id\": product_id}\n )\n\n # For regular requests, render the full page\n return await templates.app.render_template(\n request,\n \"products/detail.html\",\n context={\"product_id\": product_id}\n )\n\nroutes = [\n Route(\"/products/{product_id}\", endpoint=product_detail)\n]\n```\n\n#### Setting HTMX Response Headers\n\nFastBlocks makes it easy to set HTMX-specific response headers:\n\n```python\nfrom starlette.responses import Response\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\nTemplates = import_adapter(\"templates\")\n\n@depends.inject\nasync def search_results(request, templates: Templates = depends()):\n query = request.query_params.get(\"q\", \"\")\n\n # Render the search results\n response = await templates.app.render_template_block(\n request,\n \"search/results.html\",\n \"results_block\",\n context={\"query\": query, \"results\": []}\n )\n\n # Set HTMX-specific headers\n response.headers[\"HX-Push-Url\"] = f\"/search?q={query}\" # Update browser URL\n response.headers[\"HX-Trigger\"] = \"search-complete\" # Trigger client-side events\n\n return response\n\nroutes = [\n Route(\"/search\", endpoint=search_results)\n]\n```\n\n#### Common HTMX Patterns\n\nHere are some common HTMX patterns you can use with FastBlocks:\n\n- **Click to Load**: `<button hx-get=\"/more\" hx-target=\"#content\">Load More</button>`\n- **Form Submission**: `<form hx-post=\"/submit\" hx-swap=\"outerHTML\">...</form>`\n- **Infinite Scroll**: `<div hx-get=\"/next-page\" hx-trigger=\"revealed\" hx-swap=\"afterend\"></div>`\n- **Active Search**: `<input type=\"text\" name=\"q\" hx-get=\"/search\" hx-trigger=\"keyup changed delay:500ms\" hx-target=\"#results\">`\n- **Confirmation Dialog**: `<button hx-delete=\"/item/1\" hx-confirm=\"Are you sure?\">Delete</button>`\n\n## Adapters\n\nFastBlocks uses a pluggable adapter system for various components:\n\n- **App**: Application configuration and initialization\n- **Auth**: Authentication providers (Basic, etc.)\n- **Admin**: Admin interface providers (SQLAdmin)\n- **Routes**: Route management and discovery\n- **Templates**: Template engine adapters (Jinja2)\n- **Sitemap**: Sitemap generation\n\n#### Application Initialization Improvements (v0.13.2)\n\nThe FastBlocks application initialization process has been streamlined for better performance and reliability:\n\n```python\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\n# Get the application instance\nApp = import_adapter(\"app\")\napp = depends.get(App)\n\n# The app is now pre-configured with:\n# - Enhanced middleware stack management\n# - Optimized dependency resolution\n# - Improved error handling\n# - Lazy loading for optional components\n```\n\n**Key Improvements:**\n\n- **Faster Startup**: Lazy loading of non-critical components reduces initialization time\n- **Better Error Handling**: Clear error messages for configuration issues and missing dependencies\n- **Middleware Optimization**: Position-based middleware management with caching\n- **Memory Efficiency**: Reduced memory footprint through optimized component loading\n\nFor more information about adapters, see the [Adapters Documentation](./fastblocks/adapters/README.md).\n\n## Actions\n\nActions are utility functions that perform specific tasks:\n\n- **Gather**: Discover and consolidate routes, templates, middleware, models, and application components\n- **Sync**: Bidirectional synchronization of templates, settings, and cache across environments\n- **Minify**: HTML, CSS, and JavaScript minification\n\nFor more information about actions, see the [Actions Documentation](./fastblocks/actions/README.md).\n\n## Configuration\n\nFastBlocks uses ACB's configuration system based on Pydantic, which provides a unified way to manage settings from multiple sources:\n\n```python\nfrom acb.config import Config\nfrom acb.depends import depends\n\nconfig = depends.get(Config)\n\n# Access configuration values\nsecret_key = config.app.secret_key\ndebug_mode = config.debug.fastblocks\n```\n\n### Configuration Sources\n\n- **YAML Files**: Environment-specific settings in YAML format (settings/app.yml, settings/debug.yml, etc.)\n- **Secret Files**: Secure storage of sensitive information\n- **Environment Variables**: Override configuration via environment variables\n\n### FastBlocks-Specific Configuration\n\nFastBlocks extends ACB's configuration system with web-specific settings for templates, routing, middleware, and more. These settings are automatically loaded and validated using Pydantic models.\n\n## Command-Line Interface (CLI)\n\nFastBlocks includes a powerful CLI tool to help you create and run applications.\n\n### Installation\n\nWhen you install FastBlocks, the CLI is automatically available:\n\n```bash\npython -m fastblocks --help\n```\n\n### Creating a New Project\n\nCreate a new FastBlocks project with the `create` command:\n\n```bash\npython -m fastblocks create\n```\n\nYou'll be prompted for:\n- **app_name**: Name of your application\n- **style**: UI framework to use (bulma, webawesome, or custom)\n- **domain**: Application domain\n\nThis will create a new directory with the following structure:\n\n```\nmyapp/\n\u251c\u2500\u2500 __init__.py\n\u251c\u2500\u2500 .envrc\n\u251c\u2500\u2500 adapters/\n\u2502 \u2514\u2500\u2500 __init__.py\n\u251c\u2500\u2500 actions/\n\u2502 \u2514\u2500\u2500 __init__.py\n\u251c\u2500\u2500 main.py\n\u251c\u2500\u2500 models.py\n\u251c\u2500\u2500 pyproject.toml\n\u251c\u2500\u2500 routes.py\n\u251c\u2500\u2500 settings/\n\u2502 \u251c\u2500\u2500 adapters.yml\n\u2502 \u251c\u2500\u2500 app.yml\n\u2502 \u2514\u2500\u2500 debug.yml\n\u2514\u2500\u2500 templates/\n \u251c\u2500\u2500 base/\n \u2502 \u2514\u2500\u2500 blocks/\n \u2514\u2500\u2500 style/\n \u251c\u2500\u2500 blocks/\n \u2514\u2500\u2500 theme/\n```\n\n### Running Your Application\n\nRun your application in development mode with hot-reloading:\n\n```bash\npython -m fastblocks dev\n```\n\nThe development server includes enhanced features:\n- **Optimized Logging**: Uvicorn logging is integrated with ACB's InterceptHandler for cleaner output\n- **Smart Reloading**: Excludes `tmp/*`, `settings/*`, and `templates/*` directories from reload monitoring for better performance\n- **Template Development**: Templates are excluded from reload to prevent unnecessary restarts during template development\n\nRun your application in production mode:\n\n```bash\npython -m fastblocks run\n```\n\nRun your application with Granian (high-performance ASGI server):\n\n```bash\npython -m fastblocks dev --granian\n```\n\nRun your application in a Docker container:\n\n```bash\npython -m fastblocks run --docker\n```\n\n### CLI Options\n\n#### Create Command\n\n```bash\npython -m fastblocks create --app-name myapp --style bulma --domain example.com\n```\n\n#### Dev Command\n\n```bash\npython -m fastblocks dev [--granian] [--host HOST] [--port PORT]\n```\n\nRunning with hot-reloading enabled for development.\n\n#### Run Command\n\n```bash\npython -m fastblocks run [--docker] [--granian] [--host HOST] [--port PORT]\n```\n\nRun in production mode.\n\n#### Components Command\n\n```bash\npython -m fastblocks components\n```\n\nShow available FastBlocks components and their status.\n\n## Migration Guide\n\n### Updating from Version 0.13.1 to 0.13.2\n\nVersion 0.13.2 introduces simplified dependency management with direct ACB imports. While existing code will continue to work, we recommend updating to the new patterns for better performance and maintainability.\n\n#### Import Pattern Changes\n\n**Before (v0.13.1 and earlier):**\n```python\n# Old wrapper-based imports\nfrom fastblocks.dependencies import Templates, App\nfrom fastblocks.config import config\n```\n\n**After (v0.13.2+):**\n```python\n# Direct ACB imports (recommended)\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\nfrom acb.config import Config\n\nTemplates = import_adapter(\"templates\")\nApp = import_adapter(\"app\")\nconfig = depends.get(Config)\n```\n\n#### Route Handler Updates\n\n**Before:**\n```python\n@depends.inject\nasync def homepage(request, templates=depends(Templates)):\n return await templates.render_template(request, \"index.html\")\n```\n\n**After:**\n```python\n@depends.inject\nasync def homepage(request, templates: Templates = depends()):\n return await templates.app.render_template(request, \"index.html\")\n```\n\n#### Benefits of the New Pattern\n\n1. **Better Performance**: Direct ACB access eliminates wrapper overhead\n2. **Improved Type Safety**: Explicit type annotations with adapters\n3. **Enhanced Error Handling**: Built-in fallback mechanisms for missing dependencies\n4. **Future Compatibility**: Aligned with ACB framework patterns\n\n#### Template System Improvements\n\nVersion 0.13.2 includes enhanced null safety in template loaders:\n\n- Automatic fallback when dependencies are unavailable\n- Improved error messages for missing templates\n- Better handling of cache and storage failures\n- Enhanced dependency resolution order\n\n#### CLI Enhancements\n\nThe CLI now includes:\n\n- Optimized uvicorn logging configuration\n- Template reload exclusions for better development experience\n- Enhanced error reporting for configuration issues\n\n## Examples\n\n### Creating a Dynamic Counter with HTMX\n\n```python\nfrom starlette.routing import Route\nfrom acb.adapters import import_adapter\nfrom acb.depends import depends\n\n# Import adapters\nTemplates = import_adapter(\"templates\")\nApp = import_adapter(\"app\")\n\ncounter = 0\n\n@depends.inject\nasync def get_counter(request, templates: Templates = depends()):\n return await templates.app.render_template(\n request, \"blocks/counter.html\", context={\"count\": counter}\n )\n\n@depends.inject\nasync def increment_counter(request, templates: Templates = depends()):\n global counter\n counter += 1\n return await templates.app.render_template(\n request, \"blocks/counter.html\", context={\"count\": counter}\n )\n\nroutes = [\n Route(\"/block/counter\", endpoint=get_counter, methods=[\"GET\"]),\n Route(\"/block/counter\", endpoint=increment_counter, methods=[\"POST\"]),\n]\n\n# Create the application\napp = depends.get(App)\n```\n\n## Documentation\n\nFor more detailed documentation about FastBlocks components:\n\n- [**Core Features**](./fastblocks/README.md): Applications, middleware, and core functionality\n- [**Actions**](./fastblocks/actions/README.md): Utility functions like minification\n- [**Adapters**](./fastblocks/adapters/README.md): Pluggable components for various features\n - [**App Adapter**](./fastblocks/adapters/app/README.md): Application configuration\n - [**Auth Adapter**](./fastblocks/adapters/auth/README.md): Authentication providers\n - [**Admin Adapter**](./fastblocks/adapters/admin/README.md): Admin interface\n - [**Routes Adapter**](./fastblocks/adapters/routes/README.md): Routing system\n - [**Templates Adapter**](./fastblocks/adapters/templates/README.md): Template engine\n - [**Sitemap Adapter**](./fastblocks/adapters/sitemap/README.md): Sitemap generation\n- [**Running Tests**](./tests/TESTING.md): Comprehensive guide to testing FastBlocks components\n\n## License\n\nThis project is licensed under the terms of the BSD 3-Clause license.\n\n## Acknowledgements\n\nSpecial thanks to the following open-source projects that power FastBlocks:\n\n### Foundation\n- [Starlette](https://www.starlette.io/) - The ASGI framework that FastBlocks directly extends, providing the web application foundation\n- [Asynchronous Component Base (ACB)](https://github.com/lesleslie/acb) - The core infrastructure providing dependency injection, configuration, and component architecture\n\n### Frontend & Templates\n- [HTMX](https://htmx.org/) - The lightweight JavaScript library for dynamic interfaces\n- [Jinja2](https://jinja.palletsprojects.com/) - The template engine\n- [jinja2-async-environment](https://github.com/lesleslie/jinja2-async-environment) - Asynchronous Jinja2 environment\n- [starlette-async-jinja](https://github.com/lesleslie/starlette-async-jinja) - Starlette integration for async Jinja2\n\n### Data & Validation\n- [Pydantic](https://pydantic-docs.helpmanual.io/) - Data validation and settings management\n- [SQLAlchemy](https://www.sqlalchemy.org/) - SQL toolkit and ORM\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Starlette based app for the rapid delivery of HTMX/Jinja template blocks",
"version": "0.14.0",
"project_urls": null,
"split_keywords": [
"htmx",
" httpx",
" jinja",
" pydantic",
" redis",
" sqladmin",
" sqlalchemy",
" sqlmodel",
" starlette"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b925a03e7b9869c43a362d3994c7134dec5722f94116b7ab8bb39b3dbfc050e0",
"md5": "ffe187228b84bf87e88d8590306c660f",
"sha256": "7db00b4d9879f2f74da041877d87e7960f3a5d20c8b361e0e5b3485774166efe"
},
"downloads": -1,
"filename": "fastblocks-0.14.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ffe187228b84bf87e88d8590306c660f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 146305,
"upload_time": "2025-07-12T19:44:41",
"upload_time_iso_8601": "2025-07-12T19:44:41.239132Z",
"url": "https://files.pythonhosted.org/packages/b9/25/a03e7b9869c43a362d3994c7134dec5722f94116b7ab8bb39b3dbfc050e0/fastblocks-0.14.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "be3fe0f7dbe1b9cf2f959266d6a275cdc25fe1534240d2b11b1004332b03ae82",
"md5": "a4d8ba9ac0335809d1d45d14db563372",
"sha256": "053323b069c4729b643e0e766321ea88d24936de8b3744a01eebe0507532c6ce"
},
"downloads": -1,
"filename": "fastblocks-0.14.0.tar.gz",
"has_sig": false,
"md5_digest": "a4d8ba9ac0335809d1d45d14db563372",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 208530,
"upload_time": "2025-07-12T19:44:42",
"upload_time_iso_8601": "2025-07-12T19:44:42.894176Z",
"url": "https://files.pythonhosted.org/packages/be/3f/e0f7dbe1b9cf2f959266d6a275cdc25fe1534240d2b11b1004332b03ae82/fastblocks-0.14.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-12 19:44:42",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "fastblocks"
}