FastAPI로 Docusaurus와 유사한 사이트 구축: 2단계 - Markdown 렌더링
James Reed
Infrastructure Engineer · Leapcell

이전 글에서 FastAPI 서비스를 설정하고 Jinja2를 사용하여 동적 HTML 템플릿을 렌더링했습니다.
하지만 다른 문서 사이트 도구를 사용해 보았다면, 수동으로 HTML을 작성하는 대신 모두 Markdown을 작성하고 이를 사용하여 HTML 콘텐츠를 생성한다는 것을 알 것입니다.
이 글에서는 이와 정확히 동일한 기능을 구현할 것입니다. 로컬 .md 파일을 읽고, HTML로 구문 분석하고, 웹 템플릿에 삽입하는 것입니다.
1단계: Markdown 구문 분석 라이브러리 설치
Markdown 텍스트를 HTML 문자열로 변환하는 도구가 필요합니다. 이를 위한 인기 있는 라이브러리는 python-markdown입니다.
다음 명령을 실행하여 설치하십시오:
pip install markdown
2단계: 첫 번째 Markdown 문서 생성
관례적으로 모든 소스 문서를 새 docs/ 폴더에 저장할 것입니다.
먼저 프로젝트 루트 디렉토리에 docs 폴더를 만든 다음 그 안에 hello.md 파일을 만듭니다
업데이트된 프로젝트 구조:
fastapi-docs-site/
├── docs/               <-- 새로 추가
│   └── hello.md        <-- 새로 추가
├── main.py
├── static/
└── templates/
docs/hello.md 수정:
나중에 테스트할 수 있도록 이 새 파일을 열고 Markdown 콘텐츠를 작성하십시오.
# 안녕하세요, Markdown! 이것은 FastAPI로 렌더링된 첫 번째 Markdown 문서입니다. 코드 블록 예제입니다 (물론 아직 구문 강조 기능은 없습니다): ```python def say_hello(): print("Hello from FastAPI!") ``` - 이것은 목록 항목입니다 - 이것은 또 다른 목록 항목입니다
3단계: 문서 렌더링을 위한 템플릿 생성
지난 글에서 만든 templates/index.html은 우리의 홈페이지입니다. 이제 이 Markdown 파일의 콘텐츠를 표시할 전용 템플릿이 필요합니다.
templates/ 폴더에 doc.html이라는 새 파일을 만드십시오.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>{{ page_title }} - My Docs Site</title> </head> <body> <h1>{{ page_title }}</h1> <hr /> <div class="doc-content">{{ content | safe }}</div> </body> </html>
{{ content | safe }}는 Jinja2에게 "이 content 변수의 내용은 안전한 HTML이므로 직접 렌더링하고 이스케이프하지 마십시오"라고 지시합니다.
4단계: Markdown 렌더링 라우트 생성
다음으로, Markdown 파일에 대한 새 라우트, 예를 들어 /docs/hello를 추가하도록 main.py를 수정해 보겠습니다.
다음 작업을 수행합니다:
docs/hello.md파일의 내용을 읽습니다.markdown라이브러리를 가져옵니다.markdown.markdown()함수를 사용하여 파일 내용을 HTML 문자열로 변환합니다.- 이 HTML 문자열을 
doc.html템플릿으로content변수로 전달합니다. 
main.py를 열고 다음과 같이 수정하십시오.
# main.py from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templates from fastapi.responses import HTMLResponse import markdown # 1. markdown 라이브러리 가져오기 app = FastAPI() templates = Jinja2Templates(directory="templates") # --- 이전 글의 루트 라우트입니다 --- @app.get("/", response_class=HTMLResponse) async def root(request: Request): """ 루트 라우트, 렌더링된 HTML 템플릿을 반환합니다 """ context = { "request": request, "page_title": "안녕하세요, Jinja2!" } return templates.TemplateResponse("index.html", context) # --- 2. 새로운 문서 라우트입니다 --- @app.get("/docs/hello", response_class=HTMLResponse) async def get_hello_doc(request: Request): """ hello.md 문서를 읽고, 구문 분석하고, 렌더링합니다 """ # 3. Markdown 파일의 경로를 하드코딩합니다. # (향후 글에서 동적으로 만들 것입니다) md_file_path = "docs/hello.md" try: with open(md_file_path, "r", encoding="utf-8") as f: md_content = f.read() except FileNotFoundError: # 간단한 오류 처리 return HTMLResponse(content="<h1>404 - 문서를 찾을 수 없습니다</h1>", status_code=404) # 4. markdown 라이브러리를 사용하여 HTML로 변환합니다. html_content = markdown.markdown(md_content) # 5. 템플릿 컨텍스트를 준비합니다. # doc.html을 렌더링하고 있음을 유의하십시오. context = { "request": request, "page_title": "안녕하세요, Markdown!", # 임시로 하드코딩된 제목 "content": html_content # 변환된 HTML 전달 } return templates.TemplateResponse("doc.html", context)
5단계: 실행 및 테스트
uvicorn main:app --reload를 실행하여 서버를 시작합니다.
브라우저에서 이 URL로 이동합니다: http://127.0.0.1:8000/docs/hello
docs/hello.md의 내용이 HTML 페이지로 성공적으로 렌더링된 것을 볼 수 있습니다!

프로젝트 온라인 배포
문서 사이트는 모두가 방문해야 하므로 로컬에서 실행하는 것만으로는 충분하지 않습니다. 다음으로 온라인으로 배포할 수 있습니다.
간단한 배포 옵션은 Leapcell을 사용하는 것입니다. FastAPI를 포함한 다양한 언어 및 프레임워크 프로젝트를 호스팅할 수 있는 웹 앱 호스팅 플랫폼입니다.
아래 단계를 따르십시오.
1.웹사이트에서 계정을 등록합니다.
2.프로젝트를 GitHub에 커밋합니다. GitHub 공식 문서를 참조하여 단계를 확인하십시오. Leapcell은 나중에 GitHub 리포지토리에서 코드를 가져올 것입니다.
3.Leapcell 페이지에서 "Create Service"를 클릭합니다.

4.FastAPI 리포지토리를 선택하면 Leapcell이 필요한 구성을 자동으로 채워 넣는 것을 볼 수 있습니다.

5.아래의 "Submit"을 클릭하여 배포합니다. 배포는 빠르게 완료되고 배포 홈페이지로 돌아갑니다. 여기서 Leapcell이 도메인을 제공했음을 확인할 수 있습니다. 이것이 블로그의 온라인 주소입니다.

요약 및 다음 단계
이 글에서는 문서 사이트의 가장 핵심적인 기능인 동적 Markdown-to-HTML 변환을 구현했습니다.
hello.md의 Python 코드 블록을 아마도 알아차렸을 것입니다. 올바르게 코드로 렌더링되었지만, 평범해 보이고 색상 강조도 없으며 읽기 어렵습니다.
이것은 분명 문서 사이트가 제공해야 하는 경험이 아닙니다.
다음 글에서는 이 문제를 해결할 것입니다. 렌더링된 Markdown 코드 블록에 구문 강조 기능을 추가할 것입니다.


