1414import tempfile
1515import traceback
1616import zipfile
17- from typing import Any , Dict , List , Optional , Union
17+ from typing import Any
1818from urllib .parse import parse_qs , quote , unquote , urlparse , urlunparse
1919
2020import mammoth
@@ -112,22 +112,22 @@ def convert_soup(self, soup: Any) -> str:
112112class DocumentConverterResult :
113113 """The result of converting a document to text."""
114114
115- def __init__ (self , title : Union [ str , None ] = None , text_content : str = "" ):
116- self .title : Union [ str , None ] = title
115+ def __init__ (self , title : str | None = None , text_content : str = "" ):
116+ self .title : str | None = title
117117 self .text_content : str = text_content
118118
119119
120120class DocumentConverter :
121121 """Abstract superclass of all DocumentConverters."""
122122
123- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
123+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
124124 raise NotImplementedError ()
125125
126126
127127class PlainTextConverter (DocumentConverter ):
128128 """Anything with content type text/plain"""
129129
130- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
130+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
131131 # Guess the content type from any file extension that might be around
132132 content_type , _ = mimetypes .guess_type ("__placeholder" + kwargs .get ("file_extension" , "" ))
133133
@@ -149,7 +149,7 @@ def convert(self, local_path: str, **kwargs: Any) -> Union[None, DocumentConvert
149149class HtmlConverter (DocumentConverter ):
150150 """Anything with content type text/html"""
151151
152- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
152+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
153153 # Bail if not html
154154 extension = kwargs .get ("file_extension" , "" )
155155 if extension .lower () not in [".html" , ".htm" ]:
@@ -161,7 +161,7 @@ def convert(self, local_path: str, **kwargs: Any) -> Union[None, DocumentConvert
161161
162162 return result
163163
164- def _convert (self , html_content : str ) -> Union [ None , DocumentConverterResult ] :
164+ def _convert (self , html_content : str ) -> None | DocumentConverterResult :
165165 """Helper function that converts and HTML string."""
166166
167167 # Parse the string
@@ -189,7 +189,7 @@ def _convert(self, html_content: str) -> Union[None, DocumentConverterResult]:
189189class WikipediaConverter (DocumentConverter ):
190190 """Handle Wikipedia pages separately, focusing only on the main document content."""
191191
192- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
192+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
193193 # Bail if not Wikipedia
194194 extension = kwargs .get ("file_extension" , "" )
195195 if extension .lower () not in [".html" , ".htm" ]:
@@ -234,7 +234,7 @@ def convert(self, local_path: str, **kwargs: Any) -> Union[None, DocumentConvert
234234class YouTubeConverter (DocumentConverter ):
235235 """Handle YouTube specially, focusing on the video title, description, and transcript."""
236236
237- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
237+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
238238 # Bail if not YouTube
239239 extension = kwargs .get ("file_extension" , "" )
240240 if extension .lower () not in [".html" , ".htm" ]:
@@ -250,7 +250,7 @@ def convert(self, local_path: str, **kwargs: Any) -> Union[None, DocumentConvert
250250
251251 # Read the meta tags
252252 assert soup .title is not None and soup .title .string is not None
253- metadata : Dict [str , str ] = {"title" : soup .title .string }
253+ metadata : dict [str , str ] = {"title" : soup .title .string }
254254 for meta in soup (["meta" ]):
255255 for a in meta .attrs :
256256 if a in ["itemprop" , "property" , "name" ]:
@@ -328,13 +328,13 @@ def convert(self, local_path: str, **kwargs: Any) -> Union[None, DocumentConvert
328328 text_content = webpage_text ,
329329 )
330330
331- def _get (self , metadata : Dict [str , str ], keys : List [str ], default : Union [ str , None ] = None ) -> Union [ str , None ] :
331+ def _get (self , metadata : dict [str , str ], keys : list [str ], default : str | None = None ) -> str | None :
332332 for k in keys :
333333 if k in metadata :
334334 return metadata [k ]
335335 return default
336336
337- def _findKey (self , json : Any , key : str ) -> Union [ str , None ] : # TODO: Fix json type
337+ def _findKey (self , json : Any , key : str ) -> str | None : # TODO: Fix json type
338338 if isinstance (json , list ):
339339 for elm in json :
340340 ret = self ._findKey (elm , key )
@@ -356,7 +356,7 @@ class PdfConverter(DocumentConverter):
356356 Converts PDFs to Markdown. Most style information is ignored, so the results are essentially plain-text.
357357 """
358358
359- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
359+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
360360 # Bail if not a PDF
361361 extension = kwargs .get ("file_extension" , "" )
362362 if extension .lower () != ".pdf" :
@@ -373,7 +373,7 @@ class DocxConverter(HtmlConverter):
373373 Converts DOCX files to Markdown. Style information (e.g.m headings) and tables are preserved where possible.
374374 """
375375
376- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
376+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
377377 # Bail if not a DOCX
378378 extension = kwargs .get ("file_extension" , "" )
379379 if extension .lower () != ".docx" :
@@ -393,7 +393,7 @@ class XlsxConverter(HtmlConverter):
393393 Converts XLSX files to Markdown, with each sheet presented as a separate Markdown table.
394394 """
395395
396- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
396+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
397397 # Bail if not a XLSX
398398 extension = kwargs .get ("file_extension" , "" )
399399 if extension .lower () not in [".xlsx" , ".xls" ]:
@@ -417,7 +417,7 @@ class PptxConverter(HtmlConverter):
417417 Converts PPTX files to Markdown. Supports heading, tables and images with alt text.
418418 """
419419
420- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
420+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
421421 # Bail if not a PPTX
422422 extension = kwargs .get ("file_extension" , "" )
423423 if extension .lower () != ".pptx" :
@@ -520,7 +520,7 @@ class WavConverter(MediaConverter):
520520 Converts WAV files to markdown via extraction of metadata (if `exiftool` is installed), and speech transcription (if `speech_recognition` is installed).
521521 """
522522
523- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
523+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
524524 # Bail if not a XLSX
525525 extension = kwargs .get ("file_extension" , "" )
526526 if extension .lower () != ".wav" :
@@ -570,7 +570,7 @@ class Mp3Converter(WavConverter):
570570 Converts MP3 and M4A files to markdown via extraction of metadata (if `exiftool` is installed), and speech transcription (if `speech_recognition` AND `pydub` are installed).
571571 """
572572
573- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
573+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
574574 # Bail if not a MP3
575575 extension = kwargs .get ("file_extension" , "" )
576576 if extension .lower () not in [".mp3" , ".m4a" ]:
@@ -644,7 +644,7 @@ def __init__(self, extract_dir: str = "downloads"):
644644 # Create the extraction directory if it doesn't exist
645645 os .makedirs (self .extract_dir , exist_ok = True )
646646
647- def convert (self , local_path : str , ** kwargs : Any ) -> Union [ None , DocumentConverterResult ] :
647+ def convert (self , local_path : str , ** kwargs : Any ) -> None | DocumentConverterResult :
648648 # Bail if not a ZIP file
649649 extension = kwargs .get ("file_extension" , "" )
650650 if extension .lower () != ".zip" :
@@ -681,7 +681,7 @@ class ImageConverter(MediaConverter):
681681 Converts images to markdown via extraction of metadata (if `exiftool` is installed), OCR (if `easyocr` is installed), and description via a multimodal LLM (if an mlm_client is configured).
682682 """
683683
684- def convert (self , local_path , ** kwargs ) -> Union [ None , DocumentConverterResult ] :
684+ def convert (self , local_path , ** kwargs ) -> None | DocumentConverterResult :
685685 # Bail if not a XLSX
686686 extension = kwargs .get ("file_extension" , "" )
687687 if extension .lower () not in [".jpg" , ".jpeg" , ".png" ]:
@@ -771,9 +771,9 @@ class MarkdownConverter:
771771
772772 def __init__ (
773773 self ,
774- requests_session : Optional [ requests .Session ] = None ,
775- mlm_client : Optional [ Any ] = None ,
776- mlm_model : Optional [ Any ] = None ,
774+ requests_session : requests .Session | None = None ,
775+ mlm_client : Any | None = None ,
776+ mlm_model : Any | None = None ,
777777 ):
778778 if requests_session is None :
779779 self ._requests_session = requests .Session ()
@@ -783,7 +783,7 @@ def __init__(
783783 self ._mlm_client = mlm_client
784784 self ._mlm_model = mlm_model
785785
786- self ._page_converters : List [DocumentConverter ] = []
786+ self ._page_converters : list [DocumentConverter ] = []
787787
788788 # Register converters for successful browsing operations
789789 # Later registrations are tried first / take higher priority than earlier registrations
@@ -802,7 +802,7 @@ def __init__(
802802 self .register_page_converter (PdfConverter ())
803803
804804 def convert (
805- self , source : Union [ str , requests .Response ] , ** kwargs : Any
805+ self , source : str | requests .Response , ** kwargs : Any
806806 ) -> DocumentConverterResult : # TODO: deal with kwargs
807807 """
808808 Args:
@@ -924,7 +924,7 @@ def convert_response(
924924
925925 return result
926926
927- def _convert (self , local_path : str , extensions : List [ Union [ str , None ] ], ** kwargs ) -> DocumentConverterResult :
927+ def _convert (self , local_path : str , extensions : list [ str | None ], ** kwargs ) -> DocumentConverterResult :
928928 error_trace = ""
929929 for ext in extensions + [None ]: # Try last with no extension
930930 for converter in self ._page_converters :
0 commit comments