2

As you know this error is output by class Router in routing.py I am developing a service with FastAPI as just REST API not using HTML files But I should to append HTML output script in my source code because an external service need to redirect to my api service page

So I appended Jinja2Templates and succeed to call HTML template After that I appended bootstrap template to static folder and mount this folder But I can not mount for a router which is separated each endpoint file

Someone support me if you know the issue

Directory tree

another projects
target project
|- src
   |- app
      |- main.py
      |- controllers
         |- page_controller.py
      |- endpoints
         |- from_external_redirec.py
      |- routes
         |- api.py
      |- schemas
      |- static    <- added this needs
      |- templates <-- added this needs
         |- success.html
         |- fault.html

Note. this directory is for some docker containers. Target project is one of containers

main.py

from fastapi import FastAPI
import os
from fastapi.staticfiles import StaticFiles
from .app.routes.api import router as api_router

app = FastAPI(
    title="xxxxxxxx",
    description="xxxxx",
    version="0.0.1",
)

absolute_path = os.path.dirname(__file__)
relative_path = "app/static"
static_path = os.path.join(absolute_path, relative_path)

app.include_router(api_router)
app.mount("/static", StaticFiles(directory=static_path), name="static")

Note. StaticeFiles uses target project as default directory.So if set 'app/static' to directory parameter then FastAPI show 'app/static' not found So I set relative path instead

FYI. Dockerfile

FROM python:3.10
WORKDIR /code
RUN mkdir -p /code/src
COPY ./requirements.txt /code/requirements.txt
RUN pip install --upgrade pip
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload", "--env-file", "/code/src/env/docker/.env"]

FYI Docker compose

version: '3.3'

services:

  target-project:
    build:
      context: ./target-project/
    volumes:
      - ./target-project/src/:/code/src/

  nginx:
    restart: always
    build: ./nginx/
    ports:
      - "80:80"
    depends_on:
      - target-project

Note. This docker container uses resources under src directory

api.py

from fastapi import APIRouter
from ..endpoints import from_external_redirec

router = APIRouter()
router.include_router(from_external_redirec.router)

from_external_redirec.py

from fastapi import status as st, APIRouter, HTTPException, Request
from fastapi.responses import RedirectResponse, HTMLResponse
from fastapi.requests import Request
from requests import request
import os
from ..controllers.page_controller import pagectl

router = APIRouter(
    prefix="/external",
    tags=["External"],
)

@router.get("/result/success/", response_class=HTMLResponse)
async def show_success_page(request: Request):
    page = pagectl()
        return page.get_successful_template(request)
    return page.get_error_template(request)
    
@router.get("/result/cancel/{payment_id}", response_class=HTMLResponse)
async def show_falt_page(request: Request):
    page = pagectl()
    return page.get_cancel_template(request) 

page_controller.py

from fastapi.templating import Jinja2Templates
from fastapi.requests import Request
import os

class pagectl:
    def __init__(self):
        absolute_path = os.path.dirname(__file__)
        relative_path = "../templates"
        template_path = os.path.join(absolute_path, relative_path)
        self.template = Jinja2Templates(directory=template_path)
    
    def show_success_page(self, request: Request):
        return self.__get_template(request, "success.html")
        
    def show_fault_page(self, request: Request):
        return self.__get_template(request, "fault.html")

    def __get_template(self, request: Request, file: str):
        return self.template.TemplateResponse(
            file,
            {
                "request": request,
            }
        )
  • 2
    This is probably cause by your template, which you haven't included - it seems like you're using the `url_for` syntax from Flask and not the one from FastAPI/Starlette. It should be `url_for('static', path='/foo/bar.css')` - `path` - not `filename`. – MatsLindh Oct 12 '22 at 09:06
  • I see, your answer is so smart... it's easy to add get function for static path Actually, I found for_url doesn't return direct path so I added _enternal option but it is error in FastAPI case... Thanks I'll try one – Jun Takeshita Oct 14 '22 at 13:20
  • I changed filename to path in url_for parameter but the result is not direct path for example, If my fastapi endpoint http://mydot.com so url_for output to use this domain path but actually url_for outputs xxx.xxx.xxx.xxx for my server address and _external option is not working in FastAPI – Jun Takeshita Oct 14 '22 at 13:33

0 Answers0