fastapi-blog


Namefastapi-blog JSON
Version 0.6.0 PyPI version JSON
download
home_pageNone
SummaryBlogging for FastAPI
upload_time2024-03-24 16:35:56
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseFSL-1.0-Apache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FastAPI Blog

A simple, easy-to-use blog application built with FastAPI.

## Features

- Write blog posts in Markdown
- Syntax highlighting for code blocks
- Responsive design
- Dark mode
- Overloadable templates
- [Live, working configuration examples](https://github.com/pydanny/fastapi-blog/tree/main/tests/examples)
- SEO-friendly
- Sitemap
- Docker support

## Basic Usage

1. Import the `add_blog_to_fastapi` function
2. Run the instantiated FastAPI app through the `add_blog_to_fastapi` function

This all you need to do:

```python
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",
    }
```

3. 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`:

```markdown
---
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).
```

4. 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`:

```markdown
---
title: "About Me"
description: "A little bit of background about me"
author: "Daniel Roy Greenfeld"
---

[TOC]

## 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
```


## Advanced Usage

fastapi_blog is configurable through the `add_blog_to_fastapi` function.

### Replacing the default templates

This example is Django-like in that your local templates will overload the default ones.

```python
import fastapi_blog
import jinja2
from fastapi import FastAPI


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.get("/")
async def index() -> dict:
    return {
        "message": "Check out the blog at the URL",
        "url": f"http://localhost:8000/blog",
    }
```


### Changing the location of the blog url

Perhaps you want to have the blog at the root?

```python
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",
    }
```

## Blog at root URL

This is for when your blog/CMS needs to be at the root of the project

```python
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)
```


## Add favorite articles to the homepage

```python
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",
    }
```

### Add page not in the blog list of posts

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.

```markdown
---
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).
```


## Installation and Running Example Sites

### Option 1: Local Virtualenv

You can install this into a virtualenv using the pyproject.toml file:

```bash
pip install fastapi-blog
make run
```

### Option 2: Docker (Local Dockerfile)

Or into a Docker container using the local Dockerfile:

```bash
docker build -t fastapi-blog .
docker run -d -p 8000:8000 fastapi-blog
```

### Option 3: Docker (Prebuilt)

Or using a prebuilt Docker image from GitHub Container Registry:

```bash
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.

## Releasing a new version

1. Update the version in `pyproject.toml` and `fastapi_blog/__init__.py`

2. Update changelog.md

3. Build the distribution locally:

```bash
rm -rf dist
pip install -U build
python -m build
```

4. Upload the distribution to PyPI:

```bash
pip install -U twine
python -m twine upload dist/*
```

5. Create a new release on GitHub and tag the release:

```bash
git commit -am "Release for vXYZ"
make tag
```

## Contributors

<!-- readme: contributors -start -->
<table>
<tr>
    <td align="center">
        <a href="https://github.com/pydanny">
            <img src="https://avatars.githubusercontent.com/u/62857?v=4" width="100;" alt="pydanny"/>
            <br />
            <sub><b>Daniel Roy Greenfeld</b></sub>
        </a>
    </td>
    <td align="center">
        <a href="https://github.com/audreyfeldroy">
            <img src="https://avatars.githubusercontent.com/u/74739?v=4" width="100;" alt="audreyfeldroy"/>
            <br />
            <sub><b>Audrey Roy Greenfeld</b></sub>
        </a>
    </td></tr>
</table>
<!-- readme: contributors -end -->

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "fastapi-blog",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "Daniel Roy Greenfeld <daniel@feldroy.com>",
    "keywords": null,
    "author": null,
    "author_email": "Daniel Roy Greenfeld <daniel@feldroy.com>",
    "download_url": "https://files.pythonhosted.org/packages/5e/d3/ee10bce25b0691bfc0e733a73a94d1dbe7dcfc3d60874e9ad50ced7e4712/fastapi-blog-0.6.0.tar.gz",
    "platform": null,
    "description": "# FastAPI Blog\n\nA simple, easy-to-use blog application built with FastAPI.\n\n## Features\n\n- Write blog posts in Markdown\n- Syntax highlighting for code blocks\n- Responsive design\n- Dark mode\n- Overloadable templates\n- [Live, working configuration examples](https://github.com/pydanny/fastapi-blog/tree/main/tests/examples)\n- SEO-friendly\n- Sitemap\n- Docker support\n\n## Basic Usage\n\n1. Import the `add_blog_to_fastapi` function\n2. Run the instantiated FastAPI app through the `add_blog_to_fastapi` function\n\nThis all you need to do:\n\n```python\nfrom fastapi_blog import add_blog_to_fastapi\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\napp = add_blog_to_fastapi(app)\n\n\n@app.get(\"/\")\nasync def index() -> dict:\n    return {\n        \"message\": \"Check out the blog at the URL\",\n        \"url\": \"http://localhost:8000/blog\",\n    }\n```\n\n3. Add the first blog entry\n\nAssuming 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`:\n\n```markdown\n---\ndate: \"2024-03-21T22:20:50.52Z\"\npublished: true\ntags:\n  - fastapi\n  - fastapi-blog\ntitle: First blog post\ndescription: This is the first blog post entry.\n---\n\nExciting times in the world of fastapi-blog are ahead!\n\n## This is a markdown header\n\nAnd this is a markdown paragraph with a [link](https://github.com/pydanny/fastapi-blog).\n```\n\n4. Add the first page\n\nAssuming your FastAPI app is defined in a `main.py` module at the root of your project, create a file at `pages/about.md`:\n\n```markdown\n---\ntitle: \"About Me\"\ndescription: \"A little bit of background about me\"\nauthor: \"Daniel Roy Greenfeld\"\n---\n\n[TOC]\n\n## Intro about me\n\nI'm probably best known as \"[pydanny](https://www.google.com/search?q=pydanny)\", one of the authors of Two Scoops of Django.\n\nI 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.\n\n- [Mastodon](https://fosstodon.org/@danielfeldroy)\n- [LinkedIn](https://www.linkedin.com/in/danielfeldroy/)\n- [Twitter](https://twitter.com/pydanny)\n\n## About this site\n\nThis site is written in:\n\n- Python\n- FastAPI\n- fastapi-blog\n- Sakura minimal CSS framework\n- Markdown\n- Vanilla HTML\n```\n\n\n## Advanced Usage\n\nfastapi_blog is configurable through the `add_blog_to_fastapi` function.\n\n### Replacing the default templates\n\nThis example is Django-like in that your local templates will overload the default ones.\n\n```python\nimport fastapi_blog\nimport jinja2\nfrom fastapi import FastAPI\n\n\ndjango_style_jinja2_loader = jinja2.ChoiceLoader(\n    [\n        jinja2.FileSystemLoader(\"templates\"),\n        jinja2.PackageLoader(\"fastapi_blog\", \"templates\"),\n    ]\n)\n\napp = FastAPI()\napp = fastapi_blog.add_blog_to_fastapi(\n    app, prefix=prefix, jinja2_loader=django_style_jinja2_loader\n)\n\n\n@app.get(\"/\")\nasync def index() -> dict:\n    return {\n        \"message\": \"Check out the blog at the URL\",\n        \"url\": f\"http://localhost:8000/blog\",\n    }\n```\n\n\n### Changing the location of the blog url\n\nPerhaps you want to have the blog at the root?\n\n```python\nimport fastapi_blog\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\napp = fastapi_blog.add_blog_to_fastapi(\n    app, prefix=\"change\"\n)\n\n\n@app.get(\"/api\")\nasync def index() -> dict:\n    return {\n        \"message\": \"Check out the blog at the URL\",\n        \"url\": \"http://localhost:8000/change\",\n    }\n```\n\n## Blog at root URL\n\nThis is for when your blog/CMS needs to be at the root of the project\n\n```python\nimport fastapi_blog\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n\n@app.get(\"/api\")\nasync def index() -> dict:\n    return {\n        \"message\": \"Check out the blog at the URL\",\n        \"url\": \"http://localhost:8000\",\n    }\n\n# Because the prefix is None, the call to add_blog_to_fastapi\n# needs to happen after the other view functions are defined.\napp = fastapi_blog.add_blog_to_fastapi(app, prefix=None)\n```\n\n\n## Add favorite articles to the homepage\n\n```python\nimport fastapi_blog\nfrom fastapi import FastAPI\n\n\nfavorite_post_ids = {\n    \"code-code-code\",\n    \"thirty-minute-rule\",\n    \"2023-11-three-years-at-kraken-tech\",\n}\n\napp = FastAPI()\napp = fastapi_blog.add_blog_to_fastapi(app, favorite_post_ids=favorite_post_ids)\n\n\n@app.get(\"/\")\nasync def index() -> dict:\n    return {\n        \"message\": \"Check out the blog at the URL\",\n        \"url\": \"http://localhost:8000/blog\",\n    }\n```\n\n### Add page not in the blog list of posts\n\nIn 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.\n\n```markdown\n---\ntitle: \"About Daniel Roy Greenfeld\"\ndescription: \"A little bit of background about Daniel Roy Greenfeld\"\nauthor: \"Daniel Roy Greenfeld\"\n---\n\nI'm probably best known as \"[pydanny](https://www.google.com/search?q=pydanny)\", one of the authors of [Two Scoops of Django](/books/tech).\n```\n\n\n## Installation and Running Example Sites\n\n### Option 1: Local Virtualenv\n\nYou can install this into a virtualenv using the pyproject.toml file:\n\n```bash\npip install fastapi-blog\nmake run\n```\n\n### Option 2: Docker (Local Dockerfile)\n\nOr into a Docker container using the local Dockerfile:\n\n```bash\ndocker build -t fastapi-blog .\ndocker run -d -p 8000:8000 fastapi-blog\n```\n\n### Option 3: Docker (Prebuilt)\n\nOr using a prebuilt Docker image from GitHub Container Registry:\n\n```bash\ndocker run -d -p 8000:8000 ghcr.io/aroygreenfeld/fastapi-blog:latest\n```\n\nThis is if you just want to run the application without building it yourself.\n\n## Releasing a new version\n\n1. Update the version in `pyproject.toml` and `fastapi_blog/__init__.py`\n\n2. Update changelog.md\n\n3. Build the distribution locally:\n\n```bash\nrm -rf dist\npip install -U build\npython -m build\n```\n\n4. Upload the distribution to PyPI:\n\n```bash\npip install -U twine\npython -m twine upload dist/*\n```\n\n5. Create a new release on GitHub and tag the release:\n\n```bash\ngit commit -am \"Release for vXYZ\"\nmake tag\n```\n\n## Contributors\n\n<!-- readme: contributors -start -->\n<table>\n<tr>\n    <td align=\"center\">\n        <a href=\"https://github.com/pydanny\">\n            <img src=\"https://avatars.githubusercontent.com/u/62857?v=4\" width=\"100;\" alt=\"pydanny\"/>\n            <br />\n            <sub><b>Daniel Roy Greenfeld</b></sub>\n        </a>\n    </td>\n    <td align=\"center\">\n        <a href=\"https://github.com/audreyfeldroy\">\n            <img src=\"https://avatars.githubusercontent.com/u/74739?v=4\" width=\"100;\" alt=\"audreyfeldroy\"/>\n            <br />\n            <sub><b>Audrey Roy Greenfeld</b></sub>\n        </a>\n    </td></tr>\n</table>\n<!-- readme: contributors -end -->\n",
    "bugtrack_url": null,
    "license": "FSL-1.0-Apache-2.0",
    "summary": "Blogging for FastAPI",
    "version": "0.6.0",
    "project_urls": {
        "bugs": "https://github.com/pydanny/fastapi-blog/issues",
        "changelog": "https://github.com/pydanny/fastapi-blog/blob/master/changelog.md",
        "homepage": "https://github.com/pydanny/fastapi-blog"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3252323465efed0de94f86ede29ade6d9c195ce222de6f84b302247b152f3ffe",
                "md5": "31503257d8cfcfe5dccf9baf75da0e5d",
                "sha256": "2dc6b69aa3fd6116d29c1a4b01778424ff809dc7fe69aa437546bc4a906cb6f3"
            },
            "downloads": -1,
            "filename": "fastapi_blog-0.6.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "31503257d8cfcfe5dccf9baf75da0e5d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 17916,
            "upload_time": "2024-03-24T16:35:54",
            "upload_time_iso_8601": "2024-03-24T16:35:54.277370Z",
            "url": "https://files.pythonhosted.org/packages/32/52/323465efed0de94f86ede29ade6d9c195ce222de6f84b302247b152f3ffe/fastapi_blog-0.6.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5ed3ee10bce25b0691bfc0e733a73a94d1dbe7dcfc3d60874e9ad50ced7e4712",
                "md5": "1f09e043021fe7c44511ebaee7222e4f",
                "sha256": "f017c94cbd48f492586b3e18ff7e901dd5cc2a07700f32586f8c5a3430eb10bc"
            },
            "downloads": -1,
            "filename": "fastapi-blog-0.6.0.tar.gz",
            "has_sig": false,
            "md5_digest": "1f09e043021fe7c44511ebaee7222e4f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 18001,
            "upload_time": "2024-03-24T16:35:56",
            "upload_time_iso_8601": "2024-03-24T16:35:56.150830Z",
            "url": "https://files.pythonhosted.org/packages/5e/d3/ee10bce25b0691bfc0e733a73a94d1dbe7dcfc3d60874e9ad50ced7e4712/fastapi-blog-0.6.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-24 16:35:56",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "pydanny",
    "github_project": "fastapi-blog",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fastapi-blog"
}
        
Elapsed time: 0.33424s