Skip to content

Commit

Permalink
Fix mimetype handling on windows (#259)
Browse files Browse the repository at this point in the history
This PR fixes handling of mimetypes on windows machines:

Needed due to issue: https://bugs.python.org/issue43975

Resolves issue: #245

Chose not to use mimetypes.init since that's using a singleton pattern
and worried that users will be likely to run into issues since the
server may be parsing files which may also end up using mimetype
guessing based on file extension
  • Loading branch information
eyurtsev committed Nov 27, 2023
1 parent bcf833c commit af904f5
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
35 changes: 34 additions & 1 deletion langserve/playground.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,39 @@ class PlaygroundTemplate(Template):
delimiter = "____"


def _get_mimetype(path: str) -> str:
"""Get mimetype for file.
Custom implementation of mimetypes.guess_type that
uses the file extension to determine the mimetype for some files.
This is necessary due to: https://bugs.python.org/issue43975
Resolves issue: https://github.com/langchain-ai/langserve/issues/245
Args:
path (str): Path to file
Returns:
str: Mimetype of file
"""
try:
file_extension = path.lower().split(".")[-1]
except IndexError:
return mimetypes.guess_type(path)[0]

if file_extension == "js":
return "application/javascript"
elif file_extension == "css":
return "text/css"
elif file_extension in ["htm", "html"]:
return "text/html"

# If the file extension is not one of the specified ones,
# use the default guess method
mime_type = mimetypes.guess_type(path)[0]
return mime_type


async def serve_playground(
runnable: Runnable,
input_schema: Type[BaseModel],
Expand All @@ -39,7 +72,7 @@ async def serve_playground(

try:
with open(local_file_path, encoding="utf-8") as f:
mime_type = mimetypes.guess_type(local_file_path)[0]
mime_type = _get_mimetype(local_file_path)
if mime_type in ("text/html", "text/css", "application/javascript"):
response = PlaygroundTemplate(f.read()).substitute(
LANGSERVE_BASE_URL=base_url[1:]
Expand Down
24 changes: 24 additions & 0 deletions tests/unit_tests/test_playground.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

from langserve.playground import _get_mimetype


@pytest.mark.parametrize(
"file_extension, expected_mimetype",
[
("js", "application/javascript"),
("css", "text/css"),
("htm", "text/html"),
("html", "text/html"),
("txt", "text/plain"), # An example of an unknown extension using guess_type
],
)
def test_get_mimetype(file_extension: str, expected_mimetype: str) -> None:
# Create a filename with the given extension
filename = f"test_file.{file_extension}"

# Call the _get_mimetype function with the test filename
mimetype = _get_mimetype(filename)

# Check if the returned mimetype matches the expected one
assert mimetype == expected_mimetype

0 comments on commit af904f5

Please sign in to comment.