Neoteroi / BlackSheep

Fast ASGI web framework for Python
https://www.neoteroi.dev/blacksheep/
MIT License
1.86k stars 78 forks source link

router parameter in Application constructor #463

Closed netwang closed 8 months ago

netwang commented 8 months ago

Application( services=services, show_error_details=configuration.show_error_details, router=RouterWithPrefix(f'/{configuration.App_Name}/') if configuration.production else None, )

class RouterWithPrefix(Router): """Router With Prefix."""

   def __init__(self, prefix: str) -> None:
        super().__init__()

        self.__prefix = prefix

  def add(self, method: str, pattern: AnyStr, handler: Any) -> None:
        """Add."""
        if isinstance(pattern, str):
              pattern = (self.__prefix + pattern).replace('//', '/')
       else:
             pattern = (self.__prefix.encode() + pattern).replace(b'//', b'/')

      super().add(method, pattern, handler)

Above code is for BlackSheep V1.2.18 to add prefix to all routes,. It changes http://localhost:1400/login to http://localhost:1400/QMOSDS/login

I updated to BlackSheep 2.0.4. Above cold will not work when configuration.production is True.

Above cold will work when configuration.production is False. Use default_router

if router is None:
    router = default_router if env_settings.use_default_router else Router()

How to add prefix to all routes in BlackSheep 2.0.4?? Thanks!

RobertoPrevato commented 8 months ago

Hi @netwang

The below works fine:

import os
from blacksheep import Application, Router, get

class RouterWithPrefix(Router):
    """Router With Prefix."""

    def __init__(self, prefix: str) -> None:
        super().__init__()

        self.__prefix = prefix

    def add(self, method: str, pattern, handler) -> None:
        """Add."""
        if isinstance(pattern, str):
            pattern = (self.__prefix + pattern).replace("//", "/")
        else:
            pattern = (self.__prefix.encode() + pattern).replace(b"//", b"/")

        super().add(method, pattern, handler)

prod = os.environ.get("PROD") == "1"

app = Application(router=RouterWithPrefix(f"/example/") if prod else None)

if prod:
    print("Running router with prefix!")
    assert isinstance(app.router, RouterWithPrefix)
else:
    print("Running router without prefix...")

@app.router.get("/")
def home():
    return "Home!"

If you define your own router, you cannot use the methods imported from BlackSheep, because they are the methods of the default router. You need to use get, post, etc. of the router you are using.

For example, create a module in your application in app/router.py:

# app/router.py
import os

if os.environ.get("PROD") in {"1", "true"}:
    router = RouterWithPrefix(...)
else:
    router = Router()

head = router.head
get = router.get
post = router.post
put = router.put
patch = router.patch
delete = router.delete
trace = router.trace
options = router.options
connect = router.connect
ws = router.ws
route = router.route 

Then use the get, post, etc. methods imported from your module to define routes, not the default methods.