Movatterモバイル変換


[0]ホーム

URL:


콘텐츠로 이동
Join theFastAPI Cloud waiting list 🚀
Follow@fastapi onX (Twitter) to stay updated
FollowFastAPI onLinkedIn to stay updated
Subscribe to theFastAPI and friends newsletter 🎉
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor

Static Files -StaticFiles

You can use theStaticFiles class to serve static files, like JavaScript, CSS, images, etc.

Read more about it in theFastAPI docs for Static Files.

You can import it directly fromfastapi.staticfiles:

fromfastapi.staticfilesimportStaticFiles

fastapi.staticfiles.StaticFiles

StaticFiles(*,directory=None,packages=None,html=False,check_dir=True,follow_symlink=False)
Source code instarlette/staticfiles.py
4041424344454647484950515253545556
def__init__(self,*,directory:PathLike|None=None,packages:list[str|tuple[str,str]]|None=None,html:bool=False,check_dir:bool=True,follow_symlink:bool=False,)->None:self.directory=directoryself.packages=packagesself.all_directories=self.get_directories(directory,packages)self.html=htmlself.config_checked=Falseself.follow_symlink=follow_symlinkifcheck_diranddirectoryisnotNoneandnotos.path.isdir(directory):raiseRuntimeError(f"Directory '{directory}' does not exist")

directoryinstance-attribute

directory=directory

packagesinstance-attribute

packages=packages

all_directoriesinstance-attribute

all_directories=get_directories(directory,packages)

htmlinstance-attribute

html=html

config_checkedinstance-attribute

config_checked=False

follow_symlinkinstance-attribute

follow_symlink=follow_symlink

get_directories

get_directories(directory=None,packages=None)

Givendirectory andpackages arguments, return a list of all thedirectories that should be used for serving static files from.

Source code instarlette/staticfiles.py
58596061626364656667686970717273747576777879808182838485
defget_directories(self,directory:PathLike|None=None,packages:list[str|tuple[str,str]]|None=None,)->list[PathLike]:"""    Given `directory` and `packages` arguments, return a list of all the    directories that should be used for serving static files from.    """directories=[]ifdirectoryisnotNone:directories.append(directory)forpackageinpackagesor[]:ifisinstance(package,tuple):package,statics_dir=packageelse:statics_dir="statics"spec=importlib.util.find_spec(package)assertspecisnotNone,f"Package{package!r} could not be found."assertspec.originisnotNone,f"Package{package!r} could not be found."package_directory=os.path.normpath(os.path.join(spec.origin,"..",statics_dir))assertos.path.isdir(package_directory),(f"Directory '{statics_dir!r}' in package{package!r} could not be found.")directories.append(package_directory)returndirectories

get_path

get_path(scope)

Given the ASGI scope, return thepath string to serve up,with OS specific path separators, and any '..', '.' components removed.

Source code instarlette/staticfiles.py
101102103104105106107
defget_path(self,scope:Scope)->str:"""    Given the ASGI scope, return the `path` string to serve up,    with OS specific path separators, and any '..', '.' components removed.    """route_path=get_route_path(scope)returnos.path.normpath(os.path.join(*route_path.split("/")))

get_responseasync

get_response(path,scope)

Returns an HTTP response, given the incoming path, method and request headers.

Source code instarlette/staticfiles.py
109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
asyncdefget_response(self,path:str,scope:Scope)->Response:"""    Returns an HTTP response, given the incoming path, method and request headers.    """ifscope["method"]notin("GET","HEAD"):raiseHTTPException(status_code=405)try:full_path,stat_result=awaitanyio.to_thread.run_sync(self.lookup_path,path)exceptPermissionError:raiseHTTPException(status_code=401)exceptOSErrorasexc:# Filename is too long, so it can't be a valid static file.ifexc.errno==errno.ENAMETOOLONG:raiseHTTPException(status_code=404)raiseexcifstat_resultandstat.S_ISREG(stat_result.st_mode):# We have a static file to serve.returnself.file_response(full_path,stat_result,scope)elifstat_resultandstat.S_ISDIR(stat_result.st_mode)andself.html:# We're in HTML mode, and have got a directory URL.# Check if we have 'index.html' file to serve.index_path=os.path.join(path,"index.html")full_path,stat_result=awaitanyio.to_thread.run_sync(self.lookup_path,index_path)ifstat_resultisnotNoneandstat.S_ISREG(stat_result.st_mode):ifnotscope["path"].endswith("/"):# Directory URLs should redirect to always end in "/".url=URL(scope=scope)url=url.replace(path=url.path+"/")returnRedirectResponse(url=url)returnself.file_response(full_path,stat_result,scope)ifself.html:# Check for '404.html' if we're in HTML mode.full_path,stat_result=awaitanyio.to_thread.run_sync(self.lookup_path,"404.html")ifstat_resultandstat.S_ISREG(stat_result.st_mode):returnFileResponse(full_path,stat_result=stat_result,status_code=404)raiseHTTPException(status_code=404)

lookup_path

lookup_path(path)
Source code instarlette/staticfiles.py
151152153154155156157158159160161162163164165166167
deflookup_path(self,path:str)->tuple[str,os.stat_result|None]:fordirectoryinself.all_directories:joined_path=os.path.join(directory,path)ifself.follow_symlink:full_path=os.path.abspath(joined_path)directory=os.path.abspath(directory)else:full_path=os.path.realpath(joined_path)directory=os.path.realpath(directory)ifos.path.commonpath([full_path,directory])!=str(directory):# Don't allow misbehaving clients to break out of the static files directory.continuetry:returnfull_path,os.stat(full_path)except(FileNotFoundError,NotADirectoryError):continuereturn"",None

file_response

file_response(full_path,stat_result,scope,status_code=200)
Source code instarlette/staticfiles.py
169170171172173174175176177178179180181
deffile_response(self,full_path:PathLike,stat_result:os.stat_result,scope:Scope,status_code:int=200,)->Response:request_headers=Headers(scope=scope)response=FileResponse(full_path,status_code=status_code,stat_result=stat_result)ifself.is_not_modified(response.headers,request_headers):returnNotModifiedResponse(response.headers)returnresponse

check_configasync

check_config()

Perform a one-off configuration check that StaticFiles is actuallypointed at a directory, so that we can raise loud errors rather thanjust returning 404 responses.

Source code instarlette/staticfiles.py
183184185186187188189190191192193194195196197
asyncdefcheck_config(self)->None:"""    Perform a one-off configuration check that StaticFiles is actually    pointed at a directory, so that we can raise loud errors rather than    just returning 404 responses.    """ifself.directoryisNone:returntry:stat_result=awaitanyio.to_thread.run_sync(os.stat,self.directory)exceptFileNotFoundError:raiseRuntimeError(f"StaticFiles directory '{self.directory}' does not exist.")ifnot(stat.S_ISDIR(stat_result.st_mode)orstat.S_ISLNK(stat_result.st_mode)):raiseRuntimeError(f"StaticFiles path '{self.directory}' is not a directory.")

is_not_modified

is_not_modified(response_headers,request_headers)

Given the request and response headers, returnTrue if an HTTP"Not Modified" response could be returned instead.

Source code instarlette/staticfiles.py
199200201202203204205206207208209210211212213214215216217
defis_not_modified(self,response_headers:Headers,request_headers:Headers)->bool:"""    Given the request and response headers, return `True` if an HTTP    "Not Modified" response could be returned instead.    """ifif_none_match:=request_headers.get("if-none-match"):# The "etag" header is added by FileResponse, so it's always present.etag=response_headers["etag"]returnetagin[tag.strip(" W/")fortaginif_none_match.split(",")]try:if_modified_since=parsedate(request_headers["if-modified-since"])last_modified=parsedate(response_headers["last-modified"])ifif_modified_sinceisnotNoneandlast_modifiedisnotNoneandif_modified_since>=last_modified:returnTrueexceptKeyError:passreturnFalse

[8]ページ先頭

©2009-2026 Movatter.jp