Middleware

There are several middlewares available provided by Starlette directly.

Read more about them in the FastAPI docs for Middleware.

fastapi.middleware.cors.CORSMiddleware

  1. CORSMiddleware(
  2. app,
  3. allow_origins=(),
  4. allow_methods=("GET"),
  5. allow_headers=(),
  6. allow_credentials=False,
  7. allow_origin_regex=None,
  8. expose_headers=(),
  9. max_age=600,
  10. )
PARAMETERDESCRIPTION
app

TYPE: ASGIApp

allow_origins

TYPE: Sequence[str] DEFAULT: ()

allow_methods

TYPE: Sequence[str] DEFAULT: (‘GET’)

allow_headers

TYPE: Sequence[str] DEFAULT: ()

allow_credentials

TYPE: bool DEFAULT: False

allow_origin_regex

TYPE: Optional[str] DEFAULT: None

expose_headers

TYPE: Sequence[str] DEFAULT: ()

max_age

TYPE: int DEFAULT: 600

Source code in starlette/middleware/cors.py

  1. 14
  2. 15
  3. 16
  4. 17
  5. 18
  6. 19
  7. 20
  8. 21
  9. 22
  10. 23
  11. 24
  12. 25
  13. 26
  14. 27
  15. 28
  16. 29
  17. 30
  18. 31
  19. 32
  20. 33
  21. 34
  22. 35
  23. 36
  24. 37
  25. 38
  26. 39
  27. 40
  28. 41
  29. 42
  30. 43
  31. 44
  32. 45
  33. 46
  34. 47
  35. 48
  36. 49
  37. 50
  38. 51
  39. 52
  40. 53
  41. 54
  42. 55
  43. 56
  44. 57
  45. 58
  46. 59
  47. 60
  48. 61
  49. 62
  50. 63
  51. 64
  52. 65
  53. 66
  54. 67
  55. 68
  56. 69
  57. 70
  58. 71
  1. def init(
  2. self,
  3. app: ASGIApp,
  4. allow_origins: typing.Sequence[str] = (),
  5. allow_methods: typing.Sequence[str] = (GET,),
  6. allow_headers: typing.Sequence[str] = (),
  7. allow_credentials: bool = False,
  8. allow_origin_regex: typing.Optional[str] = None,
  9. expose_headers: typing.Sequence[str] = (),
  10. max_age: int = 600,
  11. ) -> None:
  12. if in allow_methods:
  13. allow_methods = ALL_METHODS
  14. compiled_allow_origin_regex = None
  15. if allow_origin_regex is not None:
  16. compiled_allow_origin_regex = re.compile(allow_origin_regex)
  17. allow_all_origins = in allow_origins
  18. allow_all_headers = in allow_headers
  19. preflight_explicit_allow_origin = not allow_all_origins or allow_credentials
  20. simple_headers = {}
  21. if allow_all_origins:
  22. simple_headers[Access-Control-Allow-Origin] =
  23. if allow_credentials:
  24. simple_headers[Access-Control-Allow-Credentials] = true
  25. if expose_headers:
  26. simple_headers[Access-Control-Expose-Headers] = “, .join(expose_headers)
  27. preflight_headers = {}
  28. if preflight_explicit_allow_origin:
  29. # The origin value will be set in preflight_response() if it is allowed.
  30. preflight_headers[Vary] = Origin
  31. else:
  32. preflight_headers[Access-Control-Allow-Origin] = “*”
  33. preflight_headers.update(
  34. {
  35. Access-Control-Allow-Methods: “, .join(allow_methods),
  36. Access-Control-Max-Age: str(max_age),
  37. }
  38. )
  39. allow_headers = sorted(SAFELISTED_HEADERS | set(allow_headers))
  40. if allow_headers and not allow_all_headers:
  41. preflight_headers[Access-Control-Allow-Headers] = “, .join(allow_headers)
  42. if allow_credentials:
  43. preflight_headers[Access-Control-Allow-Credentials] = true
  44. self.app = app
  45. self.allow_origins = allow_origins
  46. self.allow_methods = allow_methods
  47. self.allow_headers = [h.lower() for h in allow_headers]
  48. self.allow_all_origins = allow_all_origins
  49. self.allow_all_headers = allow_all_headers
  50. self.preflight_explicit_allow_origin = preflight_explicit_allow_origin
  51. self.allow_origin_regex = compiled_allow_origin_regex
  52. self.simple_headers = simple_headers
  53. self.preflight_headers = preflight_headers

app instance-attribute

  1. app = app

allow_origins instance-attribute

  1. allow_origins = allow_origins

allow_methods instance-attribute

  1. allow_methods = allow_methods

allow_headers instance-attribute

  1. allow_headers = [lower() for h in allow_headers]

allow_all_origins instance-attribute

  1. allow_all_origins = allow_all_origins

allow_all_headers instance-attribute

  1. allow_all_headers = allow_all_headers

preflight_explicit_allow_origin instance-attribute

  1. preflight_explicit_allow_origin = (
  2. preflight_explicit_allow_origin
  3. )

allow_origin_regex instance-attribute

  1. allow_origin_regex = compiled_allow_origin_regex

simple_headers instance-attribute

  1. simple_headers = simple_headers

preflight_headers instance-attribute

  1. preflight_headers = preflight_headers

is_allowed_origin

  1. is_allowed_origin(origin)
PARAMETERDESCRIPTION
origin

TYPE: str

Source code in starlette/middleware/cors.py

  1. 93
  2. 94
  3. 95
  4. 96
  5. 97
  6. 98
  7. 99
  8. 100
  9. 101
  10. 102
  1. def is_allowed_origin(self, origin: str) -> bool:
  2. if self.allow_all_origins:
  3. return True
  4. if self.allow_origin_regex is not None and self.allow_origin_regex.fullmatch(
  5. origin
  6. ):
  7. return True
  8. return origin in self.allow_origins

preflight_response

  1. preflight_response(request_headers)
PARAMETERDESCRIPTION
request_headers

TYPE: Headers

Source code in starlette/middleware/cors.py

  1. 104
  2. 105
  3. 106
  4. 107
  5. 108
  6. 109
  7. 110
  8. 111
  9. 112
  10. 113
  11. 114
  12. 115
  13. 116
  14. 117
  15. 118
  16. 119
  17. 120
  18. 121
  19. 122
  20. 123
  21. 124
  22. 125
  23. 126
  24. 127
  25. 128
  26. 129
  27. 130
  28. 131
  29. 132
  30. 133
  31. 134
  32. 135
  33. 136
  34. 137
  35. 138
  36. 139
  37. 140
  1. def preflight_response(self, request_headers: Headers) -> Response:
  2. requested_origin = request_headers[origin]
  3. requested_method = request_headers[access-control-request-method]
  4. requested_headers = request_headers.get(access-control-request-headers)
  5. headers = dict(self.preflight_headers)
  6. failures = []
  7. if self.is_allowed_origin(origin=requested_origin):
  8. if self.preflight_explicit_allow_origin:
  9. # The “else” case is already accounted for in self.preflight_headers
  10. # and the value would be “*”.
  11. headers[Access-Control-Allow-Origin] = requested_origin
  12. else:
  13. failures.append(origin)
  14. if requested_method not in self.allow_methods:
  15. failures.append(method)
  16. # If we allow all headers, then we have to mirror back any requested
  17. # headers in the response.
  18. if self.allow_all_headers and requested_headers is not None:
  19. headers[Access-Control-Allow-Headers] = requested_headers
  20. elif requested_headers is not None:
  21. for header in [h.lower() for h in requested_headers.split(“,”)]:
  22. if header.strip() not in self.allow_headers:
  23. failures.append(headers)
  24. break
  25. # We don’t strictly need to use 400 responses here, since its up to
  26. # the browser to enforce the CORS policy, but its more informative
  27. # if we do.
  28. if failures:
  29. failure_text = Disallowed CORS + “, .join(failures)
  30. return PlainTextResponse(failure_text, status_code=400, headers=headers)
  31. return PlainTextResponse(OK, status_code=200, headers=headers)

simple_response async

  1. simple_response(scope, receive, send, request_headers)
PARAMETERDESCRIPTION
scope

TYPE: Scope

receive

TYPE: Receive

send

TYPE: Send

request_headers

TYPE: Headers

Source code in starlette/middleware/cors.py

  1. 142
  2. 143
  3. 144
  4. 145
  5. 146
  1. async def simple_response(
  2. self, scope: Scope, receive: Receive, send: Send, request_headers: Headers
  3. ) -> None:
  4. send = functools.partial(self.send, send=send, request_headers=request_headers)
  5. await self.app(scope, receive, send)

send async

  1. send(message, send, request_headers)
PARAMETERDESCRIPTION
message

TYPE: Message

send

TYPE: Send

request_headers

TYPE: Headers

Source code in starlette/middleware/cors.py

  1. 148
  2. 149
  3. 150
  4. 151
  5. 152
  6. 153
  7. 154
  8. 155
  9. 156
  10. 157
  11. 158
  12. 159
  13. 160
  14. 161
  15. 162
  16. 163
  17. 164
  18. 165
  19. 166
  20. 167
  21. 168
  22. 169
  23. 170
  24. 171
  1. async def send(
  2. self, message: Message, send: Send, request_headers: Headers
  3. ) -> None:
  4. if message[type] != http.response.start:
  5. await send(message)
  6. return
  7. message.setdefault(headers, [])
  8. headers = MutableHeaders(scope=message)
  9. headers.update(self.simple_headers)
  10. origin = request_headers[Origin]
  11. has_cookie = cookie in request_headers
  12. # If request includes any cookie headers, then we must respond
  13. # with the specific origin instead of ‘*’.
  14. if self.allow_all_origins and has_cookie:
  15. self.allow_explicit_origin(headers, origin)
  16. # If we only allow specific origins, then we have to mirror back
  17. # the Origin header in the response.
  18. elif not self.allow_all_origins and self.is_allowed_origin(origin=origin):
  19. self.allow_explicit_origin(headers, origin)
  20. await send(message)

allow_explicit_origin staticmethod

  1. allow_explicit_origin(headers, origin)
PARAMETERDESCRIPTION
headers

TYPE: MutableHeaders

origin

TYPE: str

Source code in starlette/middleware/cors.py

  1. 173
  2. 174
  3. 175
  4. 176
  1. @staticmethod
  2. def allow_explicit_origin(headers: MutableHeaders, origin: str) -> None:
  3. headers[Access-Control-Allow-Origin] = origin
  4. headers.add_vary_header(Origin)

It can be imported from fastapi:

  1. from fastapi.middleware.cors import CORSMiddleware

fastapi.middleware.gzip.GZipMiddleware

  1. GZipMiddleware(app, minimum_size=500, compresslevel=9)
PARAMETERDESCRIPTION
app

TYPE: ASGIApp

minimum_size

TYPE: int DEFAULT: 500

compresslevel

TYPE: int DEFAULT: 9

Source code in starlette/middleware/gzip.py

  1. 10
  2. 11
  3. 12
  4. 13
  5. 14
  6. 15
  1. def init(
  2. self, app: ASGIApp, minimum_size: int = 500, compresslevel: int = 9
  3. ) -> None:
  4. self.app = app
  5. self.minimum_size = minimum_size
  6. self.compresslevel = compresslevel

app instance-attribute

  1. app = app

minimum_size instance-attribute

  1. minimum_size = minimum_size

compresslevel instance-attribute

  1. compresslevel = compresslevel

It can be imported from fastapi:

  1. from fastapi.middleware.gzip import GZipMiddleware

fastapi.middleware.httpsredirect.HTTPSRedirectMiddleware

  1. HTTPSRedirectMiddleware(app)
PARAMETERDESCRIPTION
app

TYPE: ASGIApp

Source code in starlette/middleware/httpsredirect.py

  1. 7
  2. 8
  1. def init(self, app: ASGIApp) -> None:
  2. self.app = app

app instance-attribute

  1. app = app

It can be imported from fastapi:

  1. from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware

fastapi.middleware.trustedhost.TrustedHostMiddleware

  1. TrustedHostMiddleware(
  2. app, allowed_hosts=None, www_redirect=True
  3. )
PARAMETERDESCRIPTION
app

TYPE: ASGIApp

allowed_hosts

TYPE: Optional[Sequence[str]] DEFAULT: None

www_redirect

TYPE: bool DEFAULT: True

Source code in starlette/middleware/trustedhost.py

  1. 11
  2. 12
  3. 13
  4. 14
  5. 15
  6. 16
  7. 17
  8. 18
  9. 19
  10. 20
  11. 21
  12. 22
  13. 23
  14. 24
  15. 25
  16. 26
  17. 27
  1. def init(
  2. self,
  3. app: ASGIApp,
  4. allowed_hosts: typing.Optional[typing.Sequence[str]] = None,
  5. www_redirect: bool = True,
  6. ) -> None:
  7. if allowed_hosts is None:
  8. allowed_hosts = []
  9. for pattern in allowed_hosts:
  10. assert not in pattern[1:], ENFORCE_DOMAIN_WILDCARD
  11. if pattern.startswith() and pattern != :
  12. assert pattern.startswith(.”), ENFORCE_DOMAIN_WILDCARD
  13. self.app = app
  14. self.allowed_hosts = list(allowed_hosts)
  15. self.allow_any = in allowed_hosts
  16. self.www_redirect = www_redirect

app instance-attribute

  1. app = app

allowed_hosts instance-attribute

  1. allowed_hosts = list(allowed_hosts)

allow_any instance-attribute

  1. allow_any = '*' in allowed_hosts

www_redirect instance-attribute

  1. www_redirect = www_redirect

It can be imported from fastapi:

  1. from fastapi.middleware.trustedhost import TrustedHostMiddleware

fastapi.middleware.wsgi.WSGIMiddleware

  1. WSGIMiddleware(app)
PARAMETERDESCRIPTION
app

TYPE: Callable

Source code in starlette/middleware/wsgi.py

  1. 65
  2. 66
  1. def init(self, app: typing.Callable) -> None:
  2. self.app = app

app instance-attribute

  1. app = app

It can be imported from fastapi:

  1. from fastapi.middleware.wsgi import WSGIMiddleware