A simple, easy-to-use blog application built with FastAPI.
- Write blog posts in Markdown
- Syntax highlighting for code blocks
- Responsive design
- Dark mode
- Overloadable templates
- Live, working configuration examples
- SEO-friendly
- Sitemap
- Docker support
- Import the
add_blog_to_fastapi
function - Run the instantiated FastAPI app through the
add_blog_to_fastapi
function
This all you need to do:
from fastapi_blog import add_blog_to_fastapi
from fastapi import FastAPI
app = FastAPI()
app = add_blog_to_fastapi(app)
@app.get("/")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": "http://localhost:8000/blog",
}
- Add the first blog entry
Assuming your FastAPI app is defined in a main.py
module at the root of your project, create a file at posts/first-blog-post.md
:
---
date: "2024-03-21T22:20:50.52Z"
published: true
tags:
- fastapi
- fastapi-blog
title: First blog post
description: This is the first blog post entry.
---
Exciting times in the world of fastapi-blog are ahead!
## This is a markdown header
And this is a markdown paragraph with a [link](https://github.com/pydanny/fastapi-blog).
- Add the first page
Assuming your FastAPI app is defined in a main.py
module at the root of your project, create a file at pages/about.md
:
---
title: "About Me"
description: "A little bit of background about me"
author: "Daniel Roy Greenfeld"
---
## Intro about me
I'm probably best known as "[pydanny](https://www.google.com/search?q=pydanny)", one of the authors of Two Scoops of Django.
I love to hang out with my [wife](https://audrey.feldroy.com/), play with my [daughter](/tags/uma), do [Brazilian Jiu-Jitsu](https://academyofbrazilianjiujitsu.com/), write [books](/books), and read books.
- [Mastodon](https://fosstodon.org/@danielfeldroy)
- [LinkedIn](https://www.linkedin.com/in/danielfeldroy/)
- [Twitter](https://twitter.com/pydanny)
## About this site
This site is written in:
- Python
- FastAPI
- fastapi-blog
- Sakura minimal CSS framework
- Markdown
- Vanilla HTML
fastapi_blog is configurable through the add_blog_to_fastapi
function.
Change the main app to mount StaticFiles:
from fastapi_blog import add_blog_to_fastapi
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app = add_blog_to_fastapi(app)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": "http://localhost:8000/blog",
}
This example is Django-like in that your local templates will overload the default ones.
import fastapi_blog
import jinja2
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
django_style_jinja2_loader = jinja2.ChoiceLoader(
[
jinja2.FileSystemLoader("templates"),
jinja2.PackageLoader("fastapi_blog", "templates"),
]
)
app = FastAPI()
app = fastapi_blog.add_blog_to_fastapi(
app, prefix=prefix, jinja2_loader=django_style_jinja2_loader
)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": f"http://localhost:8000/blog",
}
Perhaps you want to have the blog at the root?
import fastapi_blog
from fastapi import FastAPI
app = FastAPI()
app = fastapi_blog.add_blog_to_fastapi(
app, prefix="change"
)
@app.get("/api")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": "http://localhost:8000/change",
}
This is for when your blog/CMS needs to be at the root of the project
import fastapi_blog
from fastapi import FastAPI
app = FastAPI()
@app.get("/api")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": "http://localhost:8000",
}
# Because the prefix is None, the call to add_blog_to_fastapi
# needs to happen after the other view functions are defined.
app = fastapi_blog.add_blog_to_fastapi(app, prefix=None)
import fastapi_blog
from fastapi import FastAPI
favorite_post_ids = {
"code-code-code",
"thirty-minute-rule",
"2023-11-three-years-at-kraken-tech",
}
app = FastAPI()
app = fastapi_blog.add_blog_to_fastapi(app, favorite_post_ids=favorite_post_ids)
@app.get("/")
async def index() -> dict:
return {
"message": "Check out the blog at the URL",
"url": "http://localhost:8000/blog",
}
In the pages
directory of your blog, add markdown files with frontmatter. You can then find it by going to the URL with that name. For example, adding this pages/about.md
to the default config would make this appear at http://localhost:8000/blog/about.
---
title: "About Daniel Roy Greenfeld"
description: "A little bit of background about Daniel Roy Greenfeld"
author: "Daniel Roy Greenfeld"
---
I'm probably best known as "[pydanny](https://www.google.com/search?q=pydanny)", one of the authors of [Two Scoops of Django](/books/tech).
You can install this into a virtualenv using the pyproject.toml file:
pip install fastapi-blog
make run
Or into a Docker container using the local Dockerfile:
docker build -t fastapi-blog .
docker run -d -p 8000:8000 fastapi-blog
Or using a prebuilt Docker image from GitHub Container Registry:
docker run -d -p 8000:8000 ghcr.io/aroygreenfeld/fastapi-blog:latest
This is if you just want to run the application without building it yourself.
-
Update the version in
pyproject.toml
andfastapi_blog/__init__.py
-
Update changelog.md
-
Build the distribution locally:
rm -rf dist
pip install -U build
python -m build
- Upload the distribution to PyPI:
pip install -U twine
python -m twine upload dist/*
- Create a new release on GitHub and tag the release:
git commit -am "Release for vXYZ"
make tag
Daniel Roy Greenfeld |
Audrey Roy Greenfeld |